答案1
在 VBA 中执行此操作的伪代码:(您可以计算出真实代码)。请注意,这只写在答案中,因此您必须填写空白,但希望您能大致了解循环遍历每个地址并收集具有与该地址匹配的列的任何名称。
dim address_on as string 'current address
dim names as string 'concatenate list of names
dim in_list_already as boolean
For address_row = 1 to range().end(xldown).row
'loop through addresses
address_on = Range("Column" & address_row).value
names = ""
'First check if address_on is already in destination list?
in_list_already = false
for check_row = 1 to range("Destination").end(xldown).row
If range("Destination Col" & check_row).value = address_on then
in_list_already = true
Exit for
End if
next
if in_list_already = false then
'Find all names that have this address
for name_row = 1 to range().end(xldown).row
If range("Address Column" & name_row).value = address_on then
names = names & Range("Name Column" & name_row).value & ","
End if
next
'remove last comma
names = names.remove(Len(names)-1,1)
'add to list
Range("Column to insert to 1" & next_slot).value = names
Range("Column to insert to 2" & next_slot).value = address_on
End if
next
正如您所见,names = names & Range("Name Column" & name_row).value & ","
如果匹配,则只需将其连接到列表。
上面的方法是:
- 循环浏览您的数据
- 输出中是否已存在项目?如果不存在则不显示它(因此不会出现重复)。
- 收集所有与您所在地址相关的姓名
- 输出结果
答案2
如果记录像问题中那样被聚合,那么使用公式就可以直接完成(如果匹配的地址不在一起,则会更加复杂):
取消隐藏列以显示方法:
我创建了两个辅助列,一个用于姓名,一个用于过滤。为了匹配问题中所需的顺序,我在左侧插入了姓名辅助列。A2 中的公式:
=IF(C2=C1,A1& ", " &B2,B2)
我的 C 列是地址列。这会检查当前行中的地址是否与上一行中的地址匹配。如果不匹配,则表示这是一个新地址,并插入相关名称。如果它与上一个地址相同,它会将逗号和行名称连接到上一行的结果(因此您可以有任意数量的匹配地址)。
辅助列 D 检查该行的地址是否是该地址的最后一个地址(即下一行的地址不同)。D2 中的公式:
=C2<>C3
在列中填充公式后,单击菜单中的 D1 和自动筛选。在 D1 下拉菜单中,取消选择 FALSE。这将隐藏除每个地址最后一行之外的所有行。
如果您想要永久的“干净”列表,请复制所需的过滤列并粘贴到新位置。只有可见的列会被复制,如下面我的 F 列和 G 列所示:
您可以在过滤器打开时粘贴,但如果粘贴到隐藏行的范围内,则部分结果将被隐藏,直到您关闭过滤器为止。
答案3
我想建议一个 UDF(用户定义函数)来解决这个问题。
怎么运行的:
- 我假设源数据在范围内
A2:B8
。 在 中输入此数组 (CSE) 公式
E2
,最后输入Ctrl+Shift+Enter& 向下填充。{=INDEX($B$2:$B$8, MATCH(SMALL(IF(COUNTIF($E$1:E1, $B$2:$B$8)=0, COUNTIF($B$2:$B$8, "<"&$B$2:$B$8), " "), 1), COUNTIF($B$2:$B$8, "<"&$B$2:$B$8), 0))}
复制和粘贴下面显示的代码为 模块。
Function ExtractinOneCell(LookupValue As String, LookupRange As Range, ColumnNumber As Integer, Char As String) Dim I As Long Dim xRet As String For I = 1 To LookupRange.Columns(2).Cells.Count If LookupRange.Cells(I, 2) = LookupValue Then If xRet = "" Then xRet = LookupRange.Cells(I, ColumnNumber) & Char Else xRet = xRet & "" & LookupRange.Cells(I, ColumnNumber) & Char End If End If Next ExtractinOneCell = Left(xRet, Len(xRet) - 2) End Function
输入此公式
D2
并填写。=ExtractinOneCell(E2,$A$2:$B$8,1,", ")