Option Explicit
Sub test()
Dim a, i As Long, mtch As Object, m As Object, temp, ii
With Range("a1").CurrentRegion
a = .Value
With CreateObject("VBScript.RegExp")
.Global = True
For i = 1 To UBound(a, 1)
If a(i, 1) Like "*;*" Then
.Pattern = "([^;]+)(?=(;|$))"
Set m = .Execute(a(i, 1))
ReDim temp(0 To 1, 0 To m.Count - 1)
.Pattern = "(\S+) (\S\.|[^\s\.]+)((?= )(\S+))?"
For ii = 0 To m.Count - 1
temp(0, ii) = Trim$(m(ii)): temp(1, ii) = Trim$(m(ii))
.Pattern = "^(\S\.)? *(\S+) (\S+)((, )?\S+)?$"
If .test(Trim$(m(ii))) Then
temp(1, ii) = .Replace(Trim$(m(ii)), "$3 $2")
Else
.Pattern = "^(\S+) (\S\.) (\S+)"
If .test(Trim$(m(ii))) Then
temp(1, ii) = .Replace(Trim$(m(ii)), "$3 $1")
End If
End If
Next
HSortM temp, 0, UBound(temp, 2), 1
a(i, 1) = Join(Application.Index(temp, 1, 0), "; ")
End If
Next
End With
.Value = a
End With
End Sub
Private Sub HSortM(ary, LB, UB, ref, Optional ord As Boolean = 1)
Dim m As Variant, i As Long, ii As Long, iii As Long, temp
i = UB: ii = LB
m = ary(ref, Int((LB + UB) / 2))
Do While ii <= i
If ord Then
Do While ary(ref, ii) < m: ii = ii + 1: Loop
Else
Do While ary(ref, ii) > m: ii = ii + 1: Loop
End If
If ord Then
Do While ary(ref, i) > m: i = i - 1: Loop
Else
Do While ary(ref, i) < m: i = i - 1: Loop
End If
If ii <= i Then
For iii = LBound(ary, 1) To UBound(ary, 1)
temp = ary(iii, ii): ary(iii, ii) = ary(iii, i): ary(iii, i) = temp
Next
ii = ii + 1: i = i - 1
End If
Loop
If LB < i Then HSortM ary, LB, i, ref, ord
If ii < UB Then HSortM ary, ii, UB, ref, ord
End Sub
Bookmarks