【问题标题】:How to create an Excel Hierarchy如何创建 Excel 层次结构
【发布时间】:2023-04-08 19:46:02
【问题描述】:

我正在尝试创建 Excel 层次结构(与此问题非常相似) Creating an excel hierarchy

但我的 Excel 文件的结构完全不同。 请通过对比查看我的文件布局:

我希望将其作为数据透视表中的可扩展层次结构或通过 VBA(更简单的方法),如下所示:

虽然上图显示了层,但我想要的输出将使用层值。这就是上面提到的结构意味着它不像链接问题中的步骤那么容易。

这是我想要实现的示例。

任何帮助或指导将不胜感激。

谢谢, 斯特凡。

【问题讨论】:

  • 请包括您展示的示例的预期结果。
  • 如果您不能准确地解释您需要什么,那么向我们展示您想要的输出的图片有那么难吗?您向我们展示的图片是从链接的问题中复制的,因为它在那里,与您的问题没有任何联系。这个问题,正如它所表达的那样,只有在你的脑海中是清楚的。如果您真的需要帮助,您必须至少努力让我们了解您想要什么......
  • 使用数据透视表并选择“大纲形式”layout option。删除subtotals
  • 大家好,我已经修改了问题以解释我需要将 Level 值用作 Tier 的等价物(但我的 excel 文件的结构与链接的问题)。
  • 但是您应该能够手动创建您需要的输出示例 - 使用您的数据。也许通过创建它,您已经了解了如何迁移原始数据集。 ...

标签: excel vba pivot-table


【解决方案1】:

脚本只需要这些列:

Option Explicit

Public Sub Example()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Source")
    
    Dim LastRow As Long
    LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    ' read data into array
    Dim PartNumber() As Variant
    PartNumber = ws.Range("D2", "D" & LastRow).Value

    Dim PartDescription() As Variant
    PartDescription = ws.Range("E2", "E" & LastRow).Value

    Dim PartLevel() As Variant
    PartLevel = ws.Range("F2", "F" & LastRow).Value

    Dim PartParent() As Variant
    PartParent = ws.Range("G2", "G" & LastRow).Value
    
    ' creat a tree
    Dim RootTree As Object
    Set RootTree = CreateObject("Scripting.Dictionary")
    
    ' fill tree with data
    Dim iRow As Long
    For iRow = LBound(PartNumber, 1) To UBound(PartNumber, 1)
        If PartLevel(iRow, 1) = 0 Then
            ' create root
            ' ------------
            RootTree.Add PartNumber(iRow, 1), CreateObject("Scripting.Dictionary")
        Else
            ' create all children
            ' --------------------
            Dim BacktraceLevel As Long
            BacktraceLevel = PartLevel(iRow, 1)
            ReDim Backtrace(1 To BacktraceLevel)
            
            Backtrace(BacktraceLevel) = PartParent(iRow, 1)
            BacktraceLevel = BacktraceLevel - 1
            
            ' backtrace from current child to root
            Do While BacktraceLevel > 0
                DoEvents
                Dim FoundAt As Double
                FoundAt = Application.WorksheetFunction.Match(Backtrace(BacktraceLevel + 1), PartNumber, 0)
                If PartLevel(FoundAt, 1) <> 0 Then
                    Backtrace(BacktraceLevel) = PartParent(FoundAt, 1)
                End If
                BacktraceLevel = BacktraceLevel - 1
            Loop
            
            ' climb tree until child can be added
            Dim Parent As Object
            Set Parent = RootTree
            Dim b As Long
            For b = 1 To UBound(Backtrace)
                Set Parent = Parent(Backtrace(b))
            Next b
            
            ' add current child
            Parent.Add PartNumber(iRow, 1), CreateObject("Scripting.Dictionary")
        End If
    Next iRow
    
    ' output tree
    OutputTree RootTree, Worksheets("output").Range("A1"), PartNumber, PartDescription
End Sub

Private Sub OutputTree(ByVal Tree As Object, ByVal StartOutput As Range, ByVal PartNumber As Variant, ByVal PartDescription As Variant, Optional ByVal Level As Long = 0)
    Static iRow As Long
    
    Dim Key As Variant
    For Each Key In Tree.Keys
        StartOutput.Offset(RowOffset:=iRow, ColumnOffset:=Level).Value = PartDescription(Application.WorksheetFunction.Match(Key, PartNumber, 0), 1)
        iRow = iRow + 1
        If VarType(Tree(Key)) = 9 Then
            OutputTree Tree(Key), StartOutput, PartNumber, PartDescription, Level + 1
        End If
    Next
End Sub

它会输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2019-07-03
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多