需求:编写支持跨表选列的VBA UDF,统计两列唯一值
解决两列组合唯一值的VBA自定义函数方案
嘿,我来帮你搞定这个自定义函数的问题!你原来用IF(SUMPRODUCT(($A$1:$A1=A1)*($B$1:$B1=B1))>1;0;1)的思路完全没问题,现在把它转成能灵活指定列的VBA UDF,其实很容易实现,我给你两种方案,按需选用:
方案1:和原公式功能一致的逐行判断UDF
这个函数会像你原来的公式一样,在每行返回1(首次出现的组合)或0(重复组合),方便你后续求和统计。
VBA代码
打开VBA编辑器(按Alt+F11),插入一个新模块,粘贴下面的代码:
Function UniqueCombo(rng1 As Range, rng2 As Range, currentRow As Long) As Integer ' 先检查两个输入范围的行数是否匹配,避免出错 If rng1.Rows.Count <> rng2.Rows.Count Then UniqueCombo = CVErr(xlErrValue) Exit Function End If ' 获取当前行对应的两个列的值 Dim val1 As Variant, val2 As Variant val1 = rng1.Cells(currentRow, 1).Value val2 = rng2.Cells(currentRow, 1).Value ' 计算当前行之前的重复次数,逻辑和你原来的SUMPRODUCT一致 Dim repeatCount As Long repeatCount = Application.SumProduct((rng1.Resize(currentRow - 1, 1) = val1) * (rng2.Resize(currentRow - 1, 1) = val2)) ' 首次出现返回1,重复返回0 If repeatCount > 0 Then UniqueCombo = 0 Else UniqueCombo = 1 End If End Function
使用方法
在工作表的单元格(比如C2)里输入:=UniqueCombo($A:$A, $B:$B, ROW())
然后下拉填充即可。这里的$A:$A和$B:$B就是你要指定的两列,加$就是绝对引用,和普通公式一样,复制到其他单元格时不会自动改变列引用;如果不需要固定列,去掉$就行。ROW()会自动获取当前行号,不用手动输入数字。
方案2:直接返回唯一组合数量的UDF
如果你不想逐行判断再求和,这个函数可以直接返回两列组合后的唯一值总数,更高效:
VBA代码
同样在模块里粘贴这段代码:
Function CountUniqueCombos(rng1 As Range, rng2 As Range) As Long ' 检查两个范围行数是否匹配 If rng1.Rows.Count <> rng2.Rows.Count Then CountUniqueCombos = CVErr(xlErrValue) Exit Function End If ' 用字典存储唯一组合,字典的键不会重复 Dim comboDict As Object Set comboDict = CreateObject("Scripting.Dictionary") Dim i As Long For i = 1 To rng1.Rows.Count ' 把两列的值拼接成一个唯一键(用|分隔避免不同值拼接后冲突) Dim comboKey As String comboKey = CStr(rng1.Cells(i, 1).Value) & "|" & CStr(rng2.Cells(i, 1).Value) ' 如果键不存在,就添加到字典 If Not comboDict.Exists(comboKey) Then comboDict.Add comboKey, 1 End If Next i ' 字典的键的数量就是唯一组合的数量 CountUniqueCombos = comboDict.Count End Function
使用方法
在任意单元格输入:=CountUniqueCombos($A$2:$A$100, $B$2:$B$100)
这里指定你要统计的范围(比如A2到A100和B2到B100),函数会直接返回唯一组合的总数。
关于绝对引用的说明
你不用在VBA代码里手动加$符号!在工作表输入公式时,像普通Excel公式一样添加$来固定列或行就行——比如$A:$A是绝对引用整列,$A$2:$A$100是绝对引用固定范围,Excel会自动处理这些引用,传递给UDF的是正确的Range对象。
注意事项
- 保存文件时要选择
.xlsm格式(启用宏的工作簿),否则UDF会失效。 - 如果要处理空值,可以在代码里加判断(比如如果val1或val2为空,返回0或者跳过),根据你的需求调整。
- 第一次使用宏时,可能需要在Excel设置里启用宏(文件>选项>信任中心>信任中心设置>宏设置)。
内容的提问来源于stack exchange,提问作者Mjeppo
相关产品推荐
相关产品推荐

