Это пример того, как циклически проходить через ваши данные с использованием массива.
Option Explicit
Public Sub UnPivotData()
Dim wsSrc As Worksheet 'define source sheet
Set wsSrc = ThisWorkbook.Worksheets("Source")
Dim wsDest As Worksheet 'define output sheet
Set wsDest = ThisWorkbook.Worksheets("Destination")
Dim LastRow As Long 'find last used row
LastRow = wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row
Dim LastCol As Long 'find last used column
LastCol = wsSrc.Cells(1, wsSrc.Columns.Count).End(xlToLeft).Column
Dim srcArr As Variant 'read data range into an array (makes it faster)
srcArr = wsSrc.Range("A1", wsSrc.Cells(LastRow, LastCol)).Value
Dim OutRow As Long 'find next free output row in destination sheet.
OutRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row + 1
Dim iRow As Long, iCol As Long
For iRow = 2 To UBound(srcArr) 'loop through all rows
For iCol = 3 To UBound(srcArr, 2) 'loop through month columns
If srcArr(iRow, iCol) <> 0 Then 'check if quantity is not 0
With wsDest.Cells(OutRow, 1) 'write everything
.Value = srcArr(iRow, 1)
.Offset(0, 1).Value = srcArr(iRow, iCol)
.Offset(0, 2).Value = srcArr(1, iCol)
End With
OutRow = OutRow + 1 'move to the next free row
'Debug.Print srcArr(iRow, 1), srcArr(iRow, iCol), srcArr(1, iCol)
End If
Next iCol
Next iRow
End Sub
Альтернатива, если вы хотите использовать еще более быстрый способ использования массива для вывода тоже
Option Explicit
Public Sub UnPivotDataFastOutput()
Dim wsSrc As Worksheet 'define source sheet
Set wsSrc = ThisWorkbook.Worksheets("Source")
Dim LastRow As Long
LastRow = wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row
Dim LastCol As Long
LastCol = wsSrc.Cells(1, wsSrc.Columns.Count).End(xlToLeft).Column
Dim srcArr As Variant 'read data range into an array
srcArr = wsSrc.Range("A1", wsSrc.Cells(LastRow, LastCol)).Value
Dim OutRow As Long
OutRow = 1
Dim destRowCount As Long 'calculate array size
destRowCount = Application.WorksheetFunction.CountIf(wsSrc.Range("C2", wsSrc.Cells(LastRow, LastCol)), "<>0")
Dim destArr As Variant
ReDim destArr(1 To destRowCount, 1 To 3)
Dim iRow As Long, iCol As Long
For iRow = 2 To UBound(srcArr)
For iCol = 3 To UBound(srcArr, 2)
If srcArr(iRow, iCol) <> 0 Then
'output into array
destArr(OutRow, 1) = srcArr(iRow, 1)
destArr(OutRow, 2) = srcArr(iRow, iCol)
destArr(OutRow, 3) = srcArr(1, iCol)
OutRow = OutRow + 1
'Debug.Print srcArr(iRow, 1), srcArr(iRow, iCol), srcArr(1, iCol)
End If
Next iCol
Next iRow
'write array into sheet
ThisWorkbook.Worksheets("Destination").Range("A2").Resize(destRowCount, 3).Value = destArr
End Sub