Home > Back-end >  Paste Transpose while the first 2 columns will constant? Using VBA or Power Query
Paste Transpose while the first 2 columns will constant? Using VBA or Power Query

Time:02-05

I have data that always changes also it doesn't have the headers.

Like here I have data in 7 rows (The count of the rows can change every time.) ?

enter image description here Now I want to filter in the 2nd column with the value Sub-Catg. which always be available in the 2nd column.

The filtered data will look like this ?

enter image description here

The number of rows and columns can vary every time in each data set.

Now I want to copy the data of filtered all the rows and pastes in the below format. ?

enter image description here

CodePudding user response:

Transpose (Unpivot) Data (VBA)

Option Explicit

Sub TransposeData()
    
    ' Source
    Const sName As String = "Sheet1"
    Const sCol As Long = 2
    Const sCriterion As String = "Sub-Catg."
    ' Destination
    Const dName As String = "Sheet2"
    Const dfCellAddress As String = "A2"
    ' Workbook
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    ' Source
    Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
    If sws.AutoFilterMode Then sws.AutoFilterMode = False
    Dim surg As Range: Set surg = sws.UsedRange
    Dim scrCount As Long
    scrCount = Application.CountIf(surg.Columns(sCol), sCriterion)
    If scrCount = 0 Then Exit Sub ' no criterion found
    Dim scCount As Long: scCount = surg.Columns.Count
    If scCount <= sCol Then Exit Sub ' no data after criteria column
    Dim sData As Variant: sData = surg.Value
    
    ' Destination
    ' 'drCount' is actually the maximum possible number of rows.
    ' The result will probably have fewer ('dr').
    Dim drCount As Long: drCount = scrCount * (scCount - sCol)
    Dim dcCount As Long: dcCount = sCol   1
    Dim dData As Variant: ReDim dData(1 To drCount, 1 To dcCount)
    Dim dr As Long: dr = 1
    
    Dim sValue As Variant
    Dim sr As Long
    Dim sc As Long
    Dim cdr As Long
    Dim dc As Long
    
    ' Write to destination array ('dData')
    For sr = 1 To UBound(sData, 1)
        If CStr(sData(sr, sCol)) = sCriterion Then ' criterion found
            cdr = dr
            ' Write after criterion.
            ' Looping until the last column allows blanks in-between
            ' at the cost of the code being a little slower.
            For sc = sCol   1 To scCount
                If Len(CStr(sData(sr, sc))) > 0 Then
                    dData(dr, dcCount) = sData(sr, sc)
                    dr = dr   1
                End If
            Next sc
            If dr > cdr Then ' values after criterion found
                ' Write criterion and before.
                For sc = 1 To sCol
                    dData(cdr, sc) = sData(sr, sc)
                Next sc
            'Else ' no value after criterion found
            End If
        'Else ' criterion not found
        End If
    Next sr
    
    If dr = 1 Then Exit Sub ' no values found
    dr = dr - 1
     
    ' Write to destination range.
    Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
    With dws.Range(dfCellAddress).Resize(, dcCount)
        ' Write to range.
        .Resize(dr).Value = dData
        ' Clear below.
        .Resize(dws.Rows.Count - .Row - dr   1).Offset(dr).Clear
    End With

    MsgBox "Data transposed.", vbInformation

End Sub
  •  Tags:  
  • Related