2017-01-19 6 views
1

初めてExcel VBAでクラスタ内の別のエントリと同じアドレスを含むデータセット内の行を検索しました。これらのエントリはマージしなければならず、その行は削除されます。私は(私の知る限り、私はセットの小さなサンプルで行ったテストから言うことができるように)働く、以下を作ってみた:VBAスクリプトをより速く実行する

Sub Merge_Orders() 

Application.ScreenUpdating = False 
Application.DisplayStatusBar = False 

Dim lastrow As Long 
lastrow = Cells(Rows.Count, "A").End(xlUp).Row 
Dim y As Long 
Dim x As Long 
Dim j As Long 
Dim k As Long 

For i = 2 To lastrow //for each row, starting below header row 
    j = 1 
    y = (Cells(i, 9)) //this is the clusternumber 
    Do While y = (Cells(i + j, 9)) //while the next row is in the same cluster 
    x = (Cells(i, 12)) //this is the adresscode 
    k = 1 
    Do While x = (Cells(i + k, 12)) //while the current adresscode is the same as the next, iterating until another adresscode is hit 
     Cells(i, 16) = Val(Cells(i, 16)) + Val(Cells(i + k, 16)) //update cell value 
     Cells(i, 18) = Cells(i, 18) + Cells(i + k, 18) //update cell value 
     Cells(i, 19) = Cells(i, 19) + Cells(i + k, 19) //update cell value 
     If Cells(i, 20) > Cells(i + k, 20) Then 
     Cells(i, 20) = Cells(i + k, 20) //update cell value 
     End If 
     If Cells(i, 21) > Cells(i + k, 21) Then 
     Cells(i, 21) = Cells(i + k, 21) //update cell value 
     End If 
     Cells(i, 22) = Cells(i, 22) + Cells(i + k, 22) //update cell value 
     Cells(i, 23) = Cells(i, 23) + Cells(i + k, 23) //update cell value 

     Rows(i + 1).EntireRow.Delete //Delete the row from which data was pulled 
     k = k + 1 
    Loop 
    j = j + 1 
    Loop 
Next i 

Application.ScreenUpdating = True 
Application.DisplayStatusBar = True 
End Sub 

私が直面してる問題は時間です。 〜50行の小さなサンプルでこれをテストすると5分以上かかりました。私のエントリーは合計100,000行以上です。視界に終わりがなく1日以上走っています。これを最適化する方法があるので、私が灰色になるまで待つ必要はありませんか?

敬具、

ロブ

+3

細胞内に何か計算されていますか?そうであれば、これらの行をそれぞれ上端と下端に置くと助けになるかもしれません: 'Application.Calculation = xlManual'と' Application.Calculation = xlAutomatic' –

+3

'//'コード自体ではないのですか? ( ''はVBAのコメントマーカーなので)。 'F8'を使ってコードをステップ実行すれば、ループはどこで止まっているようですか?また、ループの各部分にいくつかのブレークを追加して、ループが予想よりも長い時間がかかっている場所を特定することもできます。 – BruceWayne

+5

あなたのコードが意図したとおりに動作するならば(小さなデータセットでテストしてみてください)、フィードバックや最適化に関するヒントは[so]ではなく[codereview.se]にお願いします。 –

答えて

1

2つのこと、私はコメントで述べたように:

1)k(全体k=k+1行)を削除します。 jと置き換えてください。またRows(i + 1).EntireRow.DeleteRows(i + j).EntireRow.Deleteに置き換えてください。

2)行を削除するため、実際にはlastrowは空白になります。 i=2 to lastrowの代わりに、それをdo while Cells(i,12)<>""または何かにしてください。これは、空の行の束をループさせる原因となります。

また、これらのタイプのロールアップは、ピボットテーブルを使用する方が簡単です。また、コメントに記載されているように、SQL GROUP BYを使用すると簡単に行うことができます。

関連する問題