These two method will transpose the data much faster than Range.Copy
and Range.Paste
.
PivotTableValues - dumps the Range.Value
into an array, data, then fills a second array, results, with the transposed values. Note: Transposed in this context simply means moved to a different place.
PivotTableValues2 - uses Arraylists to accomplish the OP's goals. Although it works great, it is somewhat a farcical answer. I just wanted to try this approach for esoteric reasons.
PivotTableValues Using Arrays
Sub PivotTableValues()
Const FIXED_COLUMN_COUNT As Long = 2
Dim ArrayRowCount As Long, Count As Long, ColumnCount As Long, RowCount As Long, x As Long, y As Long, y2 As Long
Dim data As Variant, results As Variant, v As Variant
With ThisWorkbook.Worksheets("Sheet1")
RowCount = .Range("A" & .Rows.Count).End(xlUp).Row
ColumnCount = .Cells(1, .Columns.Count).End(xlToLeft).Column
data = Range(.Range("A" & .Rows.Count).End(xlUp), .Cells(1, .Columns.Count).End(xlToLeft)).Value
ArrayRowCount = (ColumnCount - FIXED_COLUMN_COUNT) * (RowCount - 1) + 1
ReDim results(1 To ArrayRowCount, 1 To FIXED_COLUMN_COUNT + 2)
Count = 1
For y = FIXED_COLUMN_COUNT + 1 To ColumnCount
For x = 2 To RowCount
Count = Count + 1
results(Count, FIXED_COLUMN_COUNT + 1) = data(1, y)
results(Count, FIXED_COLUMN_COUNT + 2) = data(x, y)
For y2 = 1 To FIXED_COLUMN_COUNT
If Count = 2 Then
results(1, y2) = data(1, y2)
results(1, y2 + 1) = "Category"
results(1, y2 + 2) = "Value"
End If
results(Count, y2) = data(x, y2)
Next
Next
Next
End With
With ThisWorkbook.Worksheets.Add
.Range("A1").Resize(UBound(results), UBound(results, 2)).Value = results
.Columns.AutoFit
End With
End Sub
PivotTableValues2 Using ArrayLists
Sub PivotTableValues2()
Const FIXED_COLUMN_COUNT As Long = 2
Dim ColumnCount As Long, RowCount As Long, x As Long, y As Long
Dim valueList As Object, baseList As Object, results As Variant, v As Variant
Set valueList = CreateObject("System.Collections.ArrayList")
Set baseList = CreateObject("System.Collections.ArrayList")
With ThisWorkbook.Worksheets("Sheet1")
RowCount = .Range("A" & .Rows.Count).End(xlUp).Row
ColumnCount = .Cells(1, .Columns.Count).End(xlToLeft).Column
For x = 1 To RowCount
baseList.Add Application.Transpose(Application.Transpose(Range(.Cells(x, 1), .Cells(x, FIXED_COLUMN_COUNT))))
Next
For y = FIXED_COLUMN_COUNT + 2 To ColumnCount
baseList.AddRange baseList.getRange(1, RowCount - 1)
Next
For y = FIXED_COLUMN_COUNT + 1 To ColumnCount
For x = 2 To RowCount
valueList.Add Array(.Cells(1, y).Value, .Cells(x, y).Value)
Next
Next
End With
results = Application.Transpose(Application.Transpose(baseList.ToArray))
With ThisWorkbook.Worksheets.Add
.Range("A1").Resize(UBound(results), UBound(results, 2)).Value = results
valueList.Insert 0, Array("Category", "Value")
results = Application.Transpose(Application.Transpose(valueList.ToArray))
.Cells(1, FIXED_COLUMN_COUNT + 1).Resize(UBound(results), UBound(results, 2)).Value = results
.Columns.AutoFit
End With
End Sub
autofill
. – Victor K