excelvbagroupingtree-structure

Group an Excel table in up to seven levels


I have Excel tables to group, to work further with them. The content of the tables comes from software, where the content was divided tree-like in up to seven levels.

I want to rebuild this structure in Excel via VBA.

In the tables the level of each row is written in column A:
enter image description here

In the end it should be structured like in the software:
enter image description here

The result I need:
enter image description here

My code:

Sub GRUPPIEREN()
Dim mainWB  As Workbook
Dim xlFileName As String

Set mainWB = ThisWorkbook

' Schritt 2: Iterate durch Zeilen und apply groups
With mainWB.Sheets("TEST")

Dim LastRow As Long, i As Long
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row

' Stukturebenen als Variablen
Dim Ebene1 As Long
Dim Ebene2 As Long
Dim Ebene3 As Long
Dim Ebene4 As Long
Dim Ebene5 As Long

' find firsts
Dim start As Long
Dim Ebene As Long
Dim Offset As Long
Offset = 0
    
For i = 2 To LastRow
    Ebene = .Range("A" & i).Value
    If Ebene = 1 Then
        Ebene1 = i
        End If
    If Ebene = 2 Then
        Ebene2 = i
        End If
    If Ebene = 3 Then
       Ebene3 = i
        End If
    If Ebene = 4 Then
       Ebene4 = i
        End If
    If Ebene = 5 Then
       Ebene5 = i
       start = i + 1
        Exit For
    End If
Next i

For i = start To LastRow
    ' check format
    Ebene = .Range("A" & i).Value
        ' Ebene 1
        If Ebene = 1 Then
            If ((i - Ebene1) > 1) Then
                ' Neue Gruppe 1
                .Rows((Ebene1) & ":" & (i - 1)).Group
                ' leere row fuer verschachtelte Gliederung
                'OLD:.Rows(i & ":" & i).EntireRow.Insert
            End If
            
            Ebene1 = i + 1
            Offset = 0
        End If
        ' Ebene 2
        If Ebene = 2 Then
            If ((i - Ebene2) > 1) Then
                ' Neue Gruppe 2
                .Rows((Ebene2 + 1) & ":" & (i - 1 - Offset)).Group
            End If
            Offset = 0
            Ebene2 = i
        End If
        ' Ebene 3
        If Ebene = 3 Then
            If ((i - Ebene3) > 1) Then
                ' Neue Gruppe 3
                .Rows((Ebene3 + 1) & ":" & (i - 1 - Offset)).Group
            End If
            Offset = 0
            Ebene3 = i
        End If
        ' Ebene 4
        If Ebene = 4 Then
            If ((i - Ebene4) > 1) Then
                ' Neue Gruppe 4
                .Rows((Ebene4 + 1) & ":" & (i - 1 - Offset)).Group
            End If
            Offset = 0
            Ebene4 = i
        End If
        ' Ebene 5
        If Ebene = 5 Then
            If ((.Range("A" & i).Value - Ebene5) > 1) Then
                ' Neue Gruppe 5
                .Rows((Ebene5 + 1) & ":" & (i - 1 - Offset)).Group
            End If
            Offset = 0
            Ebene5 = i
        End If
Next i

' Schritt 3: Schliesse uebrige Gruppen ab
' Ebene 1
If (((LastRow + 1) - Ebene1) > 1) Then
    ' Neue Gruppe 1
    .Rows((Ebene1) & ":" & (LastRow)).Group
    ' leere row fuer verschachtelte Gliederung
    'OLD:.Rows((LastRow + 1) & ":" & (LastRow + 1)).EntireRow.Insert
End If

' Ebene 2
If (((LastRow + 1) - Ebene2) > 1) Then
    ' Neue Gruppe 2
    .Rows((Ebene2 + 1) & ":" & (LastRow)).Group
End If
' Ebene 3
If (((LastRow + 1) - Ebene3) > 1) Then
    ' Neue Gruppe 3
    .Rows((Ebene3 + 1) & ":" & (LastRow)).Group
End If
' Ebene 4
If (((LastRow + 1) - Ebene4) > 1) Then
    ' Neue Gruppe 4
    .Rows((Ebene4 + 1) & ":" & (LastRow)).Group
End If
' Ebene 5
If (((LastRow + 1) - Ebene5) > 1) Then
    ' Neue Gruppe 5
    .Rows((Ebene5 + 1) & ":" & (LastRow)).Group
End If
End With 

End Sub

It groups up to the 5th level, but the first Group on Level 1 is one row too high:
enter image description here

I think level 5 is good, but all others don't find the right end:
enter image description here


Solution

  • Pls try.

    Sub MultiLevelGroup()
        Dim i As Long, j As Long
        Dim arrData, iVal As Long, iEnd As Long
        Dim LastRow As Long
        ' Get the last row#
        LastRow = Cells(Rows.Count, "A").End(xlUp).Row
        With Range("A1:A" & LastRow)
            ' Clear outline
            .ClearOutline
            .Parent.Outline.SummaryRow = xlSummaryAbove
            ' Load data into an array
            arrData = .Value
        End With
        ' Loop through data
        For i = LBound(arrData) + 1 To LastRow - 1
            If arrData(i, 1) < arrData(i + 1, 1) Then
                iVal = arrData(i, 1)
                iEnd = 0
                ' Locate the end of each group
                For j = i + 2 To LastRow
                    If arrData(j, 1) <= iVal Then
                        iEnd = j - 1
                        Exit For
                    End If
                Next
                If iEnd = 0 Then iEnd = LastRow
                If iEnd >= i + 1 Then
                    ' Group rows
                    Range(Cells(i + 1, 1), Cells(iEnd, 1)).Rows.Group
                End If
            End If
        Next i
    End Sub
    

    Microsoft documentation:

    Range.Group method (Excel)

    Range.ClearOutline method (Excel)

    Outline.SummaryRow property (Excel)

    enter image description here