- ベストアンサー
Excel VBAについての効果的な処理方法
- Excel VBAの処理を効果的に行うための方法を教えてください。
- 現在のコードでは処理に時間がかかりすぎてしまっています。
- より高速な処理方法があれば教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
確認したい点があります。 sh1 = ActiveSheet.Cells(r, 4) から ActiveSheet.Cells(r, 19) = Application.Subtotal(105, Sheets(sh1).Range("O:O")) までの所で行っている処理には変数 i が全く登場しておらず、一見すると For i = 1 To lastrow '4 の繰り返し処理において、同じ値をセルに入力するという1回行えば済む処理をlastrow の行数と同じ回数だけ繰り返し行うという無駄な繰り返しを行っている様に見えるのですが、これはもしかしますと各シートにワークシート関数が入力されているセルがあり、関数の出力結果によって、セルに入力する値が変わって来るという事なのでしょうか? もしそうではなく、各シートには特にワークシート関数が使われているセルは存在していないという場合には、 >時間がかかりすぎてしまいます。 という事が起きる原因は For i = 1 To lastrow '4 の繰り返し処理にありますので、その繰り返し処理は行わない様にした方が良いと思います。 それからオートフィルターは処理速度が遅いため、むしろFor等の繰り返し処理で1行ずつデータを確認して行った方が処理に要する時間が短くなる場合が少なくありません。 Sub test_改() Dim lastrow As Long, lastrow2 As Long, r As Long, j As Long _ , buf As Variant, myMin(2) As Double lastrow = Cells(Rows.Count, "D").End(xlUp).Row With Application .ScreenUpdating = False .Calculation = xlManual End With For r = 7 To lastrow '7 With Sheets(ActiveSheet.Cells(r, 4)) ActiveSheet.Cells(r, 20) = _ WorksheetFunction.CountIfs(.Range("D:D"), Range("H3") & Range("I3"), .Range("K:K"), "<=3") _ / WorksheetFunction.CountIf(.Range("D:D"), Range("H3") & Range("I3")) ActiveSheet.Cells(r, 21) = _ WorksheetFunction.CountIfs(.Range("C:C"), Range("F3"), .Range("K:K"), "<=3") _ / WorksheetFunction.CountIf(.Range("C:C"), Range("F3")) ActiveSheet.Cells(r, 22) = _ WorksheetFunction.CountIfs(.Range("E:E"), Range("K3"), .Range("K:K"), "<=3") _ / WorksheetFunction.CountIf(.Range("E:E"), Range("K3")) lastrow2 = .Cells(.Rows.Count, "O").End(xlUp).Row myMin(0) = WorksheetFunction.Max(.Columns("O")) For j = 0 To UBound(myMin) myMin(j) = myMin(0) Next j If lastrow2 > 3 Then For j = 4 To lastrow2 buf = .Range("O" & j).Value If .Range("D" & j).Value = Range("H3") & Range("I3") _ And buf <> "" And buf < myMin(0) Then myMin(0) = buf If .Range("D" & j).Value = Range("H3") & Range("I3") - 200 _ And buf <> "" And buf < myMin(1) Then myMin(1) = buf If .Range("D" & j).Value = Range("H3") & Range("I3") + 200 _ And buf <> "" And buf < myMin(2) Then myMin(2) = buf Next j End If ActiveSheet.Cells(r, 15) = myMin(0) ActiveSheet.Cells(r, 18) = myMin(1) ActiveSheet.Cells(r, 19) = myMin(2) End With Next r With Application .Calculation = xlAutomatic .ScreenUpdating = True End With End Sub
その他の回答 (1)
- neKo_quatre
- ベストアンサー率44% (735/1636)
> もっと処理のスピードを上げたいのですが、 定番の方法だと、処理の前に、 ・画面の更新を停止する ・自動計算を停止する って方法があります。 Sub test() ' 処理前に、 Application.ScreenUpdating = False Application.Calculation = xlCalculationManual ' ここで実際の処理 ' ~ ' 処理の後で、 Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
お礼
コメントありがとうございます。 このコードは、call で呼び出ししていて その先に Application.ScreenUpdating = False Application.Calculation = xlCalculationManual はいれていたのです。 しかし、直接コードに入れると倍くらい速くなりました。 ありがとうございます。
お礼
コメントありがとうございます。 なぜかwith ~ End with が使えなかったため その辺は、変数sh1 にて質問どおりで 他はコードを試させて頂きました。 ものすごく速くてびっくりしました。 回答者No1様のも倍くらい早かったのですが No2様に掲示して頂いたコードでは数秒で処理が終わりました!
補足
変数i は消すのを忘れていました・・・