Here is another VBA Macro that uses arrays and a user defined object to represent each column. The User defined object consists of a Column Header item and then a collection of items below that. It should be quite fast. It makes assumptions about the data locations that should be easily modifiable at the top of the macro.
Class Module
(rename this to cColHeaders)
Option Explicit
Private pColHeader As String
Private pColItem As String
Private pColItems As Collection
Private Sub Class_Initialize()
Set pColItems = New Collection
End Sub
Public Property Get ColHeader() As String
ColHeader = pColHeader
End Property
Public Property Let ColHeader(Value As String)
pColHeader = Value
End Property
Public Property Get ColItem() As String
ColItem = pColItem
End Property
Public Property Let ColItem(Value As String)
pColItem = Value
End Property
Public Property Get ColItems() As Collection
Set ColItems = pColItems
End Property
Function ADDColItem(Value As String)
ColItems.Add Value
End Function
Regular Module
Option Explicit
Sub OrganizeByColumn()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes() As Variant
Dim cCH As cColumnHeaders, colCH As Collection
Dim I As Long, J As Long
Dim lMaxItems As Long 'will be the maximum number of items in a column
Dim V As Variant
'set source and results worksheets, ranges
Set wsSrc = Worksheets("sheet2")
Set wsRes = Worksheets("sheet3")
Set rRes = wsRes.Cells(1, 1) 'start results in wsRes A1
'Get source data == assumes in Col A starting at A1
With wsSrc
vSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With
'Collect and organize the data
Set colCH = New Collection
For I = 1 To UBound(vSrc, 1)
Set cCH = New cColumnHeaders
With cCH
.ColHeader = vSrc(I, 1)
V = Split(.ColHeader)
If UBound(V) = 0 Then
colCH.Add cCH, .ColHeader
Else
.ColItem = vSrc(I, 1)
.ADDColItem .ColItem
colCH(V(0)).ADDColItem (.ColItem)
J = colCH(V(0)).ColItems.Count
lMaxItems = IIf(lMaxItems > J, lMaxItems, J)
End If
End With
Next I
'Create and populate results array
ReDim vRes(0 To lMaxItems, 1 To colCH.Count)
For I = 1 To colCH.Count
With colCH(I)
vRes(0, I) = .ColHeader
For J = 1 To .ColItems.Count
vRes(J, I) = .ColItems(J)
Next J
End With
Next I
'resize results range
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
'write and format the results
With rRes
.EntireColumn.Clear
.Value = vRes
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.EntireColumn.AutoFit
End With
End Sub