以下は、VBAでDataGridViewの1列目にツリービューを入れる方法のサンプルコードです。このコードは、Accessフォームに配置されたDataGridViewの例を示しています。 まず、カスタムコントロールとして使用するUserControlに、DataGridViewとTreeViewを追加します。そして、DataGridViewのColumns コレクションに新しい列を追加し、その列の CellTemplate プロパティに新しいTreeCellオブジェクトを設定します。
Option Explicit
Private WithEvents mDataGridView As DataGridView
Private WithEvents mTreeView As TreeView
Private Sub UserControl_Initialize()
' DataGridViewを追加
Set mDataGridView = New DataGridView
With mDataGridView
.Visible = True
.Top = ScaleY(0, vbTwips, vbPixels)
.Left = ScaleX(0, vbTwips, vbPixels)
.Width = ScaleX(4000, vbTwips, vbPixels)
.Height = ScaleY(4000, vbTwips, vbPixels)
End With
Me.Controls.Add mDataGridView
' TreeViewを追加
Set mTreeView = New TreeView
With mTreeView
.Visible = False
.Top = ScaleY(0, vbTwips, vbPixels)
.Left = ScaleX(4000, vbTwips, vbPixels)
.Width = ScaleX(2000, vbTwips, vbPixels)
.Height = ScaleY(4000, vbTwips, vbPixels)
End With
Me.Controls.Add mTreeView
' DataGridViewにツリーセルを追加
Dim treeColumn As New DataGridViewTextBoxColumn
Dim treeCell As New TreeCell
treeColumn.CellTemplate = treeCell
mDataGridView.Columns.Insert(0, treeColumn)
End Sub
次に、DataGridViewの CellValueChanged イベントで、TreeViewに新しいノードを追加するようにします。このイベントは、DataGridViewの1列目に値が入力された場合に発生します。ノードのテキストと親ノードの参照を取得し、TreeViewに新しいノードを追加します。
' DataGridViewのCellValueChangedイベント
Private Sub mDataGridView_CellValueChanged(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles mDataGridView.CellValueChanged
If e.ColumnIndex = 0 Then
' ノードをTreeViewに追加
Dim nodeText As String
nodeText = mDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
Dim parentNode As Node
If e.RowIndex = 0 Then
' 最上位のノード
Set parentNode = mTreeView.Nodes.Add(, , nodeText)
Else
' 親ノードを取得
Dim parentRowIndex As Long
parentRowIndex = e.RowIndex - 1
Set parentNode = FindNodeByRowIndex(mTreeView.Nodes, parentRowIndex)
' 新しいノードを追加
Dim newNode As Node
Set newNode = mTreeView.Nodes.Add(parentNode, tvwChild, nodeText)
newNode.EnsureVisible
End If
End If
End Sub
' 行インデックスからノードを検索する
上記のコードでは、DataGridViewの CellValueChanged イベントで、DataGridViewの1列目に値が入力された場合にTreeViewに新しいノードを追加するようにしました。 最上位のノードの場合は、TreeViewの Nodes コレクションに新しいノードを追加します。それ以外の場合は、DataGridViewの前の行に追加されたノードの親ノードを検索し、TreeViewに新しい子ノードを追加します。 親ノードを検索するために、FindNodeByRowIndex というサブルーチンを使用しています。このサブルーチンは、TreeViewの Nodes コレクションを再帰的に探索し、指定された行インデックスに対応するノードを検索します。
Private Function FindNodeByRowIndex(nodes As Nodes, rowIndex As Long) As Node
Dim node As Node
For Each node In nodes
If node.Tag = rowIndex Then
' 行インデックスが一致するノードを見つけた
Set FindNodeByRowIndex = node
Exit Function
ElseIf node.Children.Count > 0 Then
' 子ノードを検索
Set FindNodeByRowIndex = FindNodeByRowIndex(node.Children, rowIndex)
If Not FindNodeByRowIndex Is Nothing Then
Exit Function
End If
End If
Next
End Function
このコードでは、Tag プロパティにDataGridViewの行インデックスを保存しています。これにより、TreeViewのノードを選択したときに、DataGridViewの対応する行を簡単に取得できます。 以上で、DataGridViewの1列目にツリービューを入れる方法のサンプルコードが完成しました。このコードを他のプロジェクトに追加して使用する場合は、DataGridViewの CellValueChanged イベントを処理するコードを追加する必要があります。また、TreeViewのノードを選択したときに、DataGridViewの対応する行を簡単に取得するために、TreeViewのノードに Tag プロパティを追加することをお勧めします。