Excel:パブリック変数の中身がけっこう消える件
パブリック変数ってエラーが起きてプロシージャの実行が止まると初期化されちゃうなというのは、VBAを覚え始めた頃に気づいていました。しかしエラーの発生以外でも初期化されることがあるというのは、最近になって気づきました。調べたら公式にもちゃんと書いてありました: まあなんかあったら初期化されちゃう可能性があるっていう前提でプログラムを書いてたので、気づくことがなかったのかもしれませんがw 以下は標準モジュールで宣言したパブリック変数intTempにフォームモジュールから値を設定した後、意図的にエラーを発生させるサンプルです。メッセージボックスでintTempの値を表示させます。 この場合はOn Error GoToでエラー処理をしてあり、プロシージャの実行は止まりません。 標準モジュール(各プロシージャはシート上のボタン1・ボタン2から実行します) Public intTemp As Integer '←パブリック変数 Public Sub ボタン1_Click() On Error GoTo Err_Handler intTemp = 5 '←値の設定 MsgBox Prompt:=intTemp, Title:="ボタン1 フォーム表示前" UserForm1.Show MsgBox Prompt:=intTemp, Title:="ボタン1 フォーム表示後" Err.Raise 13 '←エラー発生 Finally: Exit Sub Err_Handler: Err.Clear Resume Finally End Sub Public Sub ボタン2_Click() MsgBox Prompt:=intTemp, Title:="ボタン2" End Subフォームモジュール(CommandButton1が置いてあります) Private Sub CommandButton1_Click() intTemp = 10 '←値の設定 Unload Me End Subボタン1でまずメッセージボックスが出て、ユーザーフォーム表示後にもう一度出ます。 これは問題ありません。その後ボタン2を実行すると: intTempは「期待通り」保持されています。 次にボタン1のOn Error GoToの部分はコメントアウトしてみます。これで実行すると、Err.Raiseによりプロシージャが途中で止まります。 この後ボタン2を実行すると、intTempが初期化されているのがわかります。 これだけ見ると、じゃあエラー処理してあればだいじょぶでしょってことになりますが・・・ それでも初期化されてしまうケースをたまたま見て、エラーだけじゃないんだなと知りました。要はなんらかの理由でプロジェクトがリセットされたとExcelが認識すると、初期化されてしまうようですね。 上の例は自分では再現できなかったんですけど、そういうケースもあり得るらしい。
いろいろ見てると、「パブリック変数はブックを閉じるまで値が保持される」と説明しているサイトもありました。 知らないで使ってると危険ですよねw |
なるほど。
確かに私も、エラー後にグローバル変数の値が消えてしまうのは納得していましたが、エラーが発生しなくても消えている場合があるのは解せずにとても悩んでいました。
その時には、仕方なくExcelでワーク変数としての役割を持たせたシートを作り、マクロで使うとき以外には非表示にすることで対応していましたが、苦肉の策ですし、ワークシートに値を書き込んでいたので、型が変わったりしてしまい、本質ではない部分で非常に手がかかり、もどかしい思いをしたことがあります。
そんな状態から抜け出せずにずっと悩んでいたのを思い出しました(笑)
2011/2/28(月) 午前 0:55 [ 2011年の表示名 ]
たしかにワークシートに保存する場合はデータ型の問題がありますよね。公式の説明でも「非表示にしたワークシートに値を記述」とはなってますけど、そこまでは触れてないですねw
値を保持し続けるというやり方自体、あまりしない方がいいのかもしれないですね。
実際には必要なケースもあるのでなんとも悩ましい話ではありますが・・・
2011/2/28(月) 午前 5:40