我想对具有同一主键的多行名称进行 Vlookup:
Deal ID (Primary Key) | Name
437 | Tom Jones
437 | Frank Thomas
437 | Mary Smith
Vlookup 只会返回记录中的第一个名字 (Tom Jones)。我希望它看起来像这样:Tom Jones、Frank Thomas、Mary Smith 都在同一行。
答案1
看起来您正在尝试将 Excel 用作关系数据库,但它在这方面并不是那么擅长。最糟糕的是,除非近年来有所改变(我没有使用过 Excel 2010 之后的任何版本),否则没有工作表函数可以将范围或数组转换为分隔字符串。您必须想出一个可以做到这一点的 VBA 工作表函数。
您可以结合使用数组公式和 VBA 来实现您想要的效果。在继续之前,如果您发现自己经常做这样的事情,我强烈建议您使用真正的数据库程序。过去,我曾滥用 Excel 来执行简单的关系数据库式任务,但仅限于简单的任务。如果我不得不做更复杂的事情,那将非常痛苦。
假设您要搜索的 ID 在单元格中F1
,并且您的桌子名为Table1
,则您输入以下内容作为数组公式(使用 control-shift-enter,而不是 enter)。SimpleCat
是您的 VBA 连接工作表函数。
=SimpleCat(IF(Table1[Deal ID (Primary Key)]=$F$1, Table1[Name], ""))
SimpleCat
适用于此特定实例的方法是:
Function SimpleCat(Args() As Variant) As Variant
Dim a As Variant
SimpleCat = ""
For Each a In Args
If a <> "" Then SimpleCat = SimpleCat & a & ", "
Next
If Len(SimpleCat) > 0 Then SimpleCat = Left$(SimpleCat, Len(SimpleCat) - 2)
End Function
我把它留作一项练习,让你扩展SimpleCat
它,使它更加通用,因为拥有一个功能更齐全的通用连接函数对任何人的工具箱来说都是有用的。
解释:
当作为数组公式进行评估时,将整个表列与单个值进行比较将生成一个TRUE
s 和FALSE
s 的数组。使用IF
将构造一个新数组,从您在 的值(如果为 true 一侧)上使用的数组的正确位置提取值IF
,并填充您在 的值(如果为 false 一侧)上使用的空字符串IF
。该SimpleCat
函数将所有非空值放在这个新数组中,并在它们之间用逗号隔开。
答案2
有两个问题。首先,这不是主键;其次,Excel 中没有内置功能可以为您提供所需的结果。
主键应是与单个记录绑定的唯一标识符,并且永远不会重复。Excel 中的大多数查找函数都是为此而设计的,这就是为什么它们在找到匹配项时会停止的原因 - 如果已经找到匹配项,则不必每次都查看整个范围,从而节省资源。
我认为,要进行您在此处寻找的那种合并(将多个值拉入单个字符串),唯一的方法是使用宏或自定义函数。您究竟需要什么代码取决于您想要的确切结果,恐怕超出了这个答案的范围。
答案3
我会采用这个功能...
Function ConcatRange(inputRange As Range, Optional delimiter As String) As String
Dim oneCell As Range
Dim usedRange As Range
Set usedRange = Application.Intersect(inputRange.Parent.usedRange, inputRange.Cells)
If Not (usedRange Is Nothing) Then
For Each oneCell In usedRange
If oneCell.Text <> vbNullString Then
ConcatRange = ConcatRange & delimiter & Trim(oneCell.Text)
End If
Next oneCell
ConcatRange = Mid(ConcatRange, Len(delimiter) + 1)
End If
End Function
并对其进行修改以创建一个新的函数,如下所示:
Function ConcatIf(KeyRange as Range, KeyValue as Variant, DataColumnOffset As Integer)
它将循环遍历 KeyRange 中的每个单元格,并且仅当其值等于 KeyValue 时,才连接来自oneCell.Offset(0, DataColumnOffset)