VBAについて。Excelの2003や2007を使っています。標準モジュールで public 変数を定義しました。 ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。全く同じマクロで、この現象が起こることと、起こらないことがあります。excelの2003でも2007でも、同じ現象が起こります。簡単なマクロで再現性のある具体的なものを示したいと思い、試しましたが、できませんでした。簡単なマクロでは、きちんとパブリック変数は保持されています。問題のあるマクロはかなり長いものなので、とても示せません。問題がどこにあるのかわかりません。このマクロで不都合があるという具体的なマクロを示すことができない状態での質問で、申し訳ありません。
また、このようなプログラミングをしていて思ったのですが、ユーザーフォームに対してユーザーが任意の引数を渡す方法あるいは、ユーザーフォームから引数を受け取る方法はあるのですか?今は、pubulic変数を用いたり、具体的なセルに値を代入したりしていますが、どう考えてもそれはエレガントではないし、汎用性もないと思います。引数で引き渡すのが一番綺麗でいいとは思うのですが、それが可能かどうかわかりません。
No.4ベストアンサー
- 回答日時:
IDは違うけれども、同じ内容の質問のようですね。
http://oshiete.goo.ne.jp/qa/6420530.html
具体的にこんなことをしています、ということをおっしゃれば、話は変わるかとも思います。
今のままでは、いくら説明しても、たぶん納得いかないだろうと思います。
最初に、#3の方のMSのサポートの文章で、
>[VBA] Public 宣言された変数の有効期間
この内容、ご質問者さんは、意味を誤解しているようです。
「ほとんどの場合、プロシージャ終了後も値は保持されますが、
……Public 変数がアプリケーション終了時まで有効であること
を期待する VBA マクロの実装は、推奨されません。」
どうして、保持した変数がなくなってしまうか、いろんな理由はあっても、完成したマクロでは、原因はひとつで、End Sub を通っていないままに終了しているからです。
「ある Office ドキュメントが VBA のマクロを含む場合、…… Public 変数
の値が有効である期間は、あるプロシージャの実行を開始
し、そのプロシージャが "End Sub" で終了するまでの間のみです。」
この文章は間違いです。その話のままだったら、Public 変数など意味がなくなってしまいます。値だって確保しているし、変数は動的です。しかし、実務上、構造化マクロで、きちんと作られたマクロの流れ(ルーチン)が通る間だけだと思ってよいです。
>ユーザーformを使い、パブリック変数に値を入れたり変更し、標準モジュールに戻ったとき、そのpabulic変数が resetされてしまっている事があります。
Public 変数が、リセットされるというのは、マイクロソフトの文章は間違いに近いです。これは、極論すると、不完全なマクロだということです。しかし、本当に完全なコードを提供出来るかというのは、それは誰も自信などありません。だから、そういう方法を避けるわけです。
Public 変数は、標準モジュールを経由して、ローカルのUserForm に供給を受けるけれども、それを戻すということはしないのです。
図式化するとこうなります。
・ローカルで発生した値 →標準モジュールのPublic 変数 →UserFormのローカルのプロシージャ
・標準モジュールのPublic 変数 → UserFormのローカルのプロシージャ
※ただし、起動時の一回きり、それ以上の持ち回しはしない。逆もしない。
「ユーザーフォームに対してユーザーが任意の引数を渡す方法
ユーザーフォームから引数を受け取る方法はあるのですか?」
出来ないわけではありませんが、これらは、変数で渡すということはしないということです。
>ただ、ユーザーフォーム aUS 全体で参照し値を変更できる 変数a のようなものを、使えたらいいなあ、と思い、
理屈では、一旦、標準モジュールのPublic 変数に送っておいて、そこから他のプロシージャ等に送ればと思いますでしょうが、それはしないということです。ルーチンが別だからです。
私の基本的な設計の考え方を示しておくと、UserForm自身とか、その中にあるものは、OLEオブジェクトのインスタンスです。つまり、モノ(オブジェクト)がある限りは、値は確保しているのです。だから、UserFormが残っている以上は、変数ではなくて、モノから、値を取得するのです。そのためには、UserForm はModalモードを、Offにしておくのが良いわけです。
例えば、UserForm1.TextBox1.Value とかで取れるわけです。
これは、システム設計の話で、それを見れば分かっていただけます。非表示のワークシートのセルに書くような話は、それは状況(渡す変数の数)によります。ただ、わざわざワークシートのセルに代入する必要はないということです。そのような方法はシステム設計では全体にリスクを高くするので賛成出来ないです。
私の失敗の経験から、Public 変数については、ひとつのルーチン以上に用いないことです。また、動的には用いないことです。一回きりの静的な変数として使うべきです。静的といっても、Static 変数の意味ではなく、文字通り変数を変化させないということです。ただし、時間の間隔やカウントなどの単純なものは別です。
Public 変数が空かどうかチェックする方法も考えられますが、意味がありませんから、それなら、参照渡しにすればよいのです。
この回答への補足
詳しい説明をありがとうございました。とっても役に立ちました。
>私の失敗の経験から、Public 変数については、ひとつのルーチン以上に用いないことです。また、動的には用いないことです。一回きりの静的な変数として使うべきです。静的といっても、Static 変数の意味ではなく、文字通り変数を変化させないということです。ただし、時間の間隔やカウントなどの単純なものは別です。
これからは、これを心がけたいと思います。
>理屈では、一旦、標準モジュールのPublic 変数に送っておいて、そこから他のプロシージャ等に送ればと思いますでしょうが、それはしないということです。ルーチンが別だからです。
この部分もとっても参考になります。
こちらも見ました。
http://oshiete.goo.ne.jp/qa/6420530.html
endの部分の違い(コメントかそうでないか)により結果の違いはとても勉強にないました。
ありがとうございました。
No.5
- 回答日時:
たぶん、質問者さんには理解して頂けたと思うのですが、
念のため解説しときます。
Office の VBA はドキュメントに付随しています。
Excel の場合ですと、ワークシートにプログラムが付随しています。
このワークシートというのは、手動でもプログラムからでも追加/削除ができます。
つまり、プログラム自体が変更される可能性があるということです。
プログラムが変更されたらリセットして再コンパイルする必要がありますが、
プログラム実行中にそんなことされたら、堪りませんよね。
それで、プロシージャ実行中は保証します、という仕様になっています。
プロシージャ実行中にプログラムが変更されたと判断されたら、
終了後にリセットする、ということです。
この回答への補足
度々ありがとうございます。
>Excel の場合ですと、ワークシートにプログラムが付随しています。
確かにいわれてみれば当たり前ですが、今まであまり、今回のような件で意識したことがありませんでした。こういう視点が大切だと気付かされました。
ありがとうございます。
No.3
- 回答日時:
> > そのpabulic変数が resetされてしまっている事があります。
> Excel の仕様です。どうしようもありません。
>
> > 具体的なセルに値を代入したりしていますが
> それが確実な方法です。
情報源です。
http://support.microsoft.com/kb/408871/ja
この回答への補足
情報源見ました。
「ある Office ドキュメントが VBA のマクロを含む場合、その中のモジュールに記述された Public 変数の値が有効である期間は、あるプロシージャの実行を開始し、そのプロシージャが "End Sub" で終了するまでの間のみです。
ほとんどの場合、プロシージャ終了後も値は保持されますが、意図しないタイミングで保持されていた Public 変数の値が破棄され、使えていた変数の値が突然使えなくなる場合があります。そのため、Public 変数がアプリケーション終了時まで有効であることを期待する VBA マクロの実装は、推奨されません。」
本当にビックリしました。public変数のスコープがプロシージャのend sub までだけだなんて。それならばとても「public」とは言えませんよね。またそれに対して、の対処法が
「Excel の場合 非表示にしたワークシートに値を記述します。」
というのも拍子抜けです。それはすでにやっています。
本当にありがとうございました。自分の技術や知識のなさのために起こっていたと思っていた現象が、excelの仕様だなんて。しょうがないので、これから「非表示にしたワークシートに値を記述」する形に変えます。
せめて早く、public変数の仕様を変え、少なくとも「Public 変数がアプリケーション終了時まで有効」にして欲しいですね。
No.2
- 回答日時:
このようにコードも掲示できない(しない)場合に、このコーナーに質問しても無駄だと思いませんか。
読者は質問者のパソコンのコードも実行したり、多少変えて実行したりも出きずに、エラー原因の究明などできるわけが無い。
よほど典型的なエラーコードが出ている場合をのぞいて、このコーナーはデバッグの質問には適さない。
それなのに、エラーの原因の質問が出る。自分で究明するほか無いでしょう。この面では他人を当てにしないこと。
1つの提案はMsgbox (Public変数名)を要所要所に入れて実行してみて、何処で予想外に変化するか、見極めることは出来るのでは無いですか?
こんなこともやってみましたか。
パブリック変数にもスコープ的なな考えは必要と思うので
http://pc.nikkeibp.co.jp/pc21/special/2007_gosa/ …
などをよく読んで考えてみてください。
>ユーザーフォームに対してユーザーが任意の引数を渡す方法あるいは、ユーザーフォーム・・
は、こんな抽象的な書き方でなく、具体的にどういう場合に、どういうことをしたいのか書いて質問すべきだ。
http://oshiete.goo.ne.jp/qa/5160575.html
の質問などあるが、ユーザーフォームに引数を渡す場合と言えるのかどうか?
ーー
私は不勉強で、回答の>pabulic変数が resetされてしまっている事があります。ーー>Excel の仕様です。の具体例は想像できません。
ーー
>pabulicはPublicのミスタイプです。プログラマーとしては、コード内に、こういう誤りは無いですか。
この回答への補足
以下のマクロでも、時にはpublic変数がresetされてしまいます。しかし、resetされないこともあります。 一度resetされると、ずーっとresetとされます。また、立ち上げ直したりして、resetされないと、これもまたずーっとresetされずに正常に動きます。どういうときにうまく動き、どういうときにうまく動かないのか、分かりません。resetされるタイミングはtest1というフォームから戻ったときです。(ミスタイプは本当に申し訳ありません。publicと打ったりパブリックと打ったりして、急いで打ったためゴチャゴチャになってしまいました。)
標準モジュールにーーーーーーーーーーーーーーーーー
Option Explicit
Public a As String
Sub ini()
MsgBox "初期化します"
a = "5"
End Sub
Sub testMain()
If a = "" Then ini
MsgBox a
test1.Show
End Sub
test1 というフォームのモジュールにーーーーーーーーーーーーーー
(このフォームに コマンドボタンがあります。)
Private Sub CommandButton1_Click()
a = "10"
Unload Me
End Sub
シートのモジュールにーーーーーーーーーーーーーーーーー
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
testMain
End Sub
No.1
- 回答日時:
> そのpabulic変数が resetされてしまっている事があります。
Excel の仕様です。どうしようもありません。
> 具体的なセルに値を代入したりしていますが
それが確実な方法です。
> 引数で引き渡すのが一番綺麗でいいとは思うのですが
ケースバイケースです。
> ユーザーが引数を渡す
意味が分かりかねます。
この回答への補足
ありがとうございます。excelの仕様なのですか。ショックです。その場合どうしようもできないのですね。
public変数の意味がないような気がします。ただ、回答の2の方によると、そうでもないのようにも感じます。ますます分からなくなってしまいました。
後半の部分の質問が、下手な説明で申し訳ありません。
例えば、ユーザーフォーム aUS の中で、変数 a を使うとします。しかしその同じ変数を sub bSB でも function cFC でも使うとします。その場合、sub や function では bSB(a) や cFC(a) とか a= cFC などの形で 引数の引き渡しができます。しかし、ユーザーフォームでは、textboxとかcheckboxとか具体的なコントロールが配置され、例えばそれぞれがクリックされたときの処理とかをVBAで書くことができます。その時に例えば標準モジュールでpublic変数のようにあちこちで参照できるようなことができないかと考えたのです。感覚的にいえば、ユーザーフォーム aUS(a) とaを引数とするような感覚です。もちろん、aUS(a)とはできませんよね。ただ、ユーザーフォーム aUS 全体で参照し値を変更できる 変数a のようなものを、使えたらいいなあ、と思い、そしてそのaを標準モジュールのsubやfunctionの間でやりとりができないのかなあ、と考えたのです。つまりユーザーフォームaUSに対し 引数a を引き渡す感じのことができないか、と考えたのです。そして、このようなことが私の知識ではできなそうなので、public変数を使いました。しかし、それがうまくいかなかった。また、public変数の数は少ない方が見通しのいい、ミスの少ないプログラムになると感じたので。また、変数はどこでどう使うかを限定した方がいいと思うので。どうなのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) マクロについて教えてください。 4 2023/06/06 09:06
- Excel(エクセル) ユーザー関数の自動計算(excel2003) 1 2023/02/06 06:46
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
- Excel(エクセル) マクロだと数式が表示される 2 2022/09/10 14:48
- 情報処理技術者・Microsoft認定資格 MOS試験Excelエキスパートを受けようか考えています。 Excelは仕事で使用。 関数は入れ子含 2 2022/12/18 10:05
- Excel(エクセル) フォルダ内の全ブックのシート名を変更したい 7 2022/09/22 21:34
- Visual Basic(VBA) vba メモリ節約 3 2022/09/16 21:45
- Excel(エクセル) マクロVBA別Excelブックにデータ転記 2 2022/07/10 23:35
- Visual Basic(VBA) vbaエクセルマクロについて あるデータを作成し、デスクトップに.xlsx形式で保存するマクロを作成 2 2023/03/02 18:54
- Excel(エクセル) 【Excel】指定のセル内容を基に別シートのセルを検索して選択する【VBA】 1 2022/06/16 16:16
このQ&Aを見た人はこんなQ&Aも見ています
-
見学に行くとしたら【天国】と【地獄】どっち?
みなさんは、一度だけ見学に行けるとしたら【天国】と【地獄】どちらに行きたいですか? 理由も聞きたいです。
-
「平成」を感じるもの
「昭和レトロ」に続いて「平成レトロ」なる言葉が流行しています。 皆さんはどのようなモノ・コトに「平成」を感じますか?
-
「覚え間違い」を教えてください!
私はかなり長いこと「大団円」ということばを、たくさんの団員が祝ってくれるイメージで「大円団」だと間違えて覚えていました。
-
2024年のうちにやっておきたいこと、ここで宣言しませんか?
2024年も残すところ50日を切りましたね。 ことしはどんな1年でしたか? 2024年のうちにやっておきたいこと、 よかったらここで宣言していってください!
-
【大喜利】【投稿~12/6】 西暦2100年、小学生のなりたい職業ランキング
【お題】 ・西暦2100年の「小学生のなりたい職業ランキング」で1位になった職業は何か教えてください
-
excel/vba/public変数
その他(Microsoft Office)
-
VBA public変数はどのようなことをしたら解放されますか?
Visual Basic(VBA)
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
-
4
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
5
再度,ExcelVBA,public変数が消える
Visual Basic(VBA)
-
6
Application.ScreenUpdating = Falseが効きません
Visual Basic(VBA)
-
7
VBA たまに変数がempty値になるエラー
Excel(エクセル)
-
8
VBAで別モジュールへの変数の受け渡し方法
Visual Basic(VBA)
-
9
VBAでループ内で使う変数名を可変にできないか。
Visual Basic(VBA)
-
10
VBA 変数名に変数を使用したい。
Visual Basic(VBA)
-
11
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
12
EXCEL VBAで全選択範囲の解除
Excel(エクセル)
-
13
VBA シートのボタン名を変更したい
Visual Basic(VBA)
-
14
VBAのコマンドボタンの文字列の改行方法は?
Visual Basic(VBA)
-
15
エクセルVBAでシートモジュールでのパブリック変数
Excel(エクセル)
-
16
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
17
UserForm1.Showでエラーになります。
工学
-
18
全ての変数を一気にリセットする方法はありますか?
PowerPoint(パワーポイント)
-
19
ユーザーフォームに入力したデータを保持する方法
Visual Basic(VBA)
-
20
EXCEL VBA セルに既に入力されている文字に文字を追加する
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~12/6】 西暦2100年、小学生のなりたい職業ランキング
- ・ちょっと先の未来クイズ第5問
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで特定の列が0表示の場...
-
UWLSの記録でマクロを作成し使...
-
一つのTeratermのマクロで複数...
-
Excel マクロ VBA プロシー...
-
Excel_マクロ_現在開いているシ...
-
Excel マクロでShearePoint先の...
-
エクセルに張り付けた写真のフ...
-
ExcelのVBA。public変数の値が...
-
特定のPCだけ動作しないVBAマク...
-
[初心者です]VBAで指定列か...
-
Excel・Word リサーチ機能を無...
-
VBA アドインについて お詳しい...
-
Excel 改ページのVBAうまくい...
-
Excelで特定の文字のところで自...
-
VBAにて別ワークブック上の実行...
-
エクセルVBA イベントプロシー...
-
P.W.でシート保護されている行...
-
Excel VBAからAccessマクロを実...
-
エクセルで別のセルにあるふり...
-
Libre office マクロ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excel・Word リサーチ機能を無...
-
特定のPCだけ動作しないVBAマク...
-
エクセルで特定の列が0表示の場...
-
Excel マクロ VBA プロシー...
-
メッセージボックスのOKボタ...
-
一つのTeratermのマクロで複数...
-
エクセルに張り付けた写真のフ...
-
ExcelのVBA。public変数の値が...
-
Excel マクロでShearePoint先の...
-
TERA TERMを隠す方法
-
ExcelVBAでPDFを閉じるソース
-
Excel VBAからAccessマクロを実...
-
Excel_マクロ_現在開いているシ...
-
マクロ実行時、ユーザーフォー...
-
エクセルで別のセルにあるふり...
-
ソース内の行末に\\
-
特定文字のある行の前に空白行...
-
マクロで空白セルを詰めて別シ...
-
wordを起動した際に特定のペー...
-
【EXCEL VBA】オートシェイプを...
おすすめ情報