和風スパゲティのレシピ

日本語でコーディングするExcelVBA

通常の実行ではエラーが出るのに1行ずつ実行すると上手くいく原因

知らずに落ちると抜け出せなくなるVBAの落とし穴です。

  • マクロがエラーで止まったのに、検証しようと「デバッグ」から1行ずつ実行したら上手くいってしまう。
  • マクロの結果がおかしいので、ステップイン(F8)で1行ずつ実行して検証したら正しい結果が出てしまう。

ことにお悩みの方はこの記事に目を通してみて下さい。


この現象は大きく分けて2つの原因が考えられます。

  1. 検証時の無意識な操作で状態が変わり、それで上手くいくようになる
  2. 通常実行のVBAの処理スピードに、Windowsがついていけない


1については、高確率でActiveSheetが原因です。

Cells、Rangeの親シートが省略されている箇所を、
「 Cells」「 Range」と半角スペース入りで検索してみてください。


この罠が起きる原因は単純で、
「不具合が起きるとそのシートをアクティブにしてよく見ようとするので、
 結果的にそれで上手くいってしまう」
という原理です。


例えば

ws処理シート.Range(ws処理シート.Cells(1, 1), Cells(10, 1))

と、1ヵ所親シートの指定をし忘れてしまったとします。


この時出る[アプリケーションまたはオブジェクト定義のエラーです]に対し、

「処理シートを選択して、よーく見ながら1行ずつ実行しよう!」

と思っちゃうと、ActiveSheetがws処理シートと一致してエラーが解消されてしまうというのが、一番ありがちなパターンですね。

  • エラーは出ないけど集計結果がおかしい(特に合計が0になるなど)
  • ⇒1行ずつ実行するとちゃんとした集計結果になる。

という場合も、同じようにデータシートをよく見ながら実行したことでたまたまActiveSheetが正しい設定になった可能性が高いです。


1行ずつ実行するとなぜかうまくいくとなったら、
真っ先にActiveSheetを疑ってください。



続いて2の「VBAの処理スピードに、Windowsがついていけない」ですが、
こちらはそこそこの確率でWorkbooks.OpenやWorkbooks.Saveが原因です。

  • ファイルを開く⇒まだ開ききっていないのに次のコードが始まっちゃう
  • ファイルを保存⇒書き込みが完了する前に次のコードが始まっちゃう

あたりで良く発生し、私の経験では共有サーバーにあるブックを処理した際に発生することが多い印象です。


デバッグで1行ずつ実行するときは、開かれたブックが正しいものかを確認してから次の行を実行したくなりますので、結果としてエラーが出なくなってしまうということですね。



対処法はWindowsを待ってあげることなので、
一旦OSに制御を渡す「DoEvents」をOpenの直後(あるいは前後)に置いておくと、直ることが多いです。

Workbooks("\\00.00.00.00\~~~.xlsx").Open
DoEvents

次のコード

こんな感じですね。


あとはたまにですがApplication.ScreenUpdating = Falseが原因であることがあります。


描画停止中に開いたブックは、その後描画を開始してもマクロが終了するまでは画面には表示されないという仕様があり、これが原因かもしれません。



Openの直前だけ描画を再開し、その後また停止する

Application.ScreenUpdating = True
Workbooks("\\00.00.00.00\~~~.xlsx").Open
DoEvents
Application.ScreenUpdating = False

をやったら解決したことがありましたので、
試してみる価値はあるかもしれません。



これでうまくいかなかった場合は結構厄介で、
下手するとVBAのせいではなく、共有サーバーのせいということもありました。

その時はまあ、なんとか頑張ってください( ´∀`)b



「デバッグをしようと思ったのにエラーが出てくれない」

というのはとても困ります。


こういう「そもそも原因を調べるのが大変なバグ」と戦うときは、
バグになりやすいポイントを知識として持っているか勝負になります。


今回のポイントも、忘れないでいてあげてください。