VBAで計算を速くできるプログラムは他にありますか

このQ&Aのポイント
  • VBAで計算を速く行う方法について教えてください。
  • 自己流で書いたVBAプログラムでは計算結果が遅いです。もっと速くする方法を教えてください。
  • VBAでの計算速度を改善する方法を教えてください。
回答を見る
  • ベストアンサー

VBAで計算を速くできるプログラムは他にありますか

自己流で書いたのですが、(以下でも答えは合ってはいるのですが、計算結果が出るのが遅いので、もっと速くできるにはどのように書けば良いでしょうか?ご存知の方教えて下さい。 Sub 計算() Dim i, g, u, m, X, A As Integer i = 15 Do Until i = 231 Select Case Cells(i, 1) Case "S" Cells(i, 11) = Cells(i, 5) * Cells(i, 9) Cells(i, 13) = Cells(i, 5) * Cells(i, 9) Cells(i, 14) = 0 Case "R" Cells(i, 11) = Cells(i, 5) * Cells(i, 9) Cells(i, 13) = 0 Cells(i, 14) = Cells(i, 5) * Cells(i, 9) Case "MT" Cells(i, 11) = Cells(i, 5) * Cells(i, 7) * Cells(i, 9) Cells(i, 13) = Cells(i, 5) * 1 * Cells(i, 9) Cells(i, 14) = Cells(i, 5) * 1 * Cells(i, 9) Case "" Cells(i, 11) = "" Cells(i, 13) = "" Cells(i, 14) = "" End Select i = i + 1 Loop i = 15 g = 15 u = 15 Do Until Cells(5, g) = "" For u = 15 To 231 If Cells(u, 1) = "S" Or Cells(u, 1) = "R" Or Cells(u, 1) = "B" Or Cells(u, 1) = "T" Then Cells(u, g) = 0 End If If Cells(u, 1) = "MT" Then Cells(u, g) = Cells(u, 5) * 1 * Cells(u, 9) End If If Cells(u, 1) = "D" Then Cells(u, g) = Cells(u, 5) * Cells(5, g) * Cells(u, 9) End If Next u g = g + 1 Loop u = 15 m = 13 Do Until Cells(10, m) = "" For u = 15 To 231 If Cells(u, 1) = 0 Then Cells(u, 11) = Cells(u, 9) Cells(u, m) = Round(Cells(u, 9) * Cells(10, m), 0) End If Next u m = m + 1 Loop i = 15 X = 15 For i = 15 To 231 If Cells(i, 11) < 0 Then Cells(i, 14).ClearContents End If Next i For i = 15 To 231 If Cells(i, 11) < 0 Then Do Until Cells(i, X) = "" ' A = Cells(i, 14) Cells(i, 14) = Cells(i, X) + A A = Cells(i, 14) X = X + 1 Loop Cells(i, 14) = Cells(i, 11) - Cells(i, 13) - Cells(i, 14) End If X = 15 A = 0 Next i End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • tsubuyuki
  • ベストアンサー率45% (699/1545)
回答No.2

どんなデータの何をどうしたいコードなのかわかりませんので、 コードを拝見した感想だけ。 とりあえず、処理を早くしたいのであれば、 無駄なループをなるべく減らすのが一番の近道、と言うのが印象です。 例えば、 ~引用開始~ i = 15 X = 15 For i = 15 To 231 If Cells(i, 11) < 0 Then Cells(i, 14).ClearContents End If Next i For i = 15 To 231 If Cells(i, 11) < 0 Then Do Until Cells(i, X) = "" ' A = Cells(i, 14) Cells(i, 14) = Cells(i, X) + A A = Cells(i, 14) X = X + 1 Loop Cells(i, 14) = Cells(i, 11) - Cells(i, 13) - Cells(i, 14) End If ~引用終了~ この部分ですが、 15行目から231行目までCells(i, 11)が0未満だったら、 Cells(i, 14)を「消去」と「Do~Loop」を別々に行っていますが、 これは同時に出来るはずです。 これだけでも、トータルの処理速度は少々早く出来ます。 (同じセルに対する処理が半分で済むのですから、単純に半分ですね。  厳密に言うと、なかなかそうはいきませんが。) さらに同じ部分ですが、Do~Loopの中の処理。 これはアレですか? i行の15列目からデータがある範囲の合計を出したい、と言う処理ですか? だとしたら、単純にWorksheetFunction.Sumなどで一発で処理できそうな気がします。 これでループが一つ減りますから、ここだけでもそれなりに時間短縮が出来そうです。 さらにさらに、For i = 15 To 231 で、iは15から、と言う定義が出来ますから、 引用部冒頭の「i=15」の代入は不要ですね。 これは、随所に見られます。 あと、コード冒頭の Dim i, g, u, m, X, A As Integer この変数を宣言する部分ですが、おそらく「これら全てInteger型だよ」のおつもりでしょう。 ですが、これだと変数A以外はバリアント型(Variant)で宣言したようにとられてしまいます。 正しくは、 Dim i As Integer, g As Integer,・・・, A As Integer のように、全てにおいて「As Integer」が必要です。 で、このバリアント型は、整数型より格段に処理が遅いです。 これも、速度に影響が出ている要因の一つと言えるかもしれません。 などなど、無駄なループ処理や代入を減らせば、少しずつ早くなっていくと思いますよ。 最後にもう一つ、余計なお世話を重ねますが、 処理の速さにこだわるなら、 繰り返し処理はDo~LoopよりFor~Nextの方が少々早いですよ。 > i = 15 > Do Until i = 231 > i = i + 1 > Loop のように繰り返しの上限が決まっているなら、   For i = 15 To 231 をオススメします。

siitakekonbu
質問者

お礼

基本が良く分かっていないので、ご指摘のとおりだと思います。 大変勉強になりました。 できるかどうか試してみます。

その他の回答 (2)

  • ap_2
  • ベストアンサー率64% (70/109)
回答No.3

ANo.1で十分そうですね。更に気をつけるならANo.2。そしてもっと細かい話をすると、IntgerよりLong、OrよりIfネスト、CaseよりIf・・・ってどーでもいいヨネ。 出番か!と思ったのに(・ε・) 余計ですが、以下説明。#補足なのでベストにはしないで ExcelVBAが遅くなる最大の原因がセルアクセスです。他にも高速化テクはあるけど影響わずかなので、興味あれば「VBA 高速化」で検索してください。 セルのよーなオブジェクトへのアクセスは内部で細々と処理が走り、特に、セルへの書き込みは毎回"全セルが再計算"されるため、計算式が多いと一晩かかることも。 なのでANo.1のように、まとめて読み込みまとめて書き出すのがベスト。Resizeで範囲を指定すると2次元配列で値のみ取得でき、逆の手順で書き出せます。 ClearContentsの箇所は、MyCells(i,14)=Emptyで。

siitakekonbu
質問者

お礼

MyCells(i,14)=Empty 使わせていただきます。 有難うございました。

  • f272
  • ベストアンサー率46% (8021/17145)
回答No.1

1. CellsをすべてMyCellsに置換する 2. Sub 計算()の次に MyCells = Cells(1, 1).Resize(231, 100) を入れる。 3. End Subの前に Cells(1, 1).Resize(231, 100) = MyCells を入れる。 ただし2.と3.で使っている (231, 100) は,適当に使いそうな大きさの値にしてください。行は231行までを対象にしているようだが,列は最大でどこまで使うのかわからないから適当に100にしています。

関連するQ&A

  • エクセルVBAで、文字列の検索方法について

    先日、こちらで教えていただいたVBAがあります。 E列のセルの文字列の末尾が「計」のものを検索し、その行に色をつけるものです。 Sub iroiro() Dim x, y x = 1 Do If Right(Cells(x, 5), 1) = "計" Then For i = 2 To 5 Cells(x, i).Interior.ColorIndex = 3 Next End If x = x + 1 Loop Until Right(Cells(x, 5), 1) = "" End Sub これはばっちりで、助かっているのですが、今度は末尾ではなく、文字列中に「営業」という文字があるのを検索し、色をつけたいのです。 If Right(Cells(x, 5), 1) = "計" Thenを どう変えればいいのでしょうか?

  • vba  

    VBAはじめたばかりで、躓きました。 下記を実行すると、”Nextに対するForがありません。”とでます。 なぜこうなるのか教えてください。  G2~列2000の間が空白になるまで、  下記の処理を続けるようにしたいと思っています。  Dim i As Integer For i = 7 To 2000 Do If Cells(2, i) = "" Then Range("G2").End(xlToRight).Select ActiveCell.CurrentRegion.Resize(6, 5).Select Selection.Cut Range("B2").End(xlDown).Select ActiveCell.Offset(1).Select ActiveSheet.Paste Exit Do End If Next i Loop  よろしくお願いします。

  • VBA 九九 Do While

    VBAのDo Whileステートメントを使って九九の表をつくりたいのですが、何度やっても途中で詰まり、実行に至りません。 For NextとDo untilではできたと思うのですがDo Whileがどうしてもわからなくて… どなたか助けてください。お願いします。 Sub 九九計算_for() Dim i, j As Integer For i = 1 To 9 For j = 1 To 9 Cells(i, j).Value = i * j Next Next End Sub Sub 九九計算_do_until() j = 1 Do i = 1 Do Cells(j, i).Value = i * j i = i + 1 Loop Until i = 10 j = j + 1 Loop Until j = 10 End Sub

  • VBAで教えてください。

    データがないときはExitSubしたいのですが、何処に記述すれば良いでしょうか? Sub 削除() Dim i As Long If MsgBox("データを削除します。よろしいですか?", vbYesNo) = vbYes Then Sheets("リスト").Select i = 5 Do Until i = 200 If Cells(i, 5).Value = Sheets("マスタ登録").Range("D5") Then Cells(i, 1).EntireRow.Delete End If i = i + 1 Loop Else Exit Sub End If End Sub

  • エクセルVBAの繰り返し処理の質問

    C列にある項目とG列にある項目を比較して、 一致し、H列にある数字が10以上ならば、B列にフラグ1を立てる という処理を行いたいんですが、 下記ぐらいまでしか作れず、うまくいきません・・・ Sub フラグを立てる処理() Dim i As Integer Dim j As Integer Dim k As Integer i = 1 j = 1 Do j = j + 1 Do i = i + 1 If Cells(j, 8) > 9 Then Cells(i - 1, 4) = 1 End If Loop Until Cells(i, 3) <> Cells(j, 7) Or Cells(i, 3) = "" Loop Until Cells(j, 7) = "" End Sub わかる方がいらっしゃいましたら、お願いします。

  • このVBAソースのどこが間違ってるか教えてください

    Dim csp As Integer 'ストップ Dim css As Integer 'ストップorスタート Sub Quest2() If css = 0 Then css = 1 Quest2a Else cstp = 1 css = 0 End If End Sub Sub Quest2a() Sheets("Sheet1").Select Range("B1:J10").Select Selection.Interior.ColorIndex = x1None Range("a1").Select cstp = 0 Do r = 1: c = 5 For i = 0 To 15 If i < 9 Then Cells(r, c).Interior.ColorIndex = x1None r = r + 1 If i < 5 Then c = c + 1 Else c = c - 1 End If Cells(r, c).Interior.ColorIndex = 3 Else Cells(r, c).Interior.ColorIndex = x1None r = r - 1 If i < 13 Then c = c - 1 Else c = c + 1 End If Cells().Interior.ColorIndex = 3 End If 'タイミング For tm1 = 1 To 1000: For tm2 = 1 To 100: Next If cstp = 1 Then Exit For End If Next DoEvents If cstp = 1 Then Exit For End If If r = 3 And c = 5 Then Cells(r, c).Interior.ColorIndex = x1None End If Next DoEvents If cstp = 1 Then Exit Do End If Loop Cells(10, 9) = Cells(r, c) Cells(10, 9).Interior.ColorIndex = 8 End Sub

  • 簡単なVBA

    エクセルで特定の列データを削除したいのですが シンプルな形を教えてください ちなみに今は以下のようなVBAを使っています。 Sub 特定の列を削除する() For i = Cells(1, Columns.Count).End(xlToLeft).Column To 1 Step -1 If Cells(1, i) = "りんご" Then Columns(i).Delete End If Next i For i = Cells(1, Columns.Count).End(xlToLeft).Column To 1 Step -1 If Cells(1, i) = "みかん" Then Columns(i).Delete End If Next i For i = Cells(1, Columns.Count).End(xlToLeft).Column To 1 Step -1 If Cells(1, i) = "ばなな" Then Columns(i).Delete End If Next i End Sub

  • vbaで、連立方程式を解く方法について

    掃き出し法を使って解くようですが、 -1 0 0 2 0 0 0 0 0 -1 -2 0 0 0 0 -2 0 0 -1 1 0 0 2 1 0 0 0 0 0 0 0 -2 0 -1 0 0 0 0 2 0 0 1 このように、行の入れ替えが必要な場合、繰り返しを用いて行を入れ替える必要がありますよね? 下のように作ってみましたが、上手くいきません。↑の行列を正しく入れ替えるだけならできるのですが、もう一度プログラムを作動させるとエラーが出ます。 For j = l To 6 If Abs(a(j, l)) >= Abs(max) Then'0と負の値しかない場合、0が最大になってしまう u = j 'このときの行を保存 End If Next j For m = 1 To 7 brank = a(l, m) '入れ替える前の値を保存 a(l, m) = a(u, m) a(u, m) = brank Cells(l, m) = Cells(u, m) Cells(u, m) = brank Next m Next l do loopを使った方が良いと聞いたのですが、どのようにすればよいのでしょうか?

  • エクセルVBAラベルの変数?

    エクセル2000VBAにて下記のように作成しました。 With ActiveSheet For i = 4 To 200 If Label1.Caption = .Cells(i, 1) Then For h = 4 To 34 If Label25.Caption = .Cells(2, h) Then For idx = i To 200 If .Cells(idx, 3) = Label21.Caption Then Label6.Caption = .Cells(idx, h) Label7.Caption = .Cells(idx + 2, h) GoTo ラベル2 End If Next idx End If Next h End If Next i ラベル2: For i = 4 To 200 If Label2.Caption = .Cells(i, 1) Then For h = 4 To 34 If Label25.Caption = .Cells(2, h) Then For idx = i To 200 If .Cells(idx, 3) = Label21.Caption Then Label8.Caption = .Cells(idx, h) Label9.Caption = .Cells(idx + 2, h) GoTo ラベル3 End If Next idx End If Next h End If Next i ラベル3: ・・・ End With Label1~5まで同じ処理を行うため 1~5まで変数を使用して簡単にしたいのですが Label(変数)の書き込み方がわかりません? 検索を使用しましたが検索項目が悪いのか なかなか解決しません。 何方か教えていただけないでしょうか?

  • VBAで行列を作る方法

    次のようなプログラミングで1,0,-1の要素で作られる3×3行列を全通り調べています。 この場合3の9乗通り調べることができます。 これを4×4や5×5行列など数を大きくして調べたいのですが、このプログラムを配列を使うなどして 簡単にできる方法を教えてください。 よろしくおねがいします。 Sub test() Dim a As Integer '行 Dim b As Integer '列 Dim c As Integer, i As Integer, j As Integer, d As Integer, e As Integer Dim 内積 As Integer, step As Integer Dim f As Integer, g As Integer, h As Integer, l As Integer, m As Integer, n As Integer, k As Integer, x As Integer Dim sum As Integer, total As Integer Dim aa As Integer, aaa As Integer, aaaa As Integer, bb As Integer, bbb As Integer, bbbb As Integer a = 3 '行 b = 3 '列 c = 0 内積 = 0 con = 0 sum = 0 tatal = 0 aa = 0 aaa = 0 aaaa = 0 bb = 0 bbb = 0 bbbb = 0 x = 0 For n = 0 To 2 For m = 0 To 2 For l = 0 To 2 For k = 0 To 2 For h = 0 To 2 For g = 0 To 2 For f = 0 To 2 For e = 0 To 2 For d = 0 To 2 '要素がすべて1 For i = 1 To a For j = 1 To b Cells(i, j) = 1 Next j Next i If bbbb = 1 Then Cells(a - 2, b - 2) = 0 ElseIf bbbb = 2 Then Cells(a - 2, b - 2) = -1 End If If bbb = 1 Then Cells(a - 1, b - 2) = 0 ElseIf bbb = 2 Then Cells(a - 1, b - 2) = -1 End If If bb = 1 Then Cells(a, b - 2) = 0 ElseIf bb = 2 Then Cells(a, b - 2) = -1 End If If aaaa = 1 Then Cells(a - 2, b - 1) = 0 ElseIf aaaa = 2 Then Cells(a - 2, b - 1) = -1 End If If aaa = 1 Then Cells(a - 1, b - 1) = 0 ElseIf aaa = 2 Then Cells(a - 1, b - 1) = -1 End If If aa = 1 Then Cells(a, b - 1) = 0 ElseIf aa = 2 Then Cells(a, b - 1) = -1 End If If total = 1 Then Cells(a - 2, b) = 0 ElseIf total = 2 Then Cells(a - 2, b) = -1 End If If sum = 1 Then Cells(a - 1, b) = 0 ElseIf sum = 2 Then Cells(a - 1, b) = -1 End If If con = 1 Then Cells(a, b) = 0 ElseIf con = 2 Then Cells(a, b) = -1 End If con = con + 1 Next d con = 0 sum = sum + 1 Next e sum = 0 total = total + 1 Next f total = 0 aa = aa + 1 Next g aa= 0 aaa = aaa + 1 Next h aaa = 0 aaaa = aaaa + 1 Next k aaaa = 0 bb = bb + 1 Next l bb = 0 bbb = bbb + 1 Next m bbb = 0 bbbb = bbbb + 1 Next n End Sub

専門家に質問してみよう