Search code examples
excelvbatransposeunpivot

EXCEL VBA Transpose multiple columns to multiple rows with gaps inbetween columns


I have a large dataset to transpose and the code below does exactly that in the correct output however with a few too many columns. Currently the code will continuously read from column to column until it has them all. I would like to change this so I can select the first columns data, skip 3 columns then continue the script.

My Dataset:
UFI   CAT1    CAT2    CAT3    CAT4   CAT5   CAT6
RN1   Skip1   Skip2   Skip3   Copy1  Copy2  Copy3
RN2   Skip1   Skip2   Skip3   Copy1  Copy2  Copy3

Desired Output:
UFI    COLUMN   VALUES
RN1    CAT5     Copy1
RN1    CAT6     Copy2
RN1    CAT7     Copy3
RN2    CAT5     Copy1
RN2    CAT6     Copy2
RN2    CAT7     Copy3

Here is the VBA code below:

Option Explicit

Sub Tester()

Dim p

'get the unpivoted data as a 2-D array
p = UnPivotData(Sheets("Sheet1").Range("A1").CurrentRegion, _
                3, True, False)

Dim r As Long, c As Long
For r = 1 To UBound(p, 1)

    For c = 1 To UBound(p, 2)
        Sheets("Sheet2").Cells(r, c).Value = p(r, c)
    Next c

Next r

End Sub

Function UnPivotData(rngSrc As Range, fixedCols As Long, _
                 Optional AddCategoryColumn As Boolean = True, _
                 Optional IncludeBlanks As Boolean = True)

Dim nR As Long, nC As Long, data, dOut()
Dim r As Long, c As Long, rOut As Long, cOut As Long, cat As Long
Dim outRows As Long, outCols As Long

data = rngSrc.Value                          'get the whole table as a 2-D 
array
nR = UBound(data, 1)                         'how many rows
nC = UBound(data, 2)                         'how many cols

'calculate the size of the final unpivoted table
outRows = nR * (nC - fixedCols)
outCols = fixedCols + IIf(AddCategoryColumn, 2, 1)

'resize the output array
ReDim dOut(1 To outRows, 1 To outCols)

'populate the header row
For c = 1 To fixedCols
    dOut(1, c) = data(1, c)
Next c
If AddCategoryColumn Then
    dOut(1, fixedCols + 1) = "COLUMN"
    dOut(1, fixedCols + 2) = "VALUES"
Else
    dOut(1, fixedCols + 1) = "VALUES"
End If


'populate the data
rOut = 1
For r = 2 To nR
    For cat = fixedCols + 1 To nC


        If IncludeBlanks Or Len(data(r, cat)) > 0 Then
            rOut = rOut + 1
            'Fixed columns...
            For c = 1 To fixedCols
                dOut(rOut, c) = data(r, c)
            Next c
            'populate unpivoted values
            If AddCategoryColumn Then
                dOut(rOut, fixedCols + 1) = data(1, cat)
                dOut(rOut, fixedCols + 2) = data(r, cat)
            Else
                dOut(rOut, fixedCols + 1) = data(r, cat)
            End If
        End If

    Next cat
Next r

UnPivotData = dOut
End Function

Solution

  • Just for the sake of it:

    Sub Skip_and_Transpose()
    
    Dim Ws1 As Worksheet: Set Ws1 = Sheets(1)
    Dim Ws2 As Worksheet: Set Ws2 = Sheets(2)
    Dim P1 As Range: Set P1 = Ws1.UsedRange
    T1 = P1
    Dim T2()
    a = 1
    
    ReDim Preserve T2(1 To 3, 1 To a)
    T2(1, a) = "UFI"
    T2(2, a) = "COLUMN"
    T2(3, a) = "VALUES"
    a = a + 1
    
    For i = 2 To UBound(T1)
        For j = 5 To UBound(T1, 2)
            ReDim Preserve T2(1 To 3, 1 To a)
            T2(1, a) = T1(i, 1)
            T2(2, a) = T1(1, j)
            T2(3, a) = T1(i, j)
            a = a + 1
        Next j
    Next i
    
    Ws2.Range("A1").Resize(UBound(T2, 2), UBound(T2)) = Application.Transpose(T2)
    
    End Sub