• 締切済み

【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」の値が保持できる、 何かしらの方法はないでしょうか。 回答をよろしくお願いします。

みんなの回答

  • ap_2
  • ベストアンサー率64% (70/109)
回答No.1

UserFormやシートの「コード」は、自動生成される「オブジェクト」の内に埋め込まれます。Public宣言した変数・関数は、グローバルではなく、オブジェクトのパラメータ・メソッドになります。  UserForm1.Show 'Public関数  z = UserForm1.cancel 'Public変数  z = Sheet1.hoge 'シートの場合 逆に、標準モジュールにPublicで定義すればグローバル変数となり、UserForm内からでも = cancel でアクセスできます。が、こーいう変数はUserForm内に閉じたいですよね。

doramoku
質問者

お礼

回答ありがとうございます。 返信が、かなり遅くなってしまい本当に失礼しました。

関連するQ&A

  • VBAでマルチページの表示

    エクセル2002使用です。 ユーザーフォーム(オブジェクト名:UserForm1)に、マルチページ(オブジェクト名:page1)を配置してフォームを作成しました。 Sheet1にコマンドボタンを貼り付け、コマンドボタンをクリックして、標準モジュールを呼び出し、マルチページを標準モジュールから呼び出せるようにしたいのですがうまくいきません。 ’Sheet1 Private Sub CommandButton1_Click() Call フォーム表示 End Sub ’標準モジュール Sub フォーム表示() UserForm1.Show ’?ここのコードをいろいろ試したのですがわかりません。 End Sub この他 UserForm1.ShowPages "page1" とか 変数を入れてみたりしたのですが、うまくいきません。 すいませんが、よろしくお願いします。

  • 再度,ExcelVBA,public変数が消える

    大変申し訳ありません。一度、この件で質問し、その回答を締め切ったばかりなのですが、やはりもう少し知りたくて質問させていただきます。 ある方の回答への補足で、以下のマクロを具体例としてあげました。ただし、以下のマクロは、時にはpublic変数が消えてしまいますが、しかし、消えないこともあります。 消える理由として、 回答していただいたものから考えて、 1.End Sub を通っていないままに終了しているから 2.不完全なマクロ 3.きちんと作られたマクロの流れ(ルーチン)ではない流れがある 4.「Public 変数は、標準モジュールを経由して、ローカルのUserForm に供給、しかし、それを戻すということはしない。つまり、a.ローカルで発生した値 →標準モジュールのPublic 変数 →UserFormのローカルのプロシージャ b.標準モジュールのPublic 変数 → UserFormのローカルのプロシージャ   ※ただし、起動時の一回きり、それ以上の持ち回しはしない。逆もしない。」この件に関して、以下のマクロに問題がある。 この様なことを考えました。 4.の場合、testMainからtest1.showを呼び出し、a=10とするが、このaの値は、testMainには戻らない(戻らないことがある)のでしょうか、あるいは、testMainのend sub の後は値が保障されないのでしょうか。 あるいは、 Worksheet_SelectionChange でend sub で終わっているので、それ以降は値が保持されないのでしょうか。 あるいは、どこかに欠陥のあるマクロなのでしょうか。 http://okwave.jp/qa/q6420530.html への回答のno.6の例のマクロでendをコメントにするかしないかで、endをコメントにした場合はend subで終わった後、値が保持されています。このこととも合わせて考えると、どこに問題があるのか、どのような問題があるのか、よく分からなくなってしまいます。 よろしくお願いします。 標準モジュールにーーーーーーーーーーーーーーーーー 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

  • VBA 標準モジュールとフォーム

    ある標準モジュール内で生成した変数の値をフォームのコマンドボタンをクリックしたら表示されるプログラムはどうやってつくるのですか? 標準モジュール sub test() dim a as integer dim b as integer dim sum as string a=5 b=1 sum=a+b End sub フォームのコマンドボタンクリック Sub CommandButton1_Click() MsgBox sum End Sub 標準モジュールで計算した答えがフォームのコマンドボタンをクリックしたら答え6が表示されるようにしたいのですが、どうしたらできますか?

  • subプロシージャーは標準モジュールではなくフォームのコードを書く部分

    subプロシージャーは標準モジュールではなくフォームのコードを書く部分に書いても問題ないのでしょうか? エクセルにVBAでフォームを挿入し、 「Private Sub UserForm_Initialize()」 などのフォームのモジュールに、 Sub test() MsgBox "あああ" End Sub という標準モジュールに書くべきのsubプロシージャーを書いてもなにもエラーにならないし正常に動きます。 subプロシージャーは標準モジュールではなくフォームのコードを書く部分に書いても問題ないのでしょうか? それともエラーにならなくても標準モジュールに書いた方がいいですか?

  • エクセルVBA イベントプロシージャに引数を渡せま

    お世話になります。 エクセル2003/XP 使用です。 イベントプロシージャに引数を渡せまるかどうか教えていただけますでしょうか? 下記のコード中の変数mysheetnameを ユーザーフォーム、→ CommandButton1のプロシージャに 引数として渡して行きたいのですが、 実行すると、一番最初のWorkbook_SheetBeforeRightClickの時点で、 コンパイルエラー:  プロシージャの宣言が、イベントまたはプロシージャの定義と一致していません。 とエラー表示されます。 イベントプロシージャに引数を渡すことはできますでしょうか? ---------- ThisWorkBook内 ---------- Public mysheetname As String Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) mysheetname = ActiveSheet.Name UserForm1.Show (mysheetname)     '←変数mysheetnameの値をユーザーフォームに渡したい。 End Sub ---------- ユーザーフォーム ---------- Private Sub UserForm_Initialize(ByVal mysheetname As String ) 処理 End Sub Private Sub CommandButton1_Click(ByVal mysheetname As String ) 処理 End Sub ’--------- ここまで 引数について少し理解し始めたばかりの者です。 よろしくお願いします。

  • (VBA)ユーザーフォームの値を、モジュールで使用

    ユーザーフォームを使用したく UserForm1に以下を配置 TextBox1 TextBox2 CommandButton1 CommandButon1に以下のコード書き込みました Private Sub CommandButton1_Click() Dim N As Single Dim M As Single N = UserForm1.TextBox1.Text M = UserForm1.TextBox2.Text Unload UserForm1 End Sub 標準モジュールに以下を記載して ユーザーフォームの値を、モジュールで使用したいのですが [「M=~」で型が一致しません(エラー13)がでます。 「M=~とN=~」 を削除すると MsgBoxの値がM,Nともにゼロになります Public M As Single Public N As Single UserForm1.Show 1 M = UserForm1.TextBox1.Text     ----> ここでエラー13 N = UserForm1.TextBox1.Text MsgBox M MsgBox N ------------------------------ どこでコードが間違っていますか ?

  • エクセルVBAユーザーフォームの変数の設定方法について

    すいません、エクセルVBAのユーザーフォームの変数の設定方法について質問があります。 1 ユーザーフォームを2つ用意する。 2 それぞれにComboBox1をおく。 3 立ち上げたユーザーフォームについて、UserForm_InitializeでComboBox1に"a"のAddItemを作る。 この、「立ち上げたフォームのComboBox1に"a"のAddItemを作る」 という作業を各々のユーザーフォームに記載するのではなく、標準モジュールでまとめて記載する方法で躓いています。 Public m As String Private Sub UserForm_Initialize() ’フォーム1を立ち上げた場合   m = "UserForm1"   Call Test1(m) End Sub Private Sub UserForm_Initialize() ’フォーム2を立ち上げた場合   m = "UserForm2"   Call Test1(m) End Sub ↓ 標準モジュールに記載 Sub Test1(m As String) VBA.UserForms.Add(m).ComboBox1.AddItem "a" End Sub これだとUserForm_InitializeとTest1の間で無限ループが始まってしまい、うまく進んでくれません。 ヘルプを見ましたが、Add(変数)でユーザーフォームを変数で指定できるということ以上のことは発見できず行き詰っています。  それぞれのフォームに書けばいいだけの話なのかもしれませんが、メンテを考えると出来ればまとめて記述しておきたいと考えています。 解決方法がありましたらどうぞよろしくご教示願います。

  • VBAのプロパティウィンドウについて

    VBAでプロパティウィンドウには ・Microsoft Excel Object ・フォーム ・標準モジュール があります。 ところで、下のプログラムですが、(1)の部分を標準モジュールに書き込み、フォームにあるコマンドボタンをクリックしたら、"test.xls"が表示されます。 しかし、(1)の部分をMicrosoft Excel Object のsheet1(sheet1)のコードに書き込み、プログラムを実行させると、フォームのコマンドボタンをクリックしても"test.xls"は表示されません。 これはなぜですか? (1)の部分のコマンドボタン1はsheet1に存在します。 (1)----------------------------------- Private file_name as string Private Sub CommandButton1_Click()   file_name="test.xls" UserForm1.Show End Sub (1)----------------------------------- フォーム Sub CommandButton1_Click() MsgBox file_name End Sub

  • VBA 標準モジュールとフォーム (続き)

    先ほど、同じ質問タイトルで質問させていただいたものです。この場合どうなりますか? モジュールでの変数file_nameをフォームのボタンをクリックしたら"text.xls"が表示されるようにしたいです。 (イメージとしては、エクセルのsheet1にコマンドボタンがあってクリックするとフォームが立ち上がってフォームのコマンドボタンをクリックすると"test.xls"が表示される) モジュール Private Sub CommandButton1_Click() ←エクセルsheet1にボタンがある   dim file_name as string file_name="test.xls"   UserForm1.Show End Sub フォーム(UserForm1) Sub CommandButton1_Click() ←フォームにボタンがある MsgBox file_name End Sub

  • エクセルマクロユーザーフォームのtxtbox値を標準モジュールに保持

    宜しくお願いします。 ユーザーフォームのtxtbox値を標準モジュールに渡してマクロを実行 るのですが、一度値をセットしたら20~30回変更が無いので標準モジュール のみショートカットで実行したいのですが値を保持してくれません。 何か良い方法は無いのでしょうか。? 'フォーム起動 Sub フォーム() UserForm1.Show End Sub +++++++++++++++++++++++++++ Private Sub CommandButton1_Click() Call モジュール '標準モジュールを呼ぶ Unload UserForm1 ++++++++++++++++++++++++++ モジュール内 Static ufX As Byte ufX = UserForm1.XXX.Text 'ufXの値を保持したい。

専門家に質問してみよう