以下は、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 プロパティを追加することをお勧めします。