Excel2013でフォームを削除するときに処理停止してしまう問題の解決策

標準

VBAで作成したフォームを削除するときに、Unload Meというコマンドを使ってたのですが、特殊な条件でのみ処理停止するという問題が発生したので、その解決策です。Excel2010、2013で確認しましたが、現象が確認できたのはExcel2013のみでした。おそらくExcel2013以降ならばほぼ確実に発生します。

結論を先に書いてしまうと、シートを削除してからフォームを削除すると処理停止していしまうので、フォームを削除してからシートを削除すると上手くいきます。Unload Meそのものが原因ではありませんでした。

詳細は以下。

 

 

≪再現方法≫

準備は次の通りです。

1.新しいエクセルファイルを開き、Alt+F11でコードエディタを開く。

2.ユーザーフォームと標準モジュールを挿入する。

3.標準モジュールには次のコードを記載。

Public Sub BreakSample()
 Worksheets.Add
 UserForm1.Show
End Sub

4.ユーザーフォームにはツールボックスからボタンを貼りつける。ボタンをクリックして以下のコードを記載。

Private Sub CommandButton1_Click()
 ActiveSheet.Delete
 Unload Me
End Sub

これで準備完了です。再現方法としては次の通り。

1.Alt+F8でマクロ起動画面を表示し、BreakSampleを実行。

図20160313-1

2.新しいシートができてUserFormが表示される。

図20160313-2

3.フォームのボタンをクリック。「選択したシートに、データが存在する可能性があります。データを完全に削除するには、[削除]をクリックしてください。」という注意メッセージが出てきますが、削除を選択。

4.新しいシートが消えてフォームも消える

図20160313-3

5.ほかのセルを選択できるけれども、入力しようとするとExcelが強制終了。ウィンドウを閉じようとしても閉じられないという状況になります。

 

≪考察≫

エクセル内部の処理としては追加したシート→フォームの順でフォーカスが移っているんだと思います。なので、そこまでは問題ありません。

ところが、削除時に先にシートを削除してからフォームを削除してしまうとトラブル発生。Excel側はフォーム→シートの順でフォーカスを移動させようとします。しかしすでに削除されたシートをフォーカスしようとしてしまうため、処理できず強制終了してしまう、と。ウィンドウを閉じることもできないので、終了する場合はタスクマネージャからExcelを終了させるしかないです。

この問題の厄介なところはExcel2013だけで発生する、ということ。原因はウィンドウの表示方法がExcel2013で変わってしまったからだと思います。なので、Excel2013以降ならば2016でも発生するかも。

Excel2010までは全ファイルを1つのウィンドウで表示させていました。しかし、Excel2013からはその方式を変更して1ファイル1ウィンドウが基本となります。つまり、Excel2010までならばシートが削除されてもウィンドウは残っているため問題なくフォーカスが移るのですが、Excel2013ならばその辺がうまくいかない、と。

……ここまで書いてて、1シート1ウィンドウじゃないのに、なんでフォーカスがうまく移らないのかよく分からなくなってきました。でもExcel2013とExcel2010の違いはウィンドウの表示方式ぐらいだしなー。

 

で、解決策としては冒頭に記載したとおり。先にフォームを削除してExcelにフォーカスを移してからシートを削除すると問題なく動きます。

また、もう一つの手段もあります。フォームがデフォルトの状態だとモーダル(フォームを表示させているとExcelが操作できない状態)なので、それをオフにしたモードレス状態でフォームを表示させれば順序が違っていても問題ないです。とはいえ、モードレス状態だとフォームを表示した状態でExcelのシートに書き込みができるので、そうさせたくない場合には使えない手段ですが。

 

すべてのExcelでこの現象が起こっていれば分かりやすかったんですが、Excel2013だけというのが非常に不思議でした。結果的には順序を変えるだけで対処できることが分かったので一安心。原理が分かればなんてことないんですが、最初に問題が見つかったときは全く原因が分からずに随分と悩みました。


コメントを残す

メールアドレスが公開されることはありません。