我是excel vba的新手,我似乎无法解决vbArrays的这个问题。我在vba中创建了函数cumsum只是为了让我的生活更轻松。但是,我想使代码变得灵活,以便我可以从函数和范围传递两种变体。在我的代码中,当我添加行vec = vec.value如果我在一个范围内传递时,它工作得很好但是如果我想要它工作,如果我调用该函数并传入非范围类型它不起作用。我注意到的是如果我的代码中没有行vec = vec.value并且我传入一个范围,它的维度为0,我通过编写自己的函数来检查。有人可以向我解释如何解决这个问题吗?感谢。
Public Function cumsum(vec As Variant) As Variant
Dim temp() As Variant
MsgBox (getDimension(vec))
'works if i use vec=vec.value if vec is a range but has 0 if i do not vec = vec.values
ReDim temp(LBound(vec, 1) To UBound(vec, 1), 1 To 1) As Variant
Dim intCounter As Integer
For intCounter = LBound(vec) To UBound(vec)
If intCounter = LBound(vec) Then
temp(intCounter, 1) = vec(intCounter, 1)
Else
temp(intCounter, 1) = temp(intCounter - 1, 1) + vec(intCounter, 1)
End If
Next
cumsum = temp()
End Function
Function getDimension(var As Variant) As Integer
On Error GoTo Err:
Dim i As Integer
Dim tmp As Integer
i = 0
Do While True:
i = i + 1
tmp = UBound(var, i)
Loop
Err:
getDimension = i - 1
End Function
答案 0 :(得分:2)
为什么不使用VarType和TypeName检查vec
的数据类型,然后在vec
上执行必要的操作
Public Function cumsum2(vec As Variant) As Variant
MsgBox TypeName(vec)
MsgBox VarType(vec)
cumsum2 = 0
End Function
答案 1 :(得分:1)
来自@Jake和@chris的回答是正确方向的提示,但我认为它们不够远。
如果您完全确定您只将此例程称为UDF(即来自工作表中的公式),那么您真正需要做的就是添加:
If IsObject(vec) Then
Debug.Assert TypeOf vec Is Range
vec = vec.Value2
End If
到你的功能开始。被称为UDF的唯一对象类型是Range
。此外,作为UDF调用,您可以依赖于它传递的任何数组将从1开始编制索引。
我可以解决你日常生活中的其他问题,但是这些问题与你原来的问题不同。简而言之:这只适用于列向量,对于单细胞范围会失败等等。
请注意getDimension
函数为Range
返回零的原因,因为UBound
在范围内窒息。您的错误处理程序很乐意捕获您实际上并不期望获得并返回零的错误(类型不匹配)。 (找到“维度”的方法是假设错误将是下标范围错误。)
我回答了一段时间后回答说明为什么在使用Excel时,我认为一般的getDimension
方法不是很好:
https://stackoverflow.com/a/6904433/58845
最后,VarType
的问题在于,当传递具有默认属性的对象时,它实际上将返回属性的类型。因此VarType(<range>)
将告诉您范围内的内容类型,而不是对象的代码,因为Range
具有默认属性Range.Value
。
答案 2 :(得分:0)
修改您的getDimension
以包含
If TypeName(var) = "Range" Then
var = var.Value
End If