• 締切済み

VBA ユーザーフォーム

エクセルVBAのユーザーフォームのInitializeでnに値を代入し Private Sub UserForm_Initialize() Dim n As Long n = 19 ・・・・・ End Sub 同じユーザーフォームのボタンコマンドが押されたら Private Sub CommandButton2_Click() MsgBox n Worksheets("AAA").Cells(n, 3).Value = Me.テキストボックスの値.Text n = n + 1 End Sub nの値を用いてセルにテキストボックスの値を入れるというプログラムです。 値をいれたら、nをひとつ増やして次に備えるようにしたいのですが。 そもそも最初にnの値が受け渡しできません。 ボタンコマンドの最初の行でメッセージボックスにnの値を表示して確認しても何も数字が表示されません。 nの値の受け渡しを方法を教えてください。

  • homma
  • お礼率84% (744/884)

みんなの回答

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

#1で説明つくされていると思いますが。 私もこういう件で、初心者で、手こずった経験があります。 ーー 総論として、本件はUserFormの初めのころの勉強で、やっていると思いますが、 「シートのセルの入力にuserフォームを使うのは」得策ではないと思います。多列の(多項目、多フィールドの。テキストボックスだけでなく、コンボボックスやオプションボタンなども利用した、多項目の入力を(初めての人に)本格的に必要項目の入力を全うさせるための、入力ツールを作る(チェックシステムも組み込む)ならこういう場合は、こういうことは必要ですが。) 直接シートに入力させる方が、簡潔で戸惑いがないでしょう。 本題にかえって ーーー (1)本質問は、変数のスコープという、一番VBA学習の大切かつ早く学ぶべきことと関連していると思いました。 http://excel-ubara.com/excelvba1/EXCELVBA408.htmlなど 「VBA 変数 スコープ」で照会 >上記記事内の ・シートモジュール・・・シート毎に存在します ・ブックモジュール・・・ブックで1つだけ ・フォームモジュール・・・作ったフォームの数だけ ・標準モジュール・・・好きなだけ作れます ・クラス の区分け意識は重要でしょう。 (2)Public変数の話題があります。 「VBA 変数 Public」で照会。 Public変数も弊害が出る場合もあります。 諸言語プログラムの方針の流れとしては、別モジュールに影響をできるだけ与えないような仕組みを作り、使わせる、が基本方針でしょう。Privateというのはそういう思想でしょう。 (3)モジュールレベル変数 http://tonari-it.com/public-and-call-procedure/ >「何でもかんでもモジュールレベル変数にするべきではありません。プロシージャ内で完結する変数はDimを使うようにして、どうしてもプロシージャをまたがって使いたいもののみモジュールレベル変数にしましょう」 (3)STATIC変数の話題もあります。 http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_050_04.html の「モジュールレベルの変数」のStaticの部分 (4)プロシージャ―の実行をCallで使い、前段階で決まる変数を引数に指定して、確実に渡すことを推奨している方針もあります。 ーー それとVBAではVBEのメニューのVBAのプログラムの「実行」では、「SUB/ユーザーフォームの実行」となっていて、ユーザーフォームのInitializeイベントを指定して入れておくと Private Sub UserForm_Initialize() n = 1 MsgBox n 'UserForm1.Show End Sub このnはシートの1行目を指すnとして使えるようです。 ーー また Sub test02() n = n + 1 MsgBox n End Sub のように n = n + 1 を初めの方に入れておくと、nは初期化していないのに、初めにnは1 として使えます。其の後n=n+1を使う。 これは推奨されるやり方ではないかもしれないのですが。 Ststicにしておくと、他のモジュールの部分に実行コントロールが行って帰ってきても安全でしょう。 ーー また Private Sub UserForm_Initialize() n = 1 MsgBox n UserForm1.Show vbModal End Sub の vbModalを入れておいた方が、経験では、入力中にシートのセルに誤って空白セルを作ってしまわなくてよいようです。 ーー UserFormはVBAでは有名ではありますが、解説書は少なく(Amazonで出てくるのは4本のみ。署名になっているのは技術評論社の1本のみ。他は1部分で解説は以外に多数あろう。)、貼り付けるコントロールの説明しかない本も多く、独学だと基礎的な(仕組みの)勉強に苦労します。

homma
質問者

お礼

回答ありがとうごあいました。 お礼メールが遅くなりもうしわけりませんでした。 お気づきの通り初心者です、何度もOKWEBで質問させていただき勉強している毎日です。 ただし確実にスキルはついていると感じています、今後ともよろしくおえがいいたします。

  • eden3616
  • ベストアンサー率65% (267/405)
回答No.1

変数には有効となる範囲が存在します。 今回の場合、UserForm_InitializeとCommandButton2_Clickは別のプロシージャとなります。 Dimでプロシージャ内で宣言した変数は、そのプロシージャ内でのみ有効となる変数ですので、ほかのプロシージャからは参照できません。 たとえば、Callなどで別のプロシージャに値を渡して利用するには、値渡しとして以下のように引数を指定して値を受け渡します。 Sub test1()   Dim n As Integer   n = 19   Call test2(n) End sub Sub test2(a As Integer)   msgbox a End sub 値の渡し方には、元のプロシージャの変数内容が変更される参照渡しと、値だけを渡して別の変数とする値渡しがあります。 http://officetanaka.net/excel/vba/tips/tips94.htm 今回の場合別のプロシージャで値を設定して、ボタンで値を参照するので、こちらのようにプロシージャからプロシージャを呼び出すわけではありません。 プロシージャ間で同じ変数を共有させる方法としてモジュールの先頭にて変数を宣言することで、プロシージャではなく、モジュール内共通の変数を作ることができます。 UserFormモジュールの先頭にて以下のように変数nを宣言してください。 'モジュール間で共有の変数を作成 Dim n As Long 'フォームが呼び出されたら実行 Private Sub UserForm_Initialize()   n = 19 End Sub 'ボタンがクリックされたら実行 Private Sub CommandButton2_Click()   MsgBox n   Worksheets("AAA").Cells(n, 3).Value = Me.テキストボックスの値.Text   n = n + 1 End Sub 詳しくは変数のスコープで調べてみてください。 http://officetanaka.net/excel/vba/variable/05.htm

homma
質問者

お礼

回答ありがとうごあいました。 勉強になりました。 VBAに関して初心者で、何度もOKWEBで質問させていただき勉強を重ねているところです。 今後ともよろしくお願いいたします。

関連するQ&A

  • Excel VBAで、ユーザーフォームの値を、モジュールで使用したい。

    VBA初心者です。(おそらく)基本的な質問で、申し訳ありません。 ユーザーフォーム1には、テキストボックス1とコマンドボタン1が配置されているとします。 Sub TEST () Dim N Userform1.Show MsgBox N End Sub Private Sub CommandButton1_Click() Dim N N = TextBox1.Text UserForm1.Hide End Sub Sub TESTを実行した時に、ユーザーフォーム1からNの値を引き継ぐには、どうしたら良いのでしょうか?よろしくお願いします。

  • ユーザーフォームに入力したデーターが転記できない

    いつもお世話になります。 Windows7 excell2010 です。 いろんなものに勉強してここまでに作成したユーザーフォームですが、データーは入力できるのですがコマンドボタンをクリックしても各セルに反映されません。 色々と試行錯誤していますがうまくゆきません。 どこに不具合があるかわからず恐れ入りますがどなたかご指導いただけませんか。 参考にコードは参考に下記にします。 ユーザフォームのVBAは下記です コード ※Module1 Sub 売上() Do UserForm1.Show Loop End Sub Sub 入金() Do UserForm2.Show Loop End Sub ※UserForm1 Private Sub UserForm_Initialize() With ComboBox1 .AddItem "1" .AddItem "2" .AddItem "3" End With End Sub Private Sub CommandButton1_Click() n = Cells(Rows.Count, 1).End(xlUp).Row + 1 Cells(n, 2) = UserForm1.TextBox1.Text Cells(n, 3) = UserForm1.TextBox2.Text Cells(n, 4) = UserForm1.TextBox3.Text Cells(n, 11) = UserForm1.ComboBox1.Text Unload Me End Sub Private Sub CommandButton2_Click() Unload Me End End Sub ※UserForm2 Private Sub CommandButton1_Click() n = Cells(Rows.Count, 1).End(xlUp).Row + 1 Cells(n, 2) = UserForm2.TextBox1.Text Cells(n, 3) = UserForm2.TextBox2.Text Cells(n, 4) = UserForm2.TextBox3.Text Unload Me End Sub Private Sub CommandButton2_Click() Unload Me End End Sub

  • EXCEL VBAのユーザーフォームに引数を渡す方法について

    すいません、EXCEL VBAのユーザーフォームに引数を渡す方法についてご質問があります。 シート上にコマンドボタンを2つ用意する。 コマンドボタン1を押すと変数mは1 コマンドボタン2を押すと変数mは2 としてユーザーフォームを呼び出す。 Public m As Integer Private Sub CommandButton1_Click()  m = 1  Call フォーム呼び出し(m) End Sub Private Sub CommandButton2_Click()  m = 2  Call フォーム呼び出し(m) End Sub Sub フォーム呼び出し(m As Integer)  UserForm1.Show End Sub 次にユーザフォームにコマンドボタンを1個置き、 ボタンを押したとき、mが1であれば「ボタン1」 mが2であれば「ボタン2」 とメッセージボックスを出し、ユーザーフォームを閉じる。 Private Sub CommandButton1_Click()   If m = 1 Then    MsgBox "ボタン2"   ElseIf m = 2 Then    MsgBox "ボタン2"   End If  Unload UserForm1 End Sub プロシージャ間の引数渡しは色々なテキストに載っているのですが ユーザーフォームに引数を渡す方法はどうも見つからず、 Private Sub CommandButton1_Click(m) としても、コンパイルエラーとなってしまいます。 よろしくご教示をお願いいたします。

  • エクセルユーザーフォームで困ってます。

    エクセル初心者です。 自分のユーザーフォーム(住所、商品登録)を作りたくて大変困ってます。 下記は、ネットなどをみて貼り付けたのですが、上手くいきません。 まずTOPページを作り、ユーザーフォームを呼び出すボタンを作り、クリックすると フォームが出るようにしてあります。 そこに、自分の入力したいものをユーザーフォームにテキストでつくり、シート9に 登録ボタンを作りクリックしたら、シートに反映させたいと思ってます。 登録ボタンを押したら、入力画面はクリアにしたいです。 他にいろいろやりたい事もあるのですが、入力した順番に001・002・003と顧客番号をつけたり 検索ボタンを作って、名前や、顧客番号を入れると情報を呼び出したり、請求書用のプリントシートや、封筒シートに簡単に反映できればと思っています。 しかし、まだまだそこまではいかず、最初でつまずいてます。 現状は、フォームを呼び出すときに実行時エラーがでます。 どうしても、自分の使い勝手のいいものを作りたいので どうか、助けてください。大変まいってます。 長文になりますが、どうかよろしくお願いします。 下記の入力中のものをみていただけて、いろいろ意見をいただけるとありがたいです。 Sub FormShow() UserForm1.Show End Sub 'Sheet9へ書き込む Private Sub 登録_Click() Dim i As Integer With Worksheets(9) 'テキストボックスの値を書き出し For i = 1 To 80 .Range("B" & i) = UserForm1.Controls("TextBox" & i).Text Next End With End Sub 'Formを呼び出したとき、Sheet9から読み込む Private Sub UserForm_Initialize() Dim i As Integer With Worksheets(9) 'テキストボックスの値を読み込み For i = 1 To 80 UserForm1.Controls("TextBox" & i).Text = .Range("B" & i) Next End With End Sub '終了ボタン Private Sub CommandButton2_Click() Unload Me End Sub

  • エクセルVBA

    ユーザーフォームのテキストボックスに現在時間を表示し、表示を時計のように現在時刻を表示し続ける方法を教えてください。 以下は現在のコマンドです。 Private Sub txtTime_Change() End Sub Private Sub UserForm_Initialize() UserForm1.txtTime.Value = Time End Sub よろしくお願いします。

  • 複数のユーザーフォームをコマンドボタンにて表示・非表示させるには

    VBA勉強中のものです。 複数のユーザーフォームをコマンドボタンを使用して画面への表示切替を考えております。 例)ユーザーフォーム1,ユーザーフォーム2,ユーザーフォーム3のそれぞれにコマンドボタン1,コマンドボタン2,コマンドボタン3を作成し、   コマンドボタン1→ユーザーフォーム1を表示   コマンドボタン2→ユーザーフォーム2を表示   コマンドボタン3→ユーザーフォーム3を表示 とするようなことを考えおります。  そこで、下記のようにコードを作成したのでですが,一度表示させたユーザーフォームを再度表示させようとコマンドボタンをクリックしたら、「フォームはすでに表示させているのでモーダル表示はできません」とエラーがでてしまいます。   どなたか、どのようにしたらいいかご教授ねがいます。 サンプルコード) --------------------------------------------------- 'UserForm1のコード Private Sub CommandButton2_Click() Call UserForm2_show UserForm1.Hide End Sub Private Sub CommandButton3_Click() Call UserForm3_show UserForm1.Hide End Sub ---------------------------------------------------- 'UserForm2のコード Private Sub CommandButton1_Click() Call UserForm1_show UserForm2.Hide End Sub Private Sub CommandButton3_Click() Call UserForm3_show UserForm2.Hide End Sub ------------------------------------------------------- 'UserForm3のコード Private Sub CommandButton1_Click() Call UserForm1_show UserForm3.Hide End Sub Private Sub CommandButton2_Click() Call UserForm2_show UserForm3.Hide End Sub ------------------------------------------------------------ '標準モジュール コード Sub UserForm1_show() UserForm1.Show End Sub Sub UserForm2_show() UserForm2.Show End Sub Sub UserForm3_show() UserForm3.Show End Sub

  • エクセルのユーザーフォームについて

    パスワード入力用のしかけです。 ワークシートに配置したコマンドボタンを押してユーザーフォームを呼び出します。 Private Sub CommandButton1_Click() UserForm1.Show End Sub ユーザーフォームにはテキストボックスとコマンドボタンを配置しております。 テキストボックスのPasswordCharには * を設定しました。 Private Sub CommandButton1_Click() If StrConv(TextBox1.Text, vbLowerCase) = "abcd" Then MsgBox "OK!" Unload Me Else TextBox1.Text = "" TextBox1.SetFocus End If End Sub これで、ABCDまたはabcdと入力され、ユーザーフォーム上のコマンドボタンをクリックすれば、ユーザーフォームは消えます。 でも、いちいちマウスでクリックするのが面倒なのでEnterキー1回でユーザーフォームを消したいのです。 今でも、一度Enterキーを押すと、ボタンにフォーカスが移動するので、さらにEnterで消えますが、二度ではなくEnterキー1回でユーザーフォームを消すにはどうすればよいのでしょうか? ユーザーフォームは使ったことがないのでわかりません。 よろしくお願いします。

  • VBA ユーザーフォーム

    こんばんわ。 VBA、ユーザーフォームで、ListBoxか、Comboboxで、セルの値を参照し、そこから1つ選択するようにするにはどういうコードがりますか? Private Sub Userform_Initialize   Listbox1.AddItem "700" Listbox1.AddItem "701"   ・・・・・   ・・・・・   ・・・・・ End Sub と、やると、ListBoxには反映しますが、列が多すぎて、作成するのに手間が掛かる為、例えば、"700" の値に、Sheets(1)のC2から、C500の値を入れるようなコードはありますか? 宜しくお願いします。

  • ユーザフォームのリストボックス

    お世話になります。 ユーザフォームのリストボックス内の下記2個のどちらかを選択し Private Sub UserForm_Initialize() ListBox1.AddItem ("印刷プレビュー") ListBox1.AddItem ("印刷") End Sub CommandButton1をクリックして Worksheets("Sheet1").PrintOut か Worksheets("Sheet1").PrintPreview を実行したいのですが どうやってリストボックスとコマンドボタンを 連動できるようにすればいいのでしょうか コマンドボタンのみだったら出来るのですが、 リストボックスを使うとうまくいきません。 ご教授よろしくお願いいたします。

  • EXCEL VBAのユーザーフォーム上のテキストボックスの入力方法について

    すいません教えていただきたいことがあります。 EXCEL VBAのユーザーフォームについて、 コマンドボタンにタグを設定して、これにキーボードと同じ機能を持たせて テキストボックス内に入力することは可能でしょうか。 例えばコマンドボタンを「あ」~「ん」まで作り、それぞれのボタンに「あ」~「ん」までのタグを設定する。 Private Sub UserForm_Initialize() CommandButton1.Tag = "あ" CommandButton2.Tag = "い" ・・・・「ん」までボタンを作成する。 次に、 Private Sub CommandButton1_Click() TextBox1.Value = TextBox1.Value & CommandButton1.Tag End Sub Private Sub CommandButton2_Click() TextBox1.Value = TextBox1.Value & CommandButton3.Tag End Sub ・・・「ん」まで作成する。 この設定では、コマンドボタンのクリックで文字の追加はできますが、ボタンを押すと常に文字が一番後ろに追加されるため、 テキストボックスをクリックしても文章の途中に文字を挿入することが出来ません。 通常のキーボードの入力と同じようにテキストボックス内でクリックした箇所からコマンドボタンで入力を開始するような設定は可能でしょうか。 よろしくお願いします。

専門家に質問してみよう