Sub Transposer()
'highlight a range, including headers, then run macro
'prompt for how many columns on left to repeat
'optional: insert a primary key row (uniquely number rows, for later cross-referencing)
Dim i As Long, j As Long
Dim k As Long, z As Long
Dim outputDest As String
Dim aSrc() As Variant
Dim aWork() As Variant
Dim KeepCols As String
Dim srcRowCount As Long
Dim srcColCount As Long
Dim aRngSplit As Variant
Dim PrimaryKey As String
'Abort if a range isn't selected
If TypeName(Selection) <> "Range" Then Exit Sub
outputDest = InputBox("Enter destination address (ex Sheet1!A1)")
If outputDest = "" Then Exit Sub
KeepCols = InputBox("Enter number of columns to repeat on left side")
If KeepCols = "" Then Exit Sub
If Not IsNumeric(KeepCols) Then Exit Sub
PrimaryKey = "n"
PrimaryKey = InputBox("Enter 'y' to include a primary key column")
If LCase(PrimaryKey) <> "y" Then PrimaryKey = "n"
aSrc = Selection
srcRowCount = UBound(aSrc, 1)
srcColCount = UBound(aSrc, 2)
If PrimaryKey = "n" Then
ReDim aWork(1 To (srcRowCount * (srcColCount - KeepCols)), 1 To KeepCols + 2)
Else
ReDim aWork(1 To (srcRowCount * (srcColCount - KeepCols)), 1 To KeepCols + 2 + 1)
End If
z = 1
For i = 2 To srcRowCount 'start at 2 because first row headers
For k = 1 To srcColCount - KeepCols
If PrimaryKey = "n" Then
For j = 1 To KeepCols
aWork(z, j) = aSrc(i, j)
Next j
aWork(z, KeepCols + 1) = aSrc(1, k + KeepCols) 'month name
aWork(z, KeepCols + 2) = aSrc(i, k + KeepCols) 'qty
Else
aWork(z, 1) = i - 1 'primary key
For j = 1 To KeepCols
aWork(z, j + 1) = aSrc(i, j) 'add 1 to J to offset from primary key
Next j
aWork(z, KeepCols + 1 + 1) = aSrc(1, k + KeepCols) 'month name
aWork(z, KeepCols + 2 + 1) = aSrc(i, k + KeepCols) 'qty
End If
z = z + 1
Next k
Next i
aRngSplit = Split(outputDest, "!")
If PrimaryKey = "n" Then
Range(Selection.Cells(1, 1), Selection.Cells(1, CLng(KeepCols))).Copy Sheets(aRngSplit(0)).Range(aRngSplit(1))
Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(0, KeepCols) = "Month"
Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(0, KeepCols + 1) = "Value"
Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(1, 0).Resize(z - 1, KeepCols + 2) = aWork
Else
Range(Selection.Cells(1, 1), Selection.Cells(1, CLng(KeepCols))).Copy Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(0, 1)
Sheets(aRngSplit(0)).Range(aRngSplit(1)) = "Primary Key"
Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(0, KeepCols + 1) = "Month"
Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(0, KeepCols + 2) = "Value"
Sheets(aRngSplit(0)).Range(aRngSplit(1)).Offset(1, 0).Resize(z - 1, KeepCols + 2 + 1) = aWork
End If
Beep
End Sub