2013-08-11 5 views
12

Я получаю группу ячеек и делаю некоторые вычисления над ними в функции ниже.vba передать группу ячеек как диапазон для функции

Он работает, если я передаю диапазон (с значком :) в качестве первого параметра, но он терпит неудачу, если я выберу некоторые ячейки в качестве диапазона (A1, A3, B6, B9). Он просто получает первую ячейку перед запятой в качестве первого параметра. Но я хочу целые клетки.

Что я могу сделать? (За исключением использования строк для проходящих диапазонов)

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

И еще одно: Можно ли передать группу диапазонов в качестве параметра? как?

+0

В качестве альтернативы ParamArray, может назначить определенное имя для вашего набора непересекающихся клеток и передать имя. –

ответ

19

Как написано, ваша функция принимает только два диапазона в качестве аргументов.

Чтобы включить переменное количество диапазонов, используемых в функции, вам необходимо объявить массив вариантов 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

Для вашей функции, есть вопрос о том, какой из диапазонов (или клетки), которые могут передаваемые функции являются «Сессия» и которые «Клиенты».

Самый простой случай, если вы решили, что первый диапазон - это сеансы, а любые последующие диапазоны - это клиенты.

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) 

Или это может быть «охранник» аргумент, который отделяет Сессия колеблется от диапазонов клиентов. Затем ваш код должен будет проверить каждый аргумент, чтобы убедиться, что это был защитник. Функция будет выглядеть следующим образом:

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 
+0

Спасибо, но это немного неясно для меня. Не могли бы вы привести пример использования? Если я хочу, чтобы ваша функция 'myAdd' соответствовала моей функции' calculateIt', 'Arg1' будет' Sessions', а 'Arg2' будет' Customers'? – mrdaliri

+0

Ничего себе! Замечательно! использование аргумента guard является ответом. Еще раз спасибо! – mrdaliri

+0

@chuff, я не получаю никакого результата. Я даже поставил код «Стоп», но ни один из аргументов не отображается в * Немедленном окне *. Функция также возвращает 0. Любая идея, что здесь не так? –

5

Существует еще один способ передайте несколько диапазонов функции, которая, как мне кажется, намного удобнее для пользователя.Когда вы вызываете свою функцию в электронной таблице, вы обертываете каждый набор диапазонов в скобках, например: 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).

Надежда, что помогает :)

+0

В то время как 'ParamArray' - хороший способ, этот параметр обеспечивает очень чистый способ для многоэлементных аргументов. Он должен был получить еще много голосов ... –

Смежные вопросы