Organize Level Hierarchy into Source-Target List

xdulin

New Member
Joined
Apr 9, 2024
Messages
3
Office Version
  1. 2016
Platform
  1. Windows
I have 2 columns populated, where one column indicates the Level or Tier of the elements Named in the 2nd column. From these 2 columns, I'm trying to generate a Source-Target list as shown in the image. The tan highlighted grid is simply a visualization and may not be a necessary step in generating the Source-Target list from the Level and Name columns.
 

Attachments

  • Source-Target.jpg
    Source-Target.jpg
    178.4 KB · Views: 8

Excel Facts

Last used cell?
Press Ctrl+End to move to what Excel thinks is the last used cell.
Try on a copy. Assume data is in Column A and B. Outputing to Column D.
VBA Code:
Sub Levels()
    Dim a, b()
    Dim i As Long, j As Long, k As Long, numRow As Long
    Dim ws As Worksheet
    Dim rng As Range
    Set ws = ThisWorkbook.Worksheets("Sheet2") 'change sheet as needed
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    a = ws.Range("A1:B" & numRow).Value
    k = 1

    ReDim b(1 To numRow * numRow, 1 To 3)
    For i = 2 To numRow
        For j = i + 1 To numRow
            If a(i, 1) + 1 = a(j, 1) Then
                b(k, 1) = a(i, 2)
                b(k, 2) = a(j, 2)
                b(k, 3) = a(i, 1)
                k = k + 1
            End If
        Next j
    Next i

    Set rng = ws.Range("D2").Resize(k - 1, 3)
    rng.Value = b
   
    ' Sort by levels (column 3 in ascending order)
    With ws.Sort
        .SortFields.Clear
        .SortFields.Add key:=rng.Columns(3), SortOn:=xlSortOnValues, Order:=xlAscending
        .SetRange rng
        .Header = xlNo
        .MatchCase = False
        .Apply
    End With

    b = ws.Range("D2").Resize(k - 1, 3).Value
    rng.Value = b
End Sub
 
Upvote 0
Try on a copy. Assume data is in Column A and B. Outputing to Column D.
VBA Code:
Sub Levels()
    Dim a, b()
    Dim i As Long, j As Long, k As Long, numRow As Long
    Dim ws As Worksheet
    Dim rng As Range
    Set ws = ThisWorkbook.Worksheets("Sheet2") 'change sheet as needed
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    a = ws.Range("A1:B" & numRow).Value
    k = 1

    ReDim b(1 To numRow * numRow, 1 To 3)
    For i = 2 To numRow
        For j = i + 1 To numRow
            If a(i, 1) + 1 = a(j, 1) Then
                b(k, 1) = a(i, 2)
                b(k, 2) = a(j, 2)
                b(k, 3) = a(i, 1)
                k = k + 1
            End If
        Next j
    Next i

    Set rng = ws.Range("D2").Resize(k - 1, 3)
    rng.Value = b
  
    ' Sort by levels (column 3 in ascending order)
    With ws.Sort
        .SortFields.Clear
        .SortFields.Add key:=rng.Columns(3), SortOn:=xlSortOnValues, Order:=xlAscending
        .SetRange rng
        .Header = xlNo
        .MatchCase = False
        .Apply
    End With

    b = ws.Range("D2").Resize(k - 1, 3).Value
    rng.Value = b
End Sub
Hi Cubist,

Thanks for this.

This code almost gets there. Except that, if a Thing_# has a Level that falls underneath a preceding Level, it shouldn't be listed again in the Source-Target list.

From the image:
Thing_1 -> Thing_2
Thing_1 -> Thing_15
Thing_2 -> Thing_3
Thing_2 -> Thing_6
Thing_2 -> Thing_7
Thing_2 -> Thing_14
Thing_15 -> Thing_16
Thing_15 -> Thing_17

Note: Thing_2 should not trace to Thing_16, 17 as they both are to fall under Thing_15.

Much appreciated.
 
Upvote 0
Ok, how about this?
VBA Code:
Sub Levels()
    Dim a, b()
    Dim i As Long, j As Long, k As Long, numRow As Long
    Dim ws As Worksheet
    Dim rng As Range
    Set ws = ThisWorkbook.Worksheets("Sheet5") 'change sheet as needed
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    a = ws.Range("A1:B" & numRow).Value
    k = 1

    ReDim b(1 To numRow * numRow, 1 To 3)
    For i = 2 To numRow
        For j = i + 1 To numRow
            If a(i, 1) = a(j, 1) Then
                Exit For
            Else
                If a(i, 1) + 1 = a(j, 1) Then
                    b(k, 1) = a(i, 2)
                    b(k, 2) = a(j, 2)
                    b(k, 3) = a(i, 1)
                    k = k + 1
                End If
            End If
        Next j
    Next i

    Set rng = ws.Range("D2").Resize(k - 1, 3)
    rng.Value = b
  
    ' Sort by levels (column 3 in ascending order)
    With ws.Sort
        .SortFields.Clear
        .SortFields.Add key:=rng.Columns(3), SortOn:=xlSortOnValues, Order:=xlAscending
        .SetRange rng
        .Header = xlNo
        .MatchCase = False
        .Apply
    End With

    b = ws.Range("D2").Resize(k - 1, 3).Value
    rng.Value = b
End Sub

This is what I'm getting.
Book1.xlsb
ABCDEFG
1Level Name
21Thing_1Thing_1Thing_21
32Thing_2Thing_1Thing_151
43Thing_3Thing_2Thing_32
54Thing_4Thing_2Thing_62
64Thing_5Thing_2Thing_72
73Thing_6Thing_2Thing_142
83Thing_7Thing_15Thing_162
94Thing_8Thing_15Thing_172
105Thing_9Thing_3Thing_43
115Thing_10Thing_3Thing_53
126Thing_11Thing_7Thing_83
135Thing_12Thing_7Thing_133
144Thing_13Thing_17Thing_183
153Thing_14Thing_8Thing_94
162Thing_15Thing_8Thing_104
173Thing_16Thing_8Thing_124
183Thing_17Thing_18Thing_194
194Thing_18Thing_10Thing_115
205Thing_19Thing_19Thing_205
216Thing_20Thing_20Thing_216
227Thing_21
Sheet5
 
Upvote 0
Ok, how about this?
VBA Code:
Sub Levels()
    Dim a, b()
    Dim i As Long, j As Long, k As Long, numRow As Long
    Dim ws As Worksheet
    Dim rng As Range
    Set ws = ThisWorkbook.Worksheets("Sheet5") 'change sheet as needed
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    a = ws.Range("A1:B" & numRow).Value
    k = 1

    ReDim b(1 To numRow * numRow, 1 To 3)
    For i = 2 To numRow
        For j = i + 1 To numRow
            If a(i, 1) = a(j, 1) Then
                Exit For
            Else
                If a(i, 1) + 1 = a(j, 1) Then
                    b(k, 1) = a(i, 2)
                    b(k, 2) = a(j, 2)
                    b(k, 3) = a(i, 1)
                    k = k + 1
                End If
            End If
        Next j
    Next i

    Set rng = ws.Range("D2").Resize(k - 1, 3)
    rng.Value = b
 
    ' Sort by levels (column 3 in ascending order)
    With ws.Sort
        .SortFields.Clear
        .SortFields.Add key:=rng.Columns(3), SortOn:=xlSortOnValues, Order:=xlAscending
        .SetRange rng
        .Header = xlNo
        .MatchCase = False
        .Apply
    End With

    b = ws.Range("D2").Resize(k - 1, 3).Value
    rng.Value = b
End Sub

This is what I'm getting.
Book1.xlsb
ABCDEFG
1Level Name
21Thing_1Thing_1Thing_21
32Thing_2Thing_1Thing_151
43Thing_3Thing_2Thing_32
54Thing_4Thing_2Thing_62
64Thing_5Thing_2Thing_72
73Thing_6Thing_2Thing_142
83Thing_7Thing_15Thing_162
94Thing_8Thing_15Thing_172
105Thing_9Thing_3Thing_43
115Thing_10Thing_3Thing_53
126Thing_11Thing_7Thing_83
135Thing_12Thing_7Thing_133
144Thing_13Thing_17Thing_183
153Thing_14Thing_8Thing_94
162Thing_15Thing_8Thing_104
173Thing_16Thing_8Thing_124
183Thing_17Thing_18Thing_194
194Thing_18Thing_10Thing_115
205Thing_19Thing_19Thing_205
216Thing_20Thing_20Thing_216
227Thing_21
Sheet5

This looks to be working Cubist!

Very much appreciated,
Xavier
 
Upvote 0
You're welcome. Glad to help. Cheers.
 
Upvote 0

Forum statistics

Threads
1,215,406
Messages
6,124,720
Members
449,184
Latest member
COrmerod

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top