VBA 매크로를 사용하여이 작업을 수행 할 수 있습니다.
데이터가 A1
, 당신이 보여줄 때, 행 1에있는 이름 및 밑에 란에있는 많은 마지막성에; 그리고 워크 시트에는 그 밖의 것이 없다는 것을
- 데이터의 마지막 행 / 열 찾기
- VBA 배열로 데이터를 읽습니다 (워크 시트에서 선을 읽는 것보다 훨씬 빠른 처리).
- 사전 작성 위치
- 그만큼
key
각 항목은 첫 번째 이름입니다.
- 그만큼
item
성의 모음입니다.
- 두 개의 열과성에 한 행씩있는 결과 배열을 만듭니다.
- 결과를 워크 시트에 씁니다.
Option Explicit
Sub GroupFirstName()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes As Variant
Dim dFN As Object, cLN As Collection
Dim I As Long, J As Long
Dim LRC() As Long
Dim V, W
'Set source and results worksheets
' Edit sheetnames as required
Set wsSrc = Worksheets("Sheet2")
Set wsRes = Worksheets("Sheet3")
Set rRes = wsRes.Cells(1, 1) 'Upper left cell of results
'Read source data into variant array
With wsSrc
LRC = LastRowCol(.Name)
vSrc = .Range(.Cells(1, 1), .Cells(LRC(0), LRC(1)))
End With
'create dictionary with key = first name, and item is a collection of the last names
Set dFN = CreateObject("Scripting.Dictionary")
dFN.CompareMode = TextCompare
For J = 1 To UBound(vSrc, 2)
If Not dFN.Exists(vSrc(1, J)) Then
Set cLN = New Collection
For I = 2 To UBound(vSrc, 1)
If vSrc(I, J) <> "" Then cLN.Add vSrc(I, J)
Next I
dFN.Add Key:=vSrc(1, J), Item:=cLN
Else
For I = 2 To UBound(vSrc, 1)
If vSrc(I, J) <> "" Then dFN(vSrc(1, J)).Add vSrc(I, J)
Next I
End If
Next J
'Create results array
' Num rows = number of last names
J = 0
For Each V In dFN.Keys
J = J + dFN(V).Count
Next V
ReDim vRes(0 To J, 1 To 2)
vRes(0, 1) = "First Name"
vRes(0, 2) = "Last Name"
I = 0
For Each V In dFN.Keys
For Each W In dFN(V)
I = I + 1
vRes(I, 1) = V
vRes(I, 2) = W
Next W
Next V
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, 2)
With rRes
.EntireColumn.Clear
.Value = vRes
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.EntireColumn.AutoFit
End With
End Sub
Private Function LastRowCol(Worksht As String) As Long()
Application.Volatile
Dim WS As Worksheet, R As Range
Dim LastRow As Long, LastCol As Long
Dim L(1) As Long
Set WS = Worksheets(Worksht)
With WS
Set R = .Cells.Find(what:="*", after:=.Cells(1, 1), _
LookIn:=xlValues, searchorder:=xlByRows, _
searchdirection:=xlPrevious)
If Not R Is Nothing Then
LastRow = R.Row
LastCol = .Cells.Find(what:="*", after:=.Cells(1, 1), _
LookIn:=xlValues, searchorder:=xlByColumns, _
searchdirection:=xlPrevious).Column
Else
LastRow = 1
LastCol = 1
End If
End With
L(0) = LastRow
L(1) = LastCol
LastRowCol = L
End Function
소스 데이터
결과