2013-08-11 13 views
12

私はセルのグループを取得しており、以下の関数でそれらの計算を行っています。vbaは関数の範囲としてセルのグループを渡します。

最初のパラメータとして範囲(:記号付き)を渡しても動作しますが、セルの範囲(A1, A3, B6, B9)を選択すると失敗します。カンマの前の最初のセルを最初のパラメータとして取得します。しかし、私は全細胞が欲しい。

どうすればよいですか? (合格範囲については、文字列を使用して除く)

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

一つのことより:それはパラメータとして範囲のグループを渡すことは可能ですか?どうやって?

+0

を助けばらばらの細胞のあなたのセットに定義名を割り当て、名前を渡すことができますことを願っています。 –

答えて

19

書かれているように、関数は引数として2つの範囲しか受け入れません。

可変数の範囲を関数で使用できるようにするには、引数リストに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) 

となります。また、「セッション」の範囲をCustomersの範囲から区切る「ガード」引数にすることもできます。次に、あなたのコードは、それがガードかどうかを調べるために各引数をテストする必要があります。プログラム・ロジックは、その後の線に沿ってあるかもしれない

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

うわー!素晴らしい!ガード引数を使用することがその答えです。再度、感謝します! – mrdaliri

+0

@chuff、私は結果を得ていません。私はコードに 'Stop'を置くことさえできますが、* Immediate Window *では引数のどれも見ることができません。ファンクションも0を返します。何が間違っていますか? –

5

に別の方法があるようなものの呼び出しでおそらく

Function calculateIt(ParamArray Args() As Variant) 

:機能は次のようになります。複数の範囲を関数に渡すことができます。これは、ユーザーにとってもっときれいだと思います。あなたは、たとえば、括弧内の範囲の各セットをラップスプレッドシートで関数を呼び出すとき:calculateIt((A1,A3), (B6,B9))

上記の呼び出しは、あなたの2つのセッションがA1とA3にあると仮定して、あなたの2人の顧客は、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 

良いところは、あなたが連続した範囲としてご入力の両方を持っている場合、あなたは、例えば、あなたが通常の1と同じように、この関数を呼び出すことができ、ありますcalculateIt(A1:A3, B6:B9)

、ParamArrayはする代わりに:)

+0

ParamArrayは良い方法ですが、このオプションはマルチセル引数のための非常にクリーンな方法を提供します。それはもっと多くの票を得たはずです... –

関連する問題