【问题标题】:Build hierarchy type presentation of data in Excel在 Excel 中构建数据的层次结构类型表示
【发布时间】:2016-12-02 22:25:59
【问题描述】:

我尝试使用 vba 将我的 excel 数据转换为树数据。

Sub MakeTree()

    Dim r As Integer
    ' Iterate through the range, looking for the Root
    For r = 1 To Range("Data").Rows.Count
        If Range("Data").Cells(r, 1) = "Root" Then
            DrawNode Range("Data").Cells(r, 2), 0, 0
        End If
    Next

End Sub

Sub DrawNode(ByRef header As String, ByRef row As Integer, ByRef depth As Integer)
'The DrawNode routine draws the current node, and all child nodes.
' First we draw the header text:
    Cells(Range("Destination").row + row, Range("Destination").Column + depth) = header

    Dim r As Integer
    'Then loop through, looking for instances of that text
    For r = 1 To Range("Data").Rows.Count
        If Range("Data").Cells(r, 1) = header Then
        'Bang!  We've found one!  Then call itself to see if there are any child nodes
            row = row + 1
            DrawNode Range("Data").Cells(r, 2), row, depth + 1
        End If
    Next
End Sub

我的excel数据是这样的,

我尝试使用我的 vba 代码来转换这样的树数据。

但上面的代码对我不起作用。

有人推荐我吗?

谢谢

【问题讨论】:

  • 我建议您开始编码,然后在遇到特定问题时再提出问题。这不是代码工厂。顺便说一句,您尝试制作的树与链接问题中的树不同,因此完全相同的方法无论如何都行不通。
  • 当您最初发布问题时我已经解决了这个问题,但没有发布我的答案,因为您不会发布您的代码。现在您将 Christian Payne 的答案发布到 Build a tree like representation of data in Excel?,就好像它是您自己的一样!!!
  • 对不使用数据透视表的解决方案感兴趣?

标签: excel vba tree treeview


【解决方案1】:

试试这个,它使用了一个临时数据透视表...

Option Explicit

Sub TestMakeTree()


    Dim wsData As Excel.Worksheet
    Set wsData = ThisWorkbook.Worksheets.Item("Sheet1")

    Dim rngData As Excel.Range
    Set rngData = wsData.Range("Data")  '<----------------- this differs for me


    Dim vTree As Variant
    vTree = MakeTreeUsingPivotTable(ThisWorkbook, rngData)

    '* print it out next to data, you'd choose your own destination

    Dim rngDestinationOrigin As Excel.Range
    Set rngDestinationOrigin = wsData.Cells(rngData.Row, rngData.Columns.Count + 2)

    rngDestinationOrigin.Resize(UBound(vTree, 1), UBound(vTree, 2)) = vTree


End Sub

Function MakeTreeUsingPivotTable(ByVal wb As Excel.Workbook, ByVal rngData As Excel.Range) As Variant


    Dim oPivotCache As PivotCache
    Set oPivotCache = CreatePivotCache(wb, rngData)


    Application.ScreenUpdating = False
    Dim wsTemp As Excel.Worksheet
    Set wsTemp = wb.Worksheets.Add


    Dim oPivotTable As Excel.PivotTable
    Set oPivotTable = CreatePivotTableAndAddColumns(wsTemp, oPivotCache, rngData.Rows(1))
    oPivotTable.RowAxisLayout xlOutlineRow
    oPivotTable.ColumnGrand = False
    oPivotTable.RowGrand = False

    MakeTreeUsingPivotTable = oPivotTable.TableRange1.Value2
    Application.DisplayAlerts = False
    wsTemp.Delete
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True

End Function

Function CreatePivotTableAndAddColumns(ByVal wsDestination As Excel.Worksheet, _
            ByVal oPivotCache As Excel.PivotCache, ByVal rngColumnHeaders As Excel.Range)
    Const csTEMP_PIVOT_NAME As String = "TempMakeTreePivot"
    Dim sThirdRowDown As String
    sThirdRowDown = "'" & wsDestination.Name & "'!R3C1"

    Dim oPivotTable As Excel.PivotTable
    Set oPivotTable = oPivotCache.CreatePivotTable(TableDestination:=sThirdRowDown, _
                    TableName:=csTEMP_PIVOT_NAME, DefaultVersion:=xlPivotTableVersion15)

    Dim rngColumnLoop As Excel.Range, lLoop As Long
    For Each rngColumnLoop In rngColumnHeaders.Cells
        lLoop = lLoop + 1
        With oPivotTable.PivotFields(rngColumnLoop.Value2)
            .Orientation = xlRowField
            .Position = lLoop
        End With

    Next rngColumnLoop

    Set CreatePivotTableAndAddColumns = oPivotTable

End Function

Function CreatePivotCache(ByVal wb As Excel.Workbook, ByVal rngData As Excel.Range)
    Dim sFullyQualified As String
    sFullyQualified = "'" & rngData.Parent.Name & "'!" & rngData.Address

    Dim oPivotCache As PivotCache
    Set oPivotCache = wb.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
        sFullyQualified, Version:=xlPivotTableVersion15)
    Set CreatePivotCache = oPivotCache
End Function

【讨论】:

  • @S Meaden 我收到错误消息(运行时 1004:对象“_Worksheet”的方法“范围”失败)。
  • @Venkat 在哪一行?
  • @S Meaden 它只显示“对象'_worksheet'的方法'范围'”失败。我在网上搜索这个问题。但没有运气。
  • @Venkat:当该消息出现在对话框中时,底部是否没有四个按钮,包括一个调试按钮?如果是这样,请按调试按钮,它将以黄色突出显示问题行。请注意,由于您没有指定工作簿的结构,因此我的工作表数据将与您的不同。
  • 我怀疑@Venkat 从未定义过wsData.Range("Data")。很好的答案。
【解决方案2】:

另一个提议

Sub aaargh()
Dim o(3)
    Set ws1 = Sheet1 ' source sheet to adapt
    Set ws2 = Sheet3 ' target sheet to adapt
    With ws1
        nv = .Cells(.Rows.Count, 1).End(xlUp).Row
        .Range("A1:C" & nv).Sort key1:=.Range("a1"), order1:=xlAscending, _
                                 key2:=.Range("B1"), order2:=xlAscending, _
                                 key3:=.Range("C1"), order3:=xlAscending, _
                                 Header:=xlYes
        ctrl = 0
        For i = 2 To nv
            fl = False
            For j = 1 To 3
                If o(j) <> .Cells(i, j) Or fl = True Then
                    ctrl = ctrl + 1
                    o(j) = .Cells(i, j)
                    ws2.Cells(ctrl, j) = o(j)
                    fl = True
                End If
            Next j
            ctrl = ctrl + 1
            ws2.Cells(ctrl, 4) = .Cells(i, 4)
        Next i
    End With
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2021-12-06
    • 2019-07-05
    • 2012-10-29
    相关资源
    最近更新 更多