vba将一组单元格作为范围传递给函数

vba将一组单元格作为范围传递给函数,vba,excel,Vba,Excel,我得到一组细胞,在下面的函数中对它们进行计算 如果我将一个范围(带有:符号)作为第一个参数传递,则它会工作,但如果我选择一些单元格作为其范围(A1、A3、B6、B9),则它会失败。它只获取逗号之前的第一个单元格作为第一个参数。但我想要整个细胞 我能做什么?(使用字符串传递范围除外) 还有一件事:是否可以将一组范围作为参数传递?如何操作?如前所述,函数只接受两个范围作为参数 要允许在函数中使用可变数量的范围,需要在参数列表中声明ParamArray variant数组。然后,您可以依次处理数组中的

我得到一组细胞,在下面的函数中对它们进行计算

如果我将一个范围(带有
符号)作为第一个参数传递,则它会工作,但如果我选择一些单元格作为其范围(
A1、A3、B6、B9
),则它会失败。它只获取逗号之前的第一个单元格作为第一个参数。但我想要整个细胞

我能做什么?(使用字符串传递范围除外)


还有一件事:是否可以将一组范围作为参数传递?如何操作?

如前所述,函数只接受两个范围作为参数

要允许在函数中使用可变数量的范围,需要在参数列表中声明ParamArray variant数组。然后,您可以依次处理数组中的每个范围

比如说,

Function myAdd(Arg1 As Range, ParamArray Args2() As Variant) As Double
    Dim elem As Variant
    Dim i As Long
    For Each elem In Arg1
        myAdd = myAdd + elem.Value
    Next elem
    For i = LBound(Args2) To UBound(Args2)
        For Each elem In Args2(i)
            myAdd = myAdd + elem.Value
        Next elem
    Next i
End Function
然后可以在工作表中使用此函数添加多个范围

对于您的函数,有一个问题,可以传递给函数的范围(或单元格)中哪些是“会话”,哪些是“客户”

最容易处理的情况是,如果您确定第一个范围是会话,任何后续范围都是客户

Function calculateIt(Sessions As Range, ParamArray Customers() As Variant) As Double
    'This function accepts a single Sessions range and one or more Customers
    'ranges
    Dim i As Long
    Dim sessElem As Variant
    Dim custElem As Variant
    For Each sessElem In Sessions
        'do something with sessElem.Value, the value of each
        'cell in the single range Sessions
        Debug.Print "sessElem: " & sessElem.Value
    Next sessElem
    'loop through each of the one or more ranges in Customers()
    For i = LBound(Customers) To UBound(Customers)
        'loop through the cells in the range Customers(i)
        For Each custElem In Customers(i)
            'do something with custElem.Value, the value of
            'each cell in the range Customers(i)
            Debug.Print "custElem: " & custElem.Value
         Next custElem
    Next i
End Function
如果要包含任意数量的会话范围和任意数量的客户范围,则必须包含一个参数,该参数将告诉函数,以便它可以将会话范围与客户范围分开

可以将此参数设置为函数的第一个数值参数,该函数将标识以下参数中有多少是会话范围,其余参数隐式为客户范围。该函数的签名将是:

Function calculateIt(numOfSessionRanges, ParamAray Args() As Variant)
或者它可以是一个将会话范围与客户范围分开的“guard”参数。然后,您的代码必须测试每个参数,以查看它是否是保护。该函数看起来像:

Function calculateIt(ParamArray Args() As Variant)
也许打个电话,比如:

calculateIt(sessRange1,sessRange2,...,"|",custRange1,custRange2,...)
然后,程序逻辑可能是:

Function calculateIt(ParamArray Args() As Variant) As Double
   ...
   'loop through Args
   IsSessionArg = True
   For i = lbound(Args) to UBound(Args)
       'only need to check for the type of the argument
       If TypeName(Args(i)) = "String" Then
          IsSessionArg = False
       ElseIf IsSessionArg Then
          'process Args(i) as Session range
       Else
          'process Args(i) as Customer range
       End if
   Next i
   calculateIt = <somevalue>
End Function
将函数calculateIt(paramary Args()作为变量)计算为Double
...
'通过Args循环
IsSessionArg=True
对于i=lbound(Args)到UBound(Args)
'只需检查参数的类型
如果TypeName(Args(i))=字符串,则
IsSessionArg=False
那么ElseIf是SessionArg吗
'进程参数(i)作为会话范围
其他的
'流程参数(i)作为客户范围
如果结束
接下来我
计算EIT=
端函数

还有另一种方法可以将多个范围传递给函数,我认为这对用户来说要干净得多。在电子表格中调用函数时,将每组范围括在括号中,例如:
calculateIt((A1,A3)、(B6,B9))

上述通话假设您的两个会话位于A1和A3,您的两个客户位于B6和B9

为了实现这一点,您的函数需要在输入范围内的每个
区域中循环。例如:

Function calculateIt(Sessions As Range, Customers As Range) As Single

    ' check we passed the same number of areas
    If (Sessions.Areas.Count <> Customers.Areas.Count) Then
        calculateIt = CVErr(xlErrNA)
        Exit Function
    End If

    Dim mySession, myCustomers As Range

    ' run through each area and calculate
    For a = 1 To Sessions.Areas.Count

        Set mySession = Sessions.Areas(a)
        Set myCustomers = Customers.Areas(a)

        ' calculate them...
    Next a

End Function
函数计算(会话作为范围,客户作为范围)为单个
“检查我们通过了相同数量的区域
如果(Sessions.Areas.Count Customers.Areas.Count),则
calculateIt=CVErr(xlErrNA)
退出功能
如果结束
Dim mySession,我的客户作为范围
'遍历每个区域并计算
对于a=1到Sessions.Areas.Count
设置mySession=Sessions.Areas(a)
设置myCustomers=Customers.Areas(a)
“计算一下。。。
下一个
端函数
好的方面是,如果两个输入都是连续范围,则可以像调用普通函数一样调用此函数,例如
calculateIt(A1:A3,B6:B9)


希望有帮助:)

由于我是vba的初学者,我愿意深入了解vba,了解所有excel内置函数在那里的工作方式

因此,在上述问题上,我已经付出了基本的努力

Function multi_add(a As Range, ParamArray b() As Variant) As Double

    Dim ele As Variant

    Dim i As Long

    For Each ele In a
        multi_add = a + ele.Value **- a**
    Next ele

    For i = LBound(b) To UBound(b)
        For Each ele In b(i)
            multi_add = multi_add + ele.Value
        Next ele
    Next i

End Function

-a:对于上述代码,这是减去的,因为计数本身会加倍,所以您添加的值将第一个值添加两次。

谢谢,但我不太清楚。你能给我举个用法的例子吗?如果我想将您的
myAdd
函数与我的
calculateIt
函数匹配,
Arg1
将是
会话
Arg2
将是
客户
?哇!精彩的!答案是使用守卫参数。再次感谢@哈夫,我没有得到任何结果。我甚至在代码中添加了一个
Stop
,但在即时窗口中看不到任何参数。函数还返回0。知道这里出了什么问题吗?嗨,我有一个类似于myAdd的函数,目前接受一个范围和多个值。现在我的要求变成了接受多个范围,每个范围都有一个赋值,比如SUMIFS公式。如何在VBA中实现这一点?作为ParamArray的替代方法,可以为不相交的单元格集指定一个定义的名称并传递名称。虽然
ParamArray
是一种很好的方法,但此选项为多单元格参数提供了一种非常干净的方法。它应该得到更多的选票。。。
Function multi_add(a As Range, ParamArray b() As Variant) As Double

    Dim ele As Variant

    Dim i As Long

    For Each ele In a
        multi_add = a + ele.Value **- a**
    Next ele

    For i = LBound(b) To UBound(b)
        For Each ele In b(i)
            multi_add = multi_add + ele.Value
        Next ele
    Next i

End Function