VBA Public変数の初期化に関する質問

このQ&Aのポイント
  • VBAのPublic変数の値が再実行時に初期化されずに残る現象について質問させていただきます。
  • 現象として、コードを再実行するとPublic変数の値が初期化されずに前回の値が残ってしまいます。
  • エクセル2010での検証の結果、エディタの「リセット」ボタンや「デザインモード」ボタンを押すことで値が初期化されることが分かりましたが、明示的に初期化する方法はあるのでしょうか?
回答を見る
  • ベストアンサー

VBA Public変数の値が初期化されません

 質問させていただきます。どうぞよろしくお願いいたします。    環境:Win7 SP1 64Bit     エクセル2010 SP2 32bit でございます。 【現象】  下記のコードを実行後、再実行するとなぜか最初からB_Num = 3 になっております。 VBAの場合は明示的に初期値を入れないでも自動で初期化されるものと思っておりましたが、 「プログラム再実行時に確実に変数が初期化されている」ようにする事は可能でしょうか?       Public B_Num As Integer Sub test() If B_Num > 0 Then Stop For iii = 1 To 3 B_Num = B_Num + 1 Next End Sub 【検証内容】  ・ コード実行 →(End Subまで行って終了)   →再実行   →3が残っている。     ・ コード実行 →(End Subまで行って終了)   →終了している状態で、無意味そうですが、エディタの「リセット」ボタン(四角形)を押す。   →再実行   →何故か値が0に初期化される。     ・上記「リセット」ボタンの代わりに「デザインモード」ボタンを押す。   →同じく値が0に初期化される。     ・ThisWorkBook内、Module1内、どちらに記述しても同じ現象になる。      検索しておりましても「Public変数の値が消えてしまう」という記事はいくつかありましたが 「消えずに残っている」というものを見つけることができませんでした。 (「C言語の場合は初期値が不安定なことがあるので明示的に初期化しないといけない」という記事はありましたが。。。)  どうぞよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

Publicだからというより、モジュールレベルで宣言された変数だから、再実行時に初期化されない。初期化したければ自分でやる(そういうコードを書く)

参考URL:
http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_050_04.html
linelan
質問者

お礼

 どうもありがとうございます!m(_ _)m  >モジュールレベルで宣言された変数だから、  モジュールレベルではなく、プロシージャ単位で宣言しないと消えないのが普通なのですね。 存じませんでした。(×_×; てっきり「全プログラムが終了している状態」になると消えるものとばかり考えておりました。  今後、初期化コードを記述するようにいたします。  お教えいただきどうもありがとうございました。m(_ _)m

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.2

Public変数は、subやfunctionの外にある変数なので、subが実行し終わったくらいのことで初期化されることはありません。値を保持してくれないと困ります。 プログラムを編集したりすると、当然のことながら初期化されます。

linelan
質問者

お礼

 ご回答どうもありがとうございます!!m(_ _)m >subやfunctionの外にある変数なので、subが実行し終わったくらいのことで初期化されることはありません。値を保持してくれないと困ります。  全SUBを実行し終わると(=実行しているプログラムが1つも無い状態)同時に 全ての変数は開放されるのだと思っておりました。。。 という事は、「自動で消えるようにする」にはSUB内で宣言して引数で渡さないといけないわけですね。  勉強になりました!この度はご親切に誠にありがとうございました。m(_ _)m

関連するQ&A

  • excel/vba/public変数

    excel VBAで下記のようなコードを書きました。 他のプロシージャでも共通の変数を使用したいと思っています。 その為、public変数を宣言して使用したいと設定しましたが。 うまくいきません。 testmainを実行し、iに何も入っていないことを確認しました。 その後『1』を代入し、testmainは終了します。 testsubをその後実行し、iに先ほど代入された値を確認しようとしても何も代入されていない状態です。 全プロシージャでその変数を使用したいと思っているのですが、 何か方法、もしくはこのような使用方法ではないのでしょうか? public変数を使用してもプロシージャが終了すれば変数はクリアされるのでしょうか? 構造化の方法の問題上参照渡しや、戻り値など、指定する方が複雑になっていきます。 ご指導よろしくおねがいします。 Public i As Variant Sub testmain() MsgBox test i = 1 End Sub Sub testsub() MsgBox i End Sub

  • 【VBA】値の引渡しについて

    VBA初心者です。 VBAの勉強もかねて、今、【 標準モジュール 】と【 UserForm 】を用いて あるプログラムを作っています。 その中で、プロシージャ間をまたいで 『 値の受け渡し 』をしたいと思っています。 今回、質問をさせていただいたのは、その『 値の受け渡し 』が 「できる場合」と「できない場合」があるので、常にできるように その対応方法を教えていただきたく、今回投稿させていただきました。 ---------------------------------------------------------------- 今困っているパターンを例にあげると、 ユーザフォームの中に2つのボタン 「OK」ボタンと「キャンセル」ボタンが あるとします。 【 「キャンセル」ボタンがおされた場合には「終了する」 】という 仕組みにしたいと思っています。 そこで以下のようなプログラムを作ろうとしました。 ---------------------------------------------------------------- ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1) General部にPublic変数(以下「P変数」)を宣言する。      Public cancel as byte 2) 【標準モジュール】のプロシージャから【フォーム】の「Userform1」を表示させる。          Sub A処理()           Userform1.show           End sub   3) 【フォーム】のUserform1._CommandButton2に以下のように記述する。    (キャンセルボタンがクリックされた場合)          Private Sub CommandButton2_Click()       cancel = False       Unload Me       Exit Sub      End Sub 4) 【標準モジュール】のプロシージャの、一連の処理の最後に    以下のようにプログラムを記述する。          Sub A処理()           Userform1.show      ↓      ↓           if cancel = false then                exit sub           end if      End sub ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1)~4)のようにして 「キャンセルがクリックされた場合、すべての処理を終了する。」 というようなプログラムを記述してみました。 すると、デバッグを使って、変数「cancel」の中身を見てみると 3)の段階で、その変数「cancel」に「false」値を格納したはずなのに、 プロシージャ間をまたいだことで 4)の段階では、変数「cancel」の中身が必ず「""」と 値が空値になってしまいます。 4)の段階でも、変数「cancel」の値が保持できる、 何かしらの方法はないでしょうか。 回答をよろしくお願いします。

  • 取得した変数の値の一番大きい変数を取る

    エクセル2002使用です。 セル(A~F列)にランダムに入力された列の最終行数を変数で取っています。 その中で最も大きい変数の値を取るコードを記述したいのですが、 良い方法がわかりません。 sub test() Dim rcnt1, rcnt2, rcnt3, rcnt4, rcnt5, rcnt6, rcnt As Integer '最終行の取得 rcnt1 = Cells(65536, 1).End(xlUp).Row rcnt2 = Cells(65536, 2).End(xlUp).Row rcnt3 = Cells(65536, 3).End(xlUp).Row rcnt4 = Cells(65536, 4).End(xlUp).Row rcnt5 = Cells(65536, 5).End(xlUp).Row rcnt6 = Cells(65536, 6).End(xlUp).Row rcnt = "最も大きい変数の値" ←ここがわかりません。 end sub よろしくお願いします。

  • iと言う変数の値が1から10の間にないならば

    「iと言う変数の値が1から10の間にないならば」、としたいのですが どのようなコードを書けばいいのでしょうか? Sub test1() Dim i As Integer i = 11 If 1 < i < 10 Then MsgBox i & "は1から10の間にはありません" End If End Sub だと、メッセージが表示されてしまいます。

  • 全ての変数を一気にリセットする方法はありますか?

    全ての変数を一気にリセットする方法はありますか? Sub test() Dim i As Integer Dim int1 As Integer Dim int2 As Integer int1 = 1 int2 = 2 For i = 1 To 100 'プロシージャー int1 = 0 'リセット int2 = 0 'リセット Next End Sub みたいなコードがあり、 ループが終わる度に変数をリセットしたい場合 int1 = 0 'リセット int2 = 0 'リセット のように一つ一つ変数に値を入れてリセットするしかないですか? 例のコードは二つしか変数が有りますが 実際100個くらいの変数が有る場合も、 一個一個リセットするしかないのでしょうか? 理想としては、VBAを中断したら全ての変数がリセットされますが それと同じようなコードが有れば、楽だなと思います。

  • 変数の値について

    変数の値について教えてください。 VB2010 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim A As Single A = 2.0 MsgBox(A) End Sub 上記のプロシジャを実行するとメッセージボックスに2と表示され 2.0と表示しません。 2.0と表示させるには、どのようにすればよいなでしょうか。

  • ExcelVBA Static変数の初期化

    Static変数はファイルを一旦終了しないと0にリセットできないのでしょうか? 出来ないとすればStatic変数に代わりそういうことができる方法はありますか?(セルに番号を代入するのは無しで) Sub 番号てすと() Static g As Integer MsgBox "今のG= " & g g = g + 1 MsgBox "次のG= " & g End Sub

  • 静的変数の現在溜まってる値を知る方法

    Sub 静的変数() Static x As Long x = x + 10 MsgBox x End Sub このプロシージャーを実行するとXの値がどんどん加算されていきますが マクロを実行してない時にxの値を取得する方法はありますか? スッテプインやウォッチウインドウで確認すれば、マクロ実行中にxの値を確認できますが マクロを実行してない時に調べる方法があれば教えてください。 ちなみにウォッチウインドウで見てみると 値は<対象範囲外> 型はEmptyとなります。 (もしマクロを実行してなきゃわからないというのであればそれでも大丈夫です)

  • 別々の変数なのに同じ内容がセットされてしまう

    OS:Win7 Pro(32bit) VB.net:Visual Studio 2010 現在、vb.net2010を使用して、あるアプリケーションの改造を行っておりますが、 二つの別々の変数にもかかわらず、一方の変数に値をセットすると もう一方の変数にも値がセットされるという現象が発生しています。 APの構造は以下の通り(概略) Dim 変数A as list(Of cSubStr_A)(パブリック変数) Private Sub ルーチンA Dim  変数B as cSubStr_B 変数B.SubString. = 変数A.SubString(インデックス) 変数B.SubString.left = 123 End Sub 変数Aについては、他のサブルーチンなどで値がセットされています。 変数A、変数Bの配下には、leftという変数があります。 現在、変数B.SubString.left = 123が実行されたときに、 変数A.SubString.leftに対しても同じ値がセットされてしまいます。 (ステップ実行で確認) 他のプログラマが作成したものなので、 詳細は現在不明なのですが、変数Aと変数Bは別の変数なのに、 どうして変数B配下の変数に値がセットされると、変数Aに 反映されてしまうのかがわかりません。 別の人に聞いてみたのですが、変数名は違うけれど、 アドレスが同じところを見ているので、こういう現象になるのでは? という指摘がありました。 今までこういう現象にで合ったことがないので、 手がかりがつかめない状態です。 なにかヒントがあれば、お教え願えればと 思います。 以上、よろしくお願い申し上げます。

  • [ExcelVBA] Module1で定義した変数の(代入した)値を、Module2でも使う方法

    基本中の基本のことで誠に申し訳ございません。 ある標準Moduleで宣言した変数に値を代入します。 その後、別のModuleでその変数を使用しますが、 その変数の中の値が消えてしまいます。 たとえば下記のように、プログラムを書きます。 test1を実行すると、続いてtest2も実行されます。 この場合、変数の値が0になってしまいます。 このような場合どうやったらいいのでしょうか? Hensuu1の値をセルに一度出力させて、 別のModuleで、セルの値をもう一度変数に代入させて使用する という方法で何とかしていたのですが、大変で困っています。 Module1に記載------------ dim Hensuu1 as integer sub test1() Hensuu1 = 100 test2 end sub ------------------------- Module2に記載------------- sub test2 range("A1") = Hensuu1 end sub --------------------------

専門家に質問してみよう