![日記 日記](https://srad.jp/static/topics/journal_64.png)
Neoceratodusの日記: Excelがマクロ実行中に突然落ちる 15
つい5分前まで正常に動いていたのに。
それどころか、再起動すると動く。
まあ、落ちたり落ちなかったり。
落ちるときにはなにもなく急に落ちるので、デバッガでステップイン実行していると、落ちるときは大抵ループにはいるところで落ちている。
別にその部分はごく普通のコードだと思う(For i=1 To Cells(1,1).End(xlDown).Row とか)。
なんか面倒な予感しかしない。
追記。
どうにも書き方が悪かったようなので。
Sub hoge(ws As Worksheet)
If ws Is Nothing Then
Exit Sub
End If
Dim i As Long
For i = 1 To sh.Cells(1, 1).End(xlDown).Row
(略)
Next i
End Sub
みたいなコードで、A列には適切なデータが入った状態。
他ブックのマクロから呼ばれてたりで呼び出しは複雑め、といっても二桁とか呼び出しがネストしているわけでもない。
ステップイン実行中で言えばForステートメントの行でF8すると、エラーもなにもなくいきなりExcelが強制終了する。
通常実行時でも突然エラーメッセージもなにも吐かずにいきなり落ちる。最初は落ちたことに気がつかなかったくらい静かにいなくなってる。
かつ、対象となるデータが同じであっても、正常に処理を完了することもあれば、落ちてることもある。実行時間が数分ずれただけで、後の条件はすべて同じと言っていいはず(処理結果は別ブックに書くので、元ファイルには影響なし。結果を記載するブックは操作対象シートをきちんと指定した上で実行毎にws.Cells.Clearしている)。こんな条件で、ただ同じマクロを連続して実行したときに落ちる→落ちる→正常→おちる、みたいなことがある。
違ったらすみません (スコア:2)
ループ内にDoEventsを入れてみるとか
Re:違ったらすみません (スコア:1)
> Cells(1,1).End(xlDown).Row
これはforで都度計算するのではなく、事前に求めて変数に入れておいたほうがいいような。
あと、A列が空だったら、最終行までの100万回ループになってひどいことになりそう。
Re:違ったらすみません (スコア:1)
え、vba都度評価するんですか
いやforなら普通か。
何となく最初に評価してn to mで決めうちで終わりかと思いこんでました。デバッガのステップ実行も最初だけ通ってあとは本体のみで通らないので。
そのうち確認しよう、ループ内でインクリメントしてみたりとか。
空列想定はそれはそうなんですが、シート末尾から上にというのも面倒だし、無視しています。
使うのはほぼ自分だけだし、という言い訳。
俺たちゃ金持ちだー気にすんなー (スコア:0)
都度計算していると言うか都度インスタンス化してんね
まあどっかに定数で最大行数が定義してあるからそこを参照すりゃいい気もするけど
単に動的に設定されたiの型のサイズが最大行数よりも小さいから落ちてるだけな気がする
Re: (スコア:0)
whileでも毎回評価するでしょ…
Re:違ったらすみません (スコア:1)
なんというか、文法としてvbaのForは
For [var] = [int] To [int]
なイメージだったんです。
[int]部分は数値リテラル。[var]は変数。みたいな。
末端としてループ処理にはいる前に一度だけ評価が行われ数値になり、Forステートメントの評価段階では数値リテラルと同質な、単なる数値になっているようなイメージが。
完全に思いこみです。
言われてみれば他言語のループ構文は都度評価が基本ですよねぇ。そのためにパフォーマンス気にして代入したりするし。
Re: (スコア:0)
>A列が空だったら、最終行までの100万回ループになってひどいことになりそう。
私はUsedRange.row+UsedRange.rows.count
を取得しておいて、そこまでのループって事をよくやりますw
これだと一番左が空でもOK
Re:違ったらすみません (スコア:1)
ええ、そんな対応になりますよね…。
私の場合だと、ループ内でなくループ前におくと良いようです。
するとその直後のループでは落ちなくなる。
そしてその後のループで落ちる。
落ちる場所近辺に原因があるとは限らない (スコア:0)
なんとなく、リソース不足で落ちるときに似ているような。
シートやセルの参照を参照変数に入れた後、
たしかexcelvbaって要らなくなったらnothingを代入するって後処理しないと、参照不要でもメモリ上に残る場合があった気が。
で、同じ名前で再度宣言したときはまた、新しくメモリ確保して。。で落ちる。
with~end withは大丈夫? (スコア:1)
応答なしでタイムアウトからの強制終了コンボでなければ、メモリ破壊とかしてそうでいやな落ち方ですね。
自分だったら、Windowsのイベントログに痕跡が残ってないか確認してみますね。
Application.ScreenUpdating = False/True
してるか、
後は適時、DoEvents挟んで本来の処理を回すと変化があるか確認してみる。
VB6由来でwithとか使っていて、end with前にexit for/subとかで抜けるとスタック破壊からの落ちる系の既知バグが有った気がします。
無駄かもしれませんが、ツール>オプション、全般タブの「エラートラップ」を「エラー発生時に中断」とかでトラップしないかチャレンジしてみるとか。
親オブジェクト省略してるせいでは (スコア:0)
cellsプロパティの親を省略するとActiveSheetを見に行くから
Re:親オブジェクト省略してるせいでは (スコア:1)
それはもちろん存じております。
シートを指定しての場合であっても同様に落ちます。
(shをworksheet型変数として、もちろんnull...vbaではnothingでしたっけ...でないときにsh.Cells(以下略 で落ちます)
スマホからの投稿のため入力が面倒ではしょったせいで勘違いさせてしまってすみません。
とりあえず (スコア:0)
on error goto でtrapしてそこにブレークポイント仕掛けて
変数やセルの値を確認してからresumeしよう。
落ちたときの状態と具体的な落ちた場所を確認できれば大抵は解決できる。
Re:とりあえず (スコア:1)
On error goto ってエラー吐かずにいきなり落ちる場合も適切に動作してくれるのでしょうか。
それならとても頼りになります。
さっそく明日試してみます。
Re: (スコア:0)
なんとなく本当はループに入る前か入った後で落ちてる気はしますね