2

いくつかの条件に基づいて、配列内のを合計したいと思います。データが Excel にある場合は、=SUMIFS数式を使用します。

私が持っている 2 次元配列のサンプル データセットは次のとおりです。

ID1     ID2     ID3     Value
0       1       1       4
0       2       2       5
1       3       2       6
0       1       1       3
0       1       0       2

次の条件に基づいて値列を合計したいと思います。

ID1=0
ID2=1
ID3=1

したがって、行 1 と 4 はこの基準を満たしているため、答えは 7 (4+3) になります。

これをVBAでどのように構築しますか。

ID は無限である可能性があり、文字列である可能性があるため、ループで設定できないことに注意してください。ID=0

4

3 に答える 3

5

速度に関するちょっとした警告!

質問は2D配列に対するものであり、excel.rangeに対するものではないと思います.Excel範囲のループは非常に遅いためです(大量のデータがある場合にのみ有効ですが、使用する予定がある場合は通常のケースです. VBA マクロ ;-) )

この問題を報告するいくつかのリンクを見つけるまで、範囲の遅さに悩まされていました (10000 セルの例では、1 人のユーザーが 2D 配列を使用して 9,7seg と 0,16 seg を報告しています!!)。リンクは以下のとおりです。私の推奨事項は、常に 2D 配列を使用することです。シンプルで、クリーンで、高速です。

その他のパフォーマンス テストについては、次を参照してください。

したがって、大量のデータを処理したい場合は、2D 配列のを得るために、Jakub の応答のコードを少し変更する必要があります。

Public Function sumIfMultipleConditionsMet2(rng As Range, ParamArray conditions() As Variant) As Double
    Dim conditionCount As Long: conditionCount = UBound(conditions) + 1
    Dim summedColumnIndex As Long: summedColumnIndex = conditionCount + 1
    Dim currentRow As Range
    Dim result As Double: result = 0 'Changed from Long to Double
    Dim i As Long

    If rng.Columns.Count <> conditionCount + 1 Then
        Err.Raise 17, , "Invalid range passed"
    End If        

    Dim conditionsMet As Boolean

    'USING AN ARRAY INSTEAD OF A RANGE
    Dim arr As Variant
    arr = rng.Value 'Copy the range to an array
    Dim r As Long

    For r = LBound(arr, 1) To UBound(arr, 1)  'OLD: For Each currentRow In rng.Rows
        conditionsMet = True
        For i = LBound(conditions) To UBound(conditions)
            ' cells collection is indexed from 1, the array from 0
            ' OLD: conditionsMet = conditionsMet And (currentRow.Cells(1, i + 1).Value = conditions(i))
            conditionsMet = conditionsMet And (arr(r, i + 1) = conditions(i))
        Next i

        If conditionsMet Then
            'OLD: result = result + currentRow.Cells(1, summedColumnIndex).Value
            result = result + arr(r, summedColumnIndex)
        End If
    Next r

    sumIfMultipleConditionsMet2 = result
End Function

Jakub が返信で示したのと同じように使用します。

debug.Print sumIfMultipleConditionsMet2(Range("A1:D50000"), 0, 1, 1)

気に入っていただければ幸いです。

よろしく、 アンドレス


PS: さらに詳しく知りたい場合は、Excel の速度に関するヒントをご覧ください。気に入っていただければ幸いです。

于 2013-10-04T17:01:03.803 に答える
3

paramArray 機能を使用して、sumif 関数のより一般化されたバージョンを取得できます。例えば:

Public Function sumIfMultipleConditionsMet(rng As range, ParamArray conditions() As Variant) As Long
Dim conditionCount As Long: conditionCount = UBound(conditions) + 1
Dim summedColumnIndex As Long: summedColumnIndex = conditionCount + 1
Dim currentRow As range
Dim result As Long: result = 0
Dim i As Long

If rng.Columns.Count <> conditionCount + 1 Then
    Err.Raise 17, , "Invalid range passed"
End If


Dim conditionsMet As Boolean

For Each currentRow In rng.Rows
    conditionsMet = True

    For i = LBound(conditions) To UBound(conditions)
        ' cells collection is indexed from 1, the array from 0
        conditionsMet = conditionsMet And (currentRow.Cells(1, i + 1).Value = conditions(i))
    Next i

    If conditionsMet Then
        result = result + currentRow.Cells(1, summedColumnIndex).Value
    End If
Next

sumIfMultipleConditionsMet = result
End Function

次に、次のように使用できます。

debug.Print sumIfMultipleConditionsMet(Range("A1:D5"), 0, 1, 1)
于 2013-10-03T10:27:12.387 に答える