我正在尝试创建一个可以接受范围或数组的函数来执行一些进一步的计算。当数组通过时,该函数运行良好,但是当在工作表中的范围内使用该函数时,它的值为VALUE!错误。
我的代码如下:
Function COMRET(data as variant, N as integer)
Dim nrows as long
If IsArray(data) Then
N = UBound(data,1)
Else
N = data.rows.count
End If
'... some other calculations here
End Function
问题似乎来自上面数组的标识...当我注释掉上面的IF部分时,代码的其他部分似乎还可以。不知道我在做什么错。感谢帮助。谢谢!
答案 0 :(得分:1)
您将data
作为变量传递,这将导致IsArray(data)
始终为true,无论调用函数时是否将范围或数组传递给它。
添加第三个强制性参数也可以,它指示data
变量的数据类型:
Function COMRET(data As Variant, Is_Array As Boolean, N As Integer)
Dim nrows As Long
If Is_Array = True Then
N = UBound(data, 1)
Else
N = data.Rows.Count
End If
'... some other calculations here
End Function
或者,您可以添加一项检查,该检查通过尝试在范围上使用UBound
来使用引发的错误。这消除了第三个参数的需要:
Function COMRET(data As Variant, N As Integer)
Dim nrows As Long
On Error Resume Next
N = UBound(data, 1)
If Err.Number <> 0 Then N = data.Rows.Count
Err.Clear
On Error GoTo 0
'... some other calculations here
End Function
答案 1 :(得分:1)
您正确声明data as Variant
。
当您将范围传递给该范围时,它将正确地作为Variant / Object / Range传递,但是事情会变得有些复杂。
当您调用仅作为函数的IsArray
时,它将尝试使用传递的Range
对象Value
的{{3}}。如果范围由多个单元格组成,则IsArray(Range.Value)
为True。但是,当您调用UBound
时,这是一个非常特殊的功能,因为它被突出显示为关键字,它不会尝试获取data.Value
并将直接在data
上进行操作,而{{ 1}}是单个data
对象,因此它不能有上限(而Range
可以)。
您需要正确检测正在传递的内容:
.Value
答案 2 :(得分:0)
VarType()应该是您的朋友:
' Const vbArray = 8192 (&H2000)
' Const vbString = 8
Debug.Print VarType(data) ' = vbArray (8192) Or vbString (8) = 8200
' Is data an array of sorts?
Debug.Print CBool((VarType(data) And vbArray) = vbArray)
从MSDN帮助中:
VarType函数从不单独返回vbArray的值。它 总是添加到其他值来表示一个数组 特定类型。常量vbVariant仅在 与vbArray结合使用以指示VarType的参数 函数是Variant类型的数组。例如,返回的值 对于整数数组的计算方式为vbInteger + vbArray,或者 8194.如果对象具有默认属性,则VarType(对象)将返回该对象的默认属性的类型。