vba将一组单元格作为范围起作用

时间:2013-08-11 02:25:55

标签: excel vba excel-vba

我正在获取一组单元格并在下面的函数中对它们进行一些计算。

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

我该怎么办? (除了使用字符串传递范围)

Function calculateIt(Sessions As Range, Customers As Range) As Single
    ' calculate them...
End Function

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

3 个答案:

答案 0 :(得分:22)

如上所述,您的函数只接受两个范围作为参数。

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

例如,

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

然后可以在工作表中使用此函数添加多个范围。

myAdd usage

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

最简单的处理方法是,如果您确定第一个范围是Sessions,后续范围是客户。

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

如果要包含任意数量的Sessions范围和任意数量的Customers范围,则必须包含一个参数,该参数将告知该函数,以便它可以将Sessions范围与Customers范围分开。

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

Function calculateIt(numOfSessionRanges, ParamAray Args() As Variant)

或者它可以是一个“保护”参数,将Sessions范围与Customers范围分开。然后,您的代码必须测试每个参数以查看它是否是警卫。该函数看起来像:

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

答案 1 :(得分:6)

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

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

要使其工作,您的函数需要遍历输入范围中的每个Areas。例如:

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

好消息是,如果您将两个输入作为连续范围,则可以像正常情况一样调用此函数,例如calculateIt(A1:A3, B6:B9)

希望有所帮助:)

答案 2 :(得分:0)

当我是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 :由于上述代码被减去,导致计数本身加倍,因此您添加的值将使第一个值加两次。