Transpose grouped blocks of data with macro or formula?

Fractalis

Active Member
Joined
Oct 11, 2011
Messages
333
Office Version
  1. 365
Platform
  1. Windows
Hi all,

I'm trying with formula to transpose a data which is in stacked in vertical way.

There are blocks grouped by the CODE. For instance group with CODE=ABC has several parameters and corresponding values. I'm interested in PARAM_2, 4, 5, 6 and 7.
* PARAMETER_5 sometimes the has more than one value and appear in same cell. In output I'd like to have them in different cells if possible.
* PARAMETER_7 could appear several times (repeated) but with different values.

Below I show the input, my current attempt with CHOOSECOLS(FILTER(...)) and the output I'm looking for. I hope make sense.

Thanks for any help.


TransposeData
ABCDEFGHIJKLMNO
1CODEPARAMETERVALUEPARAM_2PARAM_4PARAM_5PARAM_6PARAM_7PARAM_2PARAM_4PARAM_5PARAM_6PARAM_7
2ABCPARAM_1 ABC4431518742 1087 411387305 ABC44315187428730593552
3ABCPARAM_2ABCTTU3001918818730593552ABC108711573
4ABCPARAM_3 11573ABC411344272
5ABCPARAM_444315144272ABC99827
6ABCPARAM_58742 1087 411399827TTU3001918818730593552
7ABCPARAM_687305 TTU11573
8ABCPARAM_7 93552
9ABCPARAM_79355211573
10ABCPARAM_711573
11ABCPARAM_744272Current OutputOutput I'm looking for
12ABCPARAM_799827
13ABCPARAM_8
14TTUPARAM_1
15TTUPARAM_2TTU
16TTUPARAM_3
17TTUPARAM_430019
18TTUPARAM_51881
19TTUPARAM_687305
20TTUPARAM_7
21TTUPARAM_793552
22TTUPARAM_711573
23TTUPARAM_8
Sheet1
Cell Formulas
RangeFormula
I2:I9,E2:H3E2=CHOOSECOLS(FILTER($B$1:$C$23,$B$1:$B$23=E$1,""),2)
Dynamic array formulas.
 
VBA
Code:
Sub test()
    Dim a, b, e, myList, col, i&, ii&, n&(1), s
    With [a1].CurrentRegion
        myList = .Parent.Evaluate("transpose(sort(unique(filter(" & _
            .Offset(1).Columns(2).Address & "," & .Offset(1).Columns(3).Address & _
            "<>""""))))")
        a = .Value: ReDim b(1 To UBound(a, 1), 1 To UBound(a, 1)): n(0) = 1
        For i = 1 To UBound(myList)
            b(1, i) = myList(i)
        Next
    End With
    For i = 2 To UBound(a, 1)
        If a(i, 3) <> "" Then
            col = Application.Match(a(i, 2), myList, 0)
            If s <> a(i, 1) Then
                s = a(i, 1): n(0) = n(0) + 1: n(1) = n(0): a(n(0), 1) = s
            End If
            For Each e In Split(a(i, 3), vbLf)
                For ii = n(1) To UBound(b, 1)
                    If b(ii, col) = "" Then
                        b(ii, 1) = s: b(ii, col) = e
                        If n(0) < ii Then n(0) = ii
                        Exit For
                    End If
                Next
            Next
        End If
    Next
    With [e1]
        .CurrentRegion.ClearContents
        .Resize(n(0), UBound(myList) + 1) = b
    End With
End Sub
 
Upvote 0
Solution
One possible formula option, based on the sample data provided:
Excel Formula:
=LET(
   rng, DROP(TRIMRANGE(A:C,2,0),1),
   var, TAKE(rng,,-1),
   chr, CHAR(10),
   arr, IFS((var<>TAKE(rng,,1))*(var<>""),TEXTBEFORE(TEXTAFTER(chr&var&chr,chr,SEQUENCE(,MAX(LEN(var)-LEN(SUBSTITUTE(var,chr,)))+1)),chr)),
   lbl, CHOOSEROWS(TAKE(rng,,2),TOCOL(IF(ISERROR(arr),arr,SEQUENCE(ROWS(rng))),2)),
   val, TOCOL(arr,2),
   pvt, PIVOTBY(HSTACK(TAKE(lbl,,1),INSTANCENUMλ(lbl)),DROP(lbl,,1),IFERROR(--(val),val),SINGLE,0,0,,0),
   HSTACK(TAKE(pvt,,1),DROP(pvt,,2))
)

Where INSTANCENUMλ is a custom function defined in Name Manager as follows:
Excel Formula:
=LAMBDA(fields,
   IF(
      ROWS(fields) = 1,
      1,
      LET(
         arr, IF(
            COLUMNS(fields) = 1,
            fields,
            BYROW(fields, LAMBDA(r, TEXTJOIN("|", 0, r)))
         ),
         srt, SORT(HSTACK(arr, SEQUENCE(ROWS(arr)))),
         key, TAKE(srt,, 1),
         SORTBY(SCAN(0, key = VSTACK("", DROP(key, -1)), LAMBDA(a,v, 1 + a * v)), DROP(srt,, 1))
      )
   )
)

Note: if the new TRIMRANGE function is not yet available to you, just define the rng variable manually (e.g. A2:C23 in this case).

Alternatively, to single-out specifice paramters:
Excel Formula:
=LET(
   rng, DROP(TRIMRANGE(A:C,2,0),1),
   tbl, FILTER(rng,ISNUMBER(XMATCH(INDEX(rng,,2),{"PARAM_4","PARAM_5","PARAM_6","PARAM_7"},,2))*(TAKE(rng,,-1)<>"")),
   var, TAKE(tbl,,-1),
   chr, CHAR(10),
   arr, TEXTBEFORE(TEXTAFTER(chr&var&chr,chr,SEQUENCE(,MAX(LEN(var)-LEN(SUBSTITUTE(var,chr,)))+1)),chr),
   lbl, CHOOSEROWS(TAKE(tbl,,2),TOCOL(IF(ISERROR(arr),arr,SEQUENCE(ROWS(tbl))),2)),
   val, TOCOL(arr,2),
   pvt, PIVOTBY(HSTACK(TAKE(lbl,,1),INSTANCENUMλ(lbl)),DROP(lbl,,1),IFERROR(--(val),val),SINGLE,0,0,,0),
   HSTACK(TAKE(pvt,,1),DROP(pvt,,2))
)
 
Last edited:
Upvote 1

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