Compiling and then splitting an array (array formula or VBA)

Matrovsky

New Member
Joined
Sep 6, 2022
Messages
5
Office Version
  1. 365
Platform
  1. Windows
So I have a table of widgets and the layers of material needed to make them:



TypeLayer 1Layer 2Layer 3Layer 4Layer 5Layer 6Layer 7
Type11.a
Type22.a
Type33.a3.b
Type44.a4.b4.c4.d4.e
Type55.a5.b5.c5.d
Type66.a6.b6.c

I need to transpose these values into something like this:


Type1 Type4 Type5
1.a 4.a 5.a
4.b 5.b
Type2 4.c 5.c
2.a 4.d 5.d
4.e
Type3 Type6
3.a 6.a
3.b 6.b
6.c

I already have an awkward function to do this, but it requires manually adjusting the size of each HSTACK element to generate (roughly) equal columns (FirstGroup, SecondGroup, and ThirdGroup are the manually-determined lengths of each column):

Excel Formula:
=LET(bigarray,
  VSTACK(
    LET(CurrEntry,1,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,2,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,3,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,4,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,5,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,6,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,7,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,8,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,9,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0)),"",
    LET(CurrEntry,10,CurrFilt,IFERROR(CHOOSECOLS(TRANSPOSE(tbl_Sample),CurrEntry),""),FILTER(CurrFilt,CurrFilt<>0))
        ),
  IFERROR(
    LET(FirstGroup,9,
        SecondGroup,7,
        ThirdGroup,10,
        HSTACK(
          CHOOSEROWS(bigarray,SEQUENCE(FirstGroup)),"",
          CHOOSEROWS(bigarray,SEQUENCE(SecondGroup,,FirstGroup+2)),"",
          CHOOSEROWS(bigarray,SEQUENCE(ThirdGroup,,FirstGroup+SecondGroup+2))
              )
        )
        ,"")
  )

I know there's an automated way to do this but I'm just not finding it. Can anyone help?

(I'd also rather have a dynamic VSTACK(TRANSPOSE(...)) option instead of making entries for each row of the table, but that's secondary.)

It doesn't have to be an array formula - the whole sheet will be generated with VBA so a code option is fine too.
 

Excel Facts

Workdays for a market open Mon, Wed, Friday?
Yes! Use "0101011" for the weekend argument in NETWORKDAYS.INTL or WORKDAY.INTL. The 7 digits start on Monday. 1 means it is a weekend.
Will this presentation work for you?

Book1
ABCDEFGH
1TypeLayer 1Layer 2Layer 3Layer 4Layer 5Layer 6Layer 7
2Type11.a
3Type22.a
4Type33.a3.b
5Type44.a4.b4.c4.d4.e
6Type55.a5.b5.c5.d
7Type66.a6.b6.c
8
9Type1Type2Type3Type4Type5Type6
101.a2.a3.a4.a5.a6.a
113.b4.b5.b6.b
124.c5.c6.c
134.d5.d
144.e
Sheet1


If the answer is yes, then Power Query is the answer

Power Query:
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Type"}, "Attribute", "Value"),
    #"Pivoted Column" = Table.Pivot(#"Unpivoted Other Columns", List.Distinct(#"Unpivoted Other Columns"[Type]), "Type", "Value"),
    #"Removed Columns" = Table.RemoveColumns(#"Pivoted Column",{"Attribute"})
in
    #"Removed Columns"
 
Upvote 0
Will this presentation work for you?

...

Unfortunately, no. The end result is part of an order form with a fixed format that can't be altered. It has to be three columns, ideally with the results spread equally across them. Thank you for the suggestion though.
 
Upvote 0
Here's a VBA option. Not my cleanest code, but it works:

VBA Code:
Sub StackTypes()
Dim Table As Range, Output As Range
Dim nr As Long, cnt() As Long, i As Long, j As Long
Dim b As Long, c As Long, an As Long, bn As Long, cn As Long
Dim m As Long, mm As Long, ixb As Long, ixc As Long
Dim r As Long, x As Long

    Set Table = Range("A2:H7")
    Set Output = Range("A10")
    
    nr = Table.Rows.Count
    ReDim cnta(1 To nr)
    For i = 1 To nr
        cnta(i) = WorksheetFunction.CountA(Table.Offset(i - 1).Resize(1))
    Next i
    
    mm = WorksheetFunction.Sum(cnta)
    
        For b = 2 To nr - 1
            For c = b + 1 To nr
                an = 0
                For i = 1 To b - 1
                    an = an + cnta(i)
                Next i
                bn = 0
                For i = b To c - 1
                    bn = bn + cnta(i)
                Next i
                cn = 0
                For i = c To nr
                    cn = cn + cnta(i)
                Next i
                m = WorksheetFunction.Max(an, bn, cn) - WorksheetFunction.Min(an, bn, cn)
                If m < mm Then
                    mm = m
                    ixb = b
                    ixc = c
                End If
            Next c
        Next b
    
    c = 0
    r = 0
    
    For i = 1 To ixb - 1
        x = 0
        While Table.Offset(i - 1, x).Resize(1, 1) <> ""
            Output.Offset(r, c) = Table.Offset(i - 1, x).Resize(1, 1)
            x = x + 1
            r = r + 1
        Wend
        r = r + 1
    Next i
    
    c = c + 2
    r = 0
    For i = ixb To ixc - 1
        x = 0
        While Table.Offset(i - 1, x).Resize(1, 1) <> ""
            Output.Offset(r, c) = Table.Offset(i - 1, x).Resize(1, 1)
            x = x + 1
            r = r + 1
        Wend
        r = r + 1
    Next i
    
    c = c + 2
    r = 0
    For i = ixc To nr
        x = 0
        While Table.Offset(i - 1, x).Resize(1, 1) <> ""
            Output.Offset(r, c) = Table.Offset(i - 1, x).Resize(1, 1)
            x = x + 1
            r = r + 1
        Wend
        r = r + 1
    Next i
    
End Sub

Change the first 2 indented lines to the input and output ranges you want. This is the result of that macro:

Book1
ABCDEFGH
1TypeLayer 1Layer 2Layer 3Layer 4Layer 5Layer 6Layer 7
2Type11.a
3Type22.a
4Type33.a3.b
5Type44.a4.b4.c4.d4.e
6Type55.a5.b5.c5.d
7Type66.a6.b6.c
8
9
10Type1Type4Type5
111.a4.a5.a
124.b5.b
13Type24.c5.c
142.a4.d5.d
154.e
16Type3Type6
173.a6.a
183.b6.b
196.c
Sheet3
 
Upvote 0

Forum statistics

Threads
1,224,919
Messages
6,181,747
Members
453,064
Latest member
robatthe2A

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