0

WorksheetFunction.Sum を使用して、結果のすべての行で同じフィールドを合計しようとしていますが、そうではないようです。エラーはスローされず、何も合計されません。実際、一部の行は複数の行の結果をスローする必要があることを知っています。

これは私がやろうとしていることです:

For Each Code In BomCodes

                        With InventorySheet
                            .AutoFilterMode = False
                            .Range("B1").AutoFilter Field:=2, Criteria1:="Project"
                            .Range("D1").AutoFilter Field:=4, Criteria1:="ContractNumber"
                            .Range("N1").AutoFilter Field:=14, Criteria1:="Code"
                            .Range("Q1").AutoFilter Field:=17, Criteria1:=">0"
                        End With

                        'Do a search through the filtered inventory
                        Set rangeFilteredInventory = InventorySheet.Range("Q2:Q" & Cells(Rows.Count, "Q").End(xlUp).Row)

                            'Get the sum of all results
                            With InventorySheet
                            TotalQty = WorksheetFunction.Sum(rangeFilteredInventory.SpecialCells(xlCellTypeVisible))
                             If TotalQty <> 0 Then
                                Debug.Print TotalQty, vbNewLine, vbNewLine
                             End If
                            End With
                         Next Code

使わずにやってみた

Applicaiton.WorksheetFunction.Sum

Set rangeFilteredInventory = InventorySheet.Range("Q2:Q" & Cells(Rows.Count, "Q").End(xlUp).Row)

すべてをループしますが、If 構造にコメントを付けると、常に 0 と表示されます。

の変更

Set rangeFilteredInventory = InventorySheet.Range("Q2:Q" & Rows.Count).End(xlUp).Row

最初のレコードにもアクセスしません

また、

Set rangeFilteredInventory = InventorySheet.Range("Q" & Rows.Count).End(xlUp).Row

最初のレコードにもアクセスしません。

だから、私の考えは、範囲を間違っているということです。そのシートのすべての「Q」を合計する必要があります。

そのシートにマクロを作成すると、

With Worksheets("sbom")
                            .AutoFilterMode = False
                            .Range("B1").AutoFilter Field:=2, Criteria1:="5522970"
                            .Range("D1").AutoFilter Field:=4, Criteria1:="0008621302140U"
                            .Range("N1").AutoFilter Field:=14, Criteria1:="LVE70001372"
                            .Range("Q1").AutoFilter Field:=17, Criteria1:=">0"
 End With

複数のレコードを返します。

間違った方法でそこに新しいものがある場合は申し訳ありません。私は VBA を初めて使用し、独学で学んでいます。

編集:

Subtotal の SUM を切り替えましたが、ループは実行されますが、TotalQty はまだ 0 です。BK201 がくれた回答の一部を使用して、いくつかの点を改善しました。

For Each Code In BomCodes
                       Debug.Print "Grabbed Code:", Code, vbNewLine
                        With InventorySheet
                            .AutoFilterMode = False
                             LRowOnQ = .Columns("Q").End(xlUp).Row
                            .Range("B1").AutoFilter Field:=2, Criteria1:="Project"
                            .Range("D1").AutoFilter Field:=4, Criteria1:="ContractNumber"
                            .Range("N1").AutoFilter Field:=14, Criteria1:="Code"
                            .Range("Q1").AutoFilter Field:=17, Criteria1:=">0"
                            Set rangeFilteredInventory = .Range("Q2:Q" & LRowOnQ)
                        End With

                        'Do a search through the filtered inventory

                            'Get the sum of all results
                           ' With InventorySheet
                            TotalQty = WorksheetFunction.Subtotal(9, rangeFilteredInventory.SpecialCells(xlCellTypeVisible))
                                If TotalQty <> 0 Then
                                    Debug.Print TotalQty, vbNewLine, vbNewLine
                                End If
                         Next Code
4

1 に答える 1

1

最後の行を検索する場合は、常に のロジックを適用してWithください。基本的に、どのシートのどの行を見つけたいか注意してください。もっと明確に。エラーの一部は、悪いコードではなく、単純な悪いコーディング スタイルから発生していると思います。アプローチは適切ですが、結果は出ていません。

より良いコーディングとおそらく解決策のために、次のコードとその後のコメントを参照してください。

For Each Code In BomCodes
    With InventorySheet
        .AutoFilterMode = False
        LRowOnQ = .Columns("Q").End(xlUp).Row
        .Range("B1").AutoFilter Field:=2, Criteria1:="Project"
        .Range("D1").AutoFilter Field:=4, Criteria1:="ContractNumber"
        .Range("N1").AutoFilter Field:=14, Criteria1:="Code"
        .Range("Q1").AutoFilter Field:=17, Criteria1:=">0"
        Set rangeFilteredInventory = .Range("Q2:Q" & LRowOnQ)
    End With

    'Get the sum of all results
    TotalQty =WorksheetFunction.Sum(rangeFilteredInventory.SpecialCells(xlCellTypeVisible))
    If TotalQty <> 0 Then
        Debug.Print TotalQty, vbNewLine, vbNewLine
    End If
Next Code

2つのこと:

まず、変数 LRowOnQ に注目してください。あなたのコードとの違いは、Cells(Rows.Count...それが取られるべき場所を明確に指定せずに使用したことです。先行InventorySheetするからといって、変数がそこから取得されるわけではありません。マクロが別のシートから呼び出され、最後の行がアクティブなシートから取得された場合、間違った値が返されます。

これに対処する適切な方法は、上記のようにInventorySheet、列 Q にロックすることです。そうすれば、値があいまいなソースから取得されることはありません。これにより、コーディング スタイルが改善され、よりSet読みrangeFilteredInventoryやすいコードに削減されます。

また、配置にも注意してください。が適用される前に設定さAutoFilterれました。理由は非常に単純です。フィルターが適用された後に配置すると、データ テーブルの最後の行ではなく、フィルター処理された列の最後の行がチェックされます。参考までにテストコードを載せておきます。

Sub Test()
    Dim Rng As Range
    Set Rng = ActiveSheet.Columns("Q")
    Debug.Print Rng.Cells(Rows.Count, 1).End(xlUp).Row
End Sub

フィルタリングされたテーブルの最後の行を返すことが、フィルタリングされていないテーブル全体よりも面倒な理由はたくさんありますが、ここでは触れません。ただし、逆にしたい場合は、すべてのAutoFilters が適用された後に配置してください。

次に、セカンダリを削除した方法に注目してWith InventorySheetください。コードでWith InventorySheet2 回宣言する必要がありましたが、2 番目のブロックはまったく使用されていません。rangeFilteredInventoryはすでに宣言されているので、Withブロックに含める必要はありません。

コーディング スタイルが修正されたとしても、アプローチには多少の作業が必要になる場合があります。私は、まず、SUBTOTAL代わりに を使用しSUMます。ただし、ケースが異なる場合や、代わりに他の理由でこれを使用したい場合があるため、これが必要であるとは思いません。

上記をテストして、結果をお知らせください。

于 2013-10-31T03:06:23.213 に答える