VBA自定义函数添加As Variant()报错,移除则正常的原因咨询
VBA自定义函数返回类型问题解析
我正在学习面向初学者的VBA在线课程,课程仅有视频内容,没有额外技术支持。其中一个自定义函数练习要求编写类似VLOOKUP的TLOOKUP函数,通过行引用和列引用获取表格交叉位置的值。我编写的代码和参考答案唯一的区别是函数声明时加了As Variant(),但添加后函数运行失败,移除该声明则正常工作。
可正常运行的TLOOKUP代码
Function TLOOKUP(full_table As Range, row_value As Range, vert_range As Range, col_value As Range, horiz_range As Range) Dim row_index As Long Dim col_index As Long row_index = Application.WorksheetFunction.Match(row_value, vert_range, 0) col_index = WorksheetFunction.Match(col_value, horiz_range, 0) TLOOKUP = WorksheetFunction.Index(full_table, row_index, col_index) End Function
导致运行失败的函数声明
Function TLOOKUP(full_table As Range, row_value As Range, vert_range As Range, col_value As Range, horiz_range As Range) As Variant()
该函数存储在personal.xlsb文件中,在Excel工作表中的调用公式为:=PERSONAL.XLSB!TLookup(B4:N29,S3,A4:A29,R8,B3:N3)
我原本疑惑,既然函数默认返回类型就是Variant,为什么加As Variant()会报错。之前课程里的ULOOKUP示例用Function ULOOKUP(...) As Variant()可以正常运行,那个示例是通过INDEX和单个MATCH实现的,我以为TLOOKUP也能同理操作。反复尝试后对比参考答案,发现就这一处差异,但找不到原因。
可正常运行的ULookup代码(对比参考)
Function ULookup(lookup_value As Range, lookup_range As Range, source_range As Range, Optional match_type As Integer = 0) As Variant() Dim results_Array() As Variant Dim lookup_index As Long ReDim results_Array(1) As Variant lookup_index = Application.WorksheetFunction.Match(lookup_value, lookup_range, match_type) results_Array(1) = WorksheetFunction.Index(source_range, lookup_index) ULookup = results_Array End Function
问题根源:返回值类型不匹配
As Variant()的含义是函数必须返回Variant类型的数组,而非单个Variant值:
- 你的
TLOOKUP最后赋值的是WorksheetFunction.Index(full_table, row_index, col_index),这个表达式返回的是单个单元格的具体值(比如数字、文本等),不是数组,和函数声明的返回类型不匹配,因此运行失败。 - 而
ULookup是把结果存入了一个Variant数组results_Array,最后将整个数组赋值给函数,和As Variant()的声明完全匹配,所以能正常运行。
哪些场景不应使用As Variant()?
- 当函数返回单个值(比如单个数字、文本、单个单元格的值)时,绝对不能用
As Variant(),因为这会强制要求返回数组,单个值无法满足类型要求,直接导致运行错误。 - 只有当函数确实需要返回数组(比如批量返回多个单元格的值、自定义构造的数组结果)时,才适合用
As Variant()声明返回类型。
是否可以忽略这个问题?
完全可以忽略。VBA中如果不指定函数返回类型,默认就是As Variant(单个Variant值,不带数组属性),这和你的TLOOKUP实际返回单个值的需求完全匹配。只要函数返回的是单个值,不管是不声明返回类型,还是明确写As Variant(注意不带括号),都能正常运行。
内容的提问来源于stack exchange,提问作者MattRiley78
相关产品推荐
相关产品推荐

