ExcelVBAを実行すると何故か最後にExcelが落ちてしまった時の備忘録です。
詳しいExcelのバージョンやソースコードは記載していません。
もし同じような現象にあってこの方法で解決出来たら幸いです。
現象:VBA実行後Excelが落ちる
私がおきた現象は、ExcelVBAを実行後
正常に終了はするのですが、終了後に
Excelが落ちてしまい、
回復済みのExcelが起動するというものでした。
VBAの内容はファイルを開いて作業して、
保存して閉じるというのを
ループで何度もやってるというものでした。
試したこと:setの解放(Nothing)の確認
配列や、ワークシート変数などを使用するときに
setを使います。
例としたwb変数にワークブックを設定します。
set wb = ThisWorkbook
このあといろいろなことで
wbを使用し、最後に解放します。
set wb = Nothing
このようにNothingを設定して解放しないと
何度も実行すると落ちることがあります。
ちなみに今回のパターンは、setで使ったものは
全て最後に解放していました。
にもかかわらずExcelは落ちました。
調査1:細かくブレークポイントを設定して調べる
どう調べていいかわからなかったので
細かくブレークポイントを設定して
どこまで正常に動くか調べました。
そもそも正常に終了してから
Excelが落ちているので、この作業は無意味のように
思われますが、実はこれが有効でした。
調査2:ステップインで1行ずつ実行
ステップインで1行ずつ実行したときに
ファイルのオープン、クローズの時に
わずかな違和感を感じました。
操作になれた人間がやるより
VBAのほうが早くかんじました。
検証・成功
そこでファイルを閉じたあと、
3秒待つ(Wait)を入れてみました。
例)
Workbook.Close
'---(このあと処理3つぐらい記載)
Application.Wait (Now + TimeValue("00:00:03")) '----3秒待つ
'-----次のファイルの処理
Workbooks.Open "C:\●●●.xlsx"
結果、これを入れたら実行後Excelは落ちなくなりました。
推測:ファイルを閉じて、次のファイルが開くタイミングが早いのかも
ファイルを閉じてから次のファイルを開く
操作がVBAのほうが人間より早すぎて
処理が追いつかないのではないかと推測しました。
それでも落ちるならAPIのsleepを使う
waitでもやはりExcelが落ちてしまった場合
sleepを使ってみました。
sleepはそのままだとエラーになるので
一番上のSubより上に宣言します。
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
'32bitだとこちら
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If
Sub XXXXXX()
これを入れることで、sleepという処理を数秒待つ関数が使えます。
sleep 5000 '----5000ミリ秒・・・5秒待つ
waitとの違いなど詳しい説明は省きますが、
私の場合はWaitで落ちたものがsleepできちんと終了できるようになりました。