VBAを最適化するのに苦労していますFor Each
Excelテーブルに基づくピボットテーブルの10〜15k行をすべて同じブック内で解析する必要があるループ。現在、完了までに約2分かかりますが、会議で使用しているので改善したいと思います。
画面の更新、手動計算の無効化、他のデータ型としての変数の「dim
」など、いくつかの興味深い提案を検索して見つけましたが、速度に違いはありません。私はFor Each
ループは、この目的を目的としたものではありません。
this スーパーユーザーの投稿を読んでいると、関連する値を「辞書」に入れることができ、非常に高速になるようです。フィルタリングする項目が2つあるという事実は、私にとっては少し複雑になります。
私は「やって学ぶ」ので、VBAコーダーであるとは主張していません。ですから、どんな助けでも大歓迎です!
Dim pvtTable As PivotTable
Dim pvtField1, pvtField2 As PivotField
Dim pvtItem1, pvtItem2 As PivotItem
Set ws = ActiveSheet
Set pvtTable = ws.PivotTables("PTReport")
Set pvtField1 = pvtTable.PivotFields("callNummer")
Set pvtField2 = pvtTable.PivotFields("Destination")
Application.ScreenUpdating = False
For Each pvtItem1 In pvtField1.PivotItems
If InStr(UCase(pvtItem1), "STORE") > 0 Then
pvtItem1.Visible = True
Else
pvtItem1.Visible = False
End If
Next
For Each pvtItem2 In pvtField2.PivotItems
If InStr(UCase(pvtItem2), "221") > 0 Then
pvtItem2.Visible = True
Else
pvtItem2.Visible = False
End If
Next
Application.ScreenUpdating = True
何か明確にしたり、提供したりできる場合は、詳細をお知らせください。
InStr(UCase())
への20-30Kの呼び出しが問題だと思います。いくつかのヘルパー列を定義することをお勧めします。たとえば、「callNummer」と「Destination」のデータが列A
とB
にある場合は、
Y1
_→=IFERROR(SEARCH("store", A1), 0)
Z1
_→=IFERROR(SEARCH("221", B1), 0)
次に、VBAコードを変更して、_Yn
_と_Zn
_が_> 0
_であるかどうかを確認します。このように、「callNummer」と「Destination」のデータが変更されるたびに文字列内の文字列チェックが実行され、VBAルーチンが実行する作業が大幅に少なくなります。そしてもちろん、すべてが機能するようになったら、ヘルパー列を非表示にすることができます。
_pvtItemN.Visible = …
_ステートメントをこのフレームワークに変換する方法が正確にわかりません。
ただし、これを機能させることができない場合でも、InStr(UCase(pvtItem2), "221")
テストをInStr(pvtItem2, "221")
に変更できます。探しているのが数字だけの場合、セルのアルファベットの内容を大文字に変換する理由はありません。
最初のfor ... nextループの直前に、次のコードを追加します。
Dim saveCalc as xlCalculation
With Application
.ScreenUpdating = False
saveCalc = .Calculation
.Calculation = xlCalculationManual
End With
次に、2番目のfor ... nextループの後に、次のコードを追加します。
With Application
.ScreenUpdating = True
.Calculation = saveCalc
End With