現在、私は毎月手動で準備しているレポートを自動化しようとしていますが、効率的に実行するにはいくつか問題があります。基本的には、報告書は、4つの入力があります。Excel VBA:複数の配列間でインデックス(Match())を複製する
- を今月YTDは[87K行×8つのcols] &貯蓄レポート(部品番号別)[70K行×4つのcolsの]
- 今月部品番号ルックアップテーブルを過ごし あなたが見ることができるように(製品番号)&貯蓄レポートをお過ごし[60K行×4つのcolsの]
- 前月品番ルックアップテーブル[77K行×8つのcols]
私の目標は、これらの入力をすべて組み合わせた1つのデータテーブルを取得し、いくつかの列に対して軽い数学的計算を実行することです。ここに私のコードは、これまでのようになります。
'Store data from 4 data worksheets into arrays
Dim arrPrevDMCRLookup As Variant
Dim lngFirstPDLRow As Long 'PDL = Previous DMCR Lookup
Dim lngLastPDLRow As Long
Dim lngNumPDLRows As Long
Dim lngNumPDLCols As Long
lngFirstPDLRow = 2 'Does not store header row
lngLastPDLRow = wsPreviousLookupData.UsedRange.Rows.Count
arrPrevDMCRLookup = wsPreviousLookupData.Range("A" & lngFirstPDLRow & ":H" & lngLastPDLRow)
lngNumPDLRows = UBound(arrPrevDMCRLookup, 1) - LBound(arrPrevDMCRLookup, 1) + 1
lngNumPDLCols = UBound(arrPrevDMCRLookup, 2) - LBound(arrPrevDMCRLookup, 2) + 1
Dim arrPrevDMCRPivot As Variant
Dim lngFirstPDPRow As Long 'PDP = Previous DMCR Pivot
Dim lngLastPDPRow As Long
Dim lngNumPDPRows As Long
Dim lngNumPDPCols As Long
lngFirstPDPRow = 5 'Does not store header row
lngLastPDPRow = wsPreviousPivotSheet.UsedRange.Rows.Count
arrPrevDMCRPivot = wsPreviousPivotSheet.Range("A" & lngFirstPDPRow & ":D" & lngLastPDPRow)
lngNumPDPRows = UBound(arrPrevDMCRPivot, 1) - LBound(arrPrevDMCRPivot, 1) + 1
lngNumPDPCols = UBound(arrPrevDMCRPivot, 2) - LBound(arrPrevDMCRPivot, 2) + 1
Dim arrCurrDMCRLookup As Variant
Dim lngFirstCDLRow As Long 'CDL = Current DMCR Lookup
Dim lngLastCDLRow As Long
Dim lngNumCDLRows As Long
Dim lngNumCDLCols As Long
lngFirstCDLRow = 2 'Does not store header row
lngLastCDLRow = wsCurrentLookupData.UsedRange.Rows.Count
arrCurrDMCRLookup = wsCurrentLookupData.Range("A" & lngFirstCDLRow & ":H" & lngLastCDLRow)
lngNumCDLRows = UBound(arrCurrDMCRLookup, 1) - LBound(arrCurrDMCRLookup, 1) + 1
lngNumCDLCols = UBound(arrCurrDMCRLookup, 2) - LBound(arrCurrDMCRLookup, 2) + 1
Dim arrCurrDMCRPivot As Variant
Dim lngFirstCDPRow As Long 'CDP = Current DMCR Pivot
Dim lngLastCDPRow As Long
Dim lngNumCDPRows As Long
Dim lngNumCDPCols As Long
lngFirstCDPRow = 5 'Does not store header row
lngLastCDPRow = wsCurrentPivotSheet.UsedRange.Rows.Count
arrCurrDMCRPivot = wsCurrentPivotSheet.Range("A" & lngFirstCDPRow & ":D" & lngLastCDPRow)
lngNumCDPRows = UBound(arrCurrDMCRPivot, 1) - LBound(arrCurrDMCRPivot, 1) + 1
lngNumCDPCols = UBound(arrCurrDMCRPivot, 2) - LBound(arrCurrDMCRPivot, 2) + 1
'Create array for output data
Dim arrData As Variant
ReDim arrData(1 To lngNumCDPRows, 1 To 21) 'arrData needs to have the same number of rows as arrCurrDMCRPivot and 21 columns
'Fill arrData
Dim i As Long 'Loop variable
Dim j As Long 'Loop variable
For i = 1 To lngNumCDPRows
'Update status bar
Call UpdateStatusBar(1, lngNumCDPRows, i, "Combining reports...")
'Grab data from arrCurrDMCRPivot
arrData(i, 1) = arrCurrDMCRPivot(i, 1) 'Concatenate string
arrData(i, 9) = arrCurrDMCRPivot(i, 2) 'Current Engineering Manager
arrData(i, 10) = arrCurrDMCRPivot(i, 3) 'Current YTD USD Spend
arrData(i, 11) = arrCurrDMCRPivot(i, 4) 'Current YTD USD Savings
'Lookup data from arrCurrDMCRLookup
For j = 1 To lngNumCDLRows
If arrData(i, 1) = arrCurrDMCRLookup(j, 1) Then 'Concatenate strings match
arrData(i, 2) = arrCurrDMCRLookup(j, 2) 'Part number
arrData(i, 3) = arrCurrDMCRLookup(j, 3) 'Part name
arrData(i, 4) = arrCurrDMCRLookup(j, 4) 'Supplier Code
arrData(i, 5) = arrCurrDMCRLookup(j, 5) 'Supplier Name
arrData(i, 6) = arrCurrDMCRLookup(j, 6) 'DMCR Comp Grp
arrData(i, 7) = arrCurrDMCRLookup(j, 7) 'ACSD Org
arrData(i, 12) = arrCurrDMCRLookup(j, 8) 'Current DMCR: Prior Year Average Cost
Exit For 'Stop looking when a match was found
End If
Next j
'Lookup data from arrPrevDMCRPivot
For j = 1 To lngNumPDPRows
If arrData(i, 1) = arrPrevDMCRPivot(j, 1) Then 'Concatenate strings match
arrData(i, 13) = arrPrevDMCRPivot(j, 2) 'Previous Engineering Manager
arrData(i, 14) = arrPrevDMCRPivot(j, 3) 'Previous YTD USD Spend
arrData(i, 15) = arrPrevDMCRPivot(j, 4) 'Previous YTD USD Savings
Exit For 'Stop looking when a match was found
End If
Next j
'Lookup data from arrPrevDMCRLookup
For j = 1 To lngNumPDLRows
If arrData(i, 1) = arrPrevDMCRLookup(j, 1) Then 'Concatenate strings match
arrData(i, 16) = arrPrevDMCRLookup(j, 8) 'Previous DMCR: Prior Year Average Cost
Exit For 'Stop looking when a match was found
End If
Next j
'Calculate remaining fields
Next i
あなたが見ることができるように、私は私のアレイ間でインデックス(マッチ())の機能を複製するようにネストされたループを使用しています。しかし、これはばかげて遅いようです!私のステータスバーの更新を見て、私はそれがまだ行を完了しているとは思わなかった!
今、出力配列の各行に対して、3つの配列にわたって潜在的な224k行をループしています。それはループスルーする潜在的な1570万行です!これを行うにはより良い方法が必要です。そうですか?使用するでしょう
Application.WorksheetFunction.Index(<column from one of the input arrays>, Application.WorksheetFunction.Match(<concatenate string from output array>,<column from input array containing concatenate strings>,0))
仕事がありますか?どのように入力配列から見たい列を指定するのですか?このことをより合理的な速度にするためのヒントは?
ご協力いただきありがとうございます。ここで
クイックノート - あなたのnumRowsの数/ NUMCOLSの割り当てを簡素化することができるように、配列は、ワークシートの範囲から選ばれ、常にずつベースになるまでちょうど ' UBound(array、[dimension]) ' –
各ワークシートのデータはA1から始まりますか? –
ループを避けたい場合は、各配列に辞書ベースのルックアップを作成することができます。これははるかに高速です。 –