Excel VBA Workbook_Openについて

このQ&Aのポイント
  • Excel2003VBAを勉強中の方が、UserForm1に配置したコントロールを操作するためのコードを作成しています。
  • CommandButton1を押すと、ListBox1にCドライブの「写真Sampleフォルダ」にある画像ファイル一覧が表示されます。
  • ListBox1で選択した画像ファイル名をダブルクリックすると、Image1に画像が表示されます。また、Workbook_OpenイベントでUserForm1を表示するように設定し、ユーザーが手動でCommandButton1をクリックすることなくファイル一覧が表示されるようにしたいと思っています。しかし、コンパイルエラーが発生し、どうすれば解決できるか分かりません。
回答を見る
  • ベストアンサー

ExcelVBAWorkbook_Openについて

Excel2003VBAを勉強中の者です。早速ですが質問させて頂きます。 UserForm1にTextBox1、CommandButton1、ListBox1、Image1を配置しました。 TextBox1のTextプロパティには「C:\写真Sampleフォルダ\」と入力しております。 また、Cドライブの「写真Sampleフォルダ」にはjpg画像が複数入っております。 この状態で、以下の動作を行うことが出来るコードを作ってみました。 *このコード自体は目的通りにちゃんと動きます。 ~~実行できる動作~~ ○CommandButton1を押すとListBox1に、Cドライブの「写真Sampleフォルダ」にある画像ファイル一覧が表示される。 ○ListBox1の画像ファイル一覧にあるファイル名をひとつダブルクリックして、Image1に表示させる。 ~~CommandButton1のクリックイベントのコード~~ Private Sub CommandButton1_Click() Dim FilePass As String FilePass = TextBox1.Value Dim FileName As String Dim i As Long i = 1 Dim FileDate() As Variant ReDim FileDate(1 To i) As Variant FileName = Dir(FilePass) Do FileDate(i) = FileName i = i + 1 ReDim Preserve FileDate(1 To i) FileName = Dir() Loop While FileName <> "" ListBox1.List = FileDate End Sub ~~ListBox1のダブルクリックイベントのコード~~ Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) Dim List1No As Long List1No = ListBox1.ListIndex Dim FileName As String Dim FileFullPass As String If List1No < 0 Then MsgBox "読み込むファイルを指定して下さい" Exit Sub Else FileName = Me.ListBox1.Value End If FileFullPass = Me.TextBox1 & "\" & Me.ListBox1 Image1.Picture = LoadPicture(FileFullPass) End Sub ここで更に使い易くしたく、以下の動作を追加しようと考えました。 ○ブックを開いた時に同時にUserForm1を表示する。 ○UserForm1が表示されたあとに続いてCommandButton1をクリックしなくてもListBox1にファイル一覧が表示される。 要は、ブックを開いたらListBox1に自動的に表示されたファイル名をダブルクリックするだけで画像が表示される状態にしたいのです。 そのため、ThisWorkbookモジュールに以下のコードを入力しました。 Private Sub Workbook_Open() UserForm1.Show Call CommandButton1_Click End Sub しかし、ここで「コンパイルエラー SubまたはFunctionが定義されていません。」というエラーが発生します。 そこでCall CommandButton1_Clickを消してUserForm1.Showのみにして再度実行したところUserForm1の表示だけなら上手く動作しました。 調べていくうちにフォームモジュールのコードはどうやらブックモジュールでは呼び出し出来ないのかな?と思い始めたのですが本当にそうなのでしょうか? だとすると、UserForm1がブックモジュールのUserForm1.Showとうコードで表示される事もおかしい気がしてきて分からなくなってしまいました。 なんとかしてこの動作が実行出来るようにしたく、どなたかご教示頂けます様お願い致します。

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

  • ベストアンサー
  • mar00
  • ベストアンサー率36% (158/430)
回答No.2

FilePass = TextBox1.Value となっていますが常にCドライブの「写真Sampleフォルダ」という事でいいのでしょうか。 入力して指定する為にTextBox1があるのでは? 常にCドライブの「写真Sampleフォルダ」という事であれば FilePass = Cドライブの「写真Sampleフォルダ」にして Private Sub CommandButton1_Click()を Private Sub UserForm_Initialize()にすればいいと思います。

souko3
質問者

お礼

早速のご回答有難う御座います。 早速実行してみたところ、目的の動作が出来る事を確認できました! Initializeというのは「初期化=オールクリア」に使用するのだと思っていましたが、私の考え方が間違っておりました。 凄く便利なものなんですね、間違いなく多用すると思われますので、これを機会にきっちりマスターしておきます! >常にCドライブの「写真Sampleフォルダ」という事でいいのでしょうか。 今はこの状態でいいですが、今後はボタンを付けて別フォルダを読み込む設定にするかもしれません。 しかし、試しにInitializeでコードを実行した後、更にCommandButton1に違うフォルダを指定したコードを入力して実行してみましたが、上手く動作できましたので、とりあえず問題はクリアできるかと思います。 (同じ様なコードをInitializeとCommandButton1のイベントに2つ書くのはナンセンスだとは感じておりますが、そこを突き詰めていくとDreamyCatさんのご教示にある「変数の定義」=スコープの概念をちゃんとおさえる必要があるかと思われまして、私の知識がまだそのレベルに至っておりません><) 的確なご教示のお陰で凄く便利なフォームにすることが出来ました、有難う御座います!

その他の回答 (1)

  • DreamyCat
  • ベストアンサー率56% (295/524)
回答No.1

 変数の定義で修正が必要になる部分が出るかもしれませんが private でなく public にすればcommandbuttonなどの呼び出しができます。 call UserForm1.CommandButton1_Click Public Sub CommandButton1_Click() 処理 end sub

souko3
質問者

お礼

早速のご回答有難う御座います! 内容を確認し、早速実行してみました。 ご教示の内容にある様に「変数の定義」に修正が必要なみたいで、「SubまたはFunctionが定義されていない」エラーが出てしまいました。 このエラーを回避するために変数の宣言を変えてみたり、定数にしてみたり、宣言の場所を変えてみたりとやってみましたが、理解できていない為、上手く呼び出しする事が出来ませんでした>< 折角アドバイス頂いたのに申し訳ありません。 しかし、この「変数の定義」(スコープという考え方の事だと認識しました。)というのは、かなり重要なステップであることが分かってきましたので、これから掘り下げて調べていくつもりです。 貴重なアドバイス有難う御座います。 今後もお助け頂けるととても嬉しいです! 有難う御座いました。

関連するQ&A

  • 値渡しについて

    UserForm1で以下のように求めた値「R」を UserForm2に渡すにはどのようにすればよいのでしょうか。 **************************************** <UserForm1(コード)> Public R As Integer ----------------------------------- Private Sub CommandButton1_Click()    Dim N As Integer        :    N = TextBox1.Text    R= N * 2 + 3        : End Sub **************************************** <UserForm2(コード)> Private Sub CommandButton1_Click()   Dim i As Integer       :   For i = 4 To R       :   Next i       : 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のUserFormのイベント

    VBAの公式問題集の練習をしているのですが、分からないことがあるので質問致します。 UserFormのイベントを使ってコードにマクロを作成したのですが、ユーザーフォームの実行を押しても、コンパイルエラーが表示されてしまいます。 具体的なマクロの式ですが、 Option Explicit Private Sub UserForm_Initialize() Dim i As Long TextBox1.Text = "UserFormの初期化" For i = 1 To 5 Listbox1.AddItem "Sample" & i Next i Listbox1.ListIndex = 2 End Sub です。 エラーには、コンパイルエラー: TextBox1が表示され、変数が定義されていませんと出ます。 どのようにしたらいいのでしょうか。 どなたかお分かりになるかたがいらっしゃいましたら教えて下さい。 お願いします。

  • VBAにてリストボックスに表示された文字をエクセルのセルにコピペするには

    先日、ここで教えてもらった以下の内容で、幾つかのテキストボックスに表示された内容のうち、電話番号をエクセルのセルに転記する方法が、上手くいきません。”検索"名のシート上で実行します。 過去のログを参考にしましたが、解決できませんでした。 またお世話になりますが、だれか教えてください。 Private Sub CommandButton1_Click() Dim Namae As String Dim MeNamae As UserForm Dim ken As String Namae = TextBox1.Text Set MeNamae = UserForm1 Call 検索(Namae, MeNamae) End Sub Public Sub 検索(ByVal Namae As String, ByRef MeNamae As UserForm) Dim Nagasa As Integer Dim i As Long Dim MaxRows As Long Dim kensaku As Worksheet Dim KensakuChar As String Dim ListNamae As String Dim ListChar As String Dim KBanme As Integer Dim LBanme As Integer Set kensaku = Worksheets("顧客データ") MaxRows = kensaku.UsedRange.Rows.Count Nagasa = Len(Namae) MeNamae.ListBox1.Clear For i = 3 To MaxRows ListNamae = kensaku.Cells(i, 3) KBanme = 0 LBanme = 0 Do Do While Nagasa >= KBanme KBanme = KBanme + 1 KensakuChar = Mid(Namae, KBanme, 1) If KensakuChar <> " " Then Exit Do End If Loop Do While Nagasa >= LBanme LBanme = LBanme + 1 ListChar = Mid(ListNamae, LBanme, 1) If ListChar <> " " Then Exit Do End If Loop If KensakuChar = ListChar Then If Nagasa = KBanme Then With MeNamae .ListBox1.AddItem (ListNamae) .ListBox1.List(.ListBox1.ListCount - 1, 1) = i End With End If Else Exit Do End If Loop Until Nagasa <= KBanme Next End Sub Private Sub ListBox1_Click() Dim r As Long With ListBox1 If .ListIndex > -1 Then r = .List(.ListIndex, 1) '選択した名前の行 TextBox6.Value = Worksheets("顧客データ").Cells(r, 3) 'カタカナ名 TextBox2.Value = Worksheets("顧客データ").Cells(r, 5) '漢字名 TextBox3.Value = Worksheets("顧客データ").Cells(r, 7) '住所 TextBox4.Value = Worksheets("顧客データ").Cells(r, 1) '電話番号 TextBox5.Value = Worksheets("顧客データ").Cells(r, 2) '顧客番号 End If End With End Sub Private Sub CommandButton3_Click() 'クリックすると  Worksheets("検索").Cells(, 2) ’このシートの(G2)に上記の電話番号が入力される End Sub

  • EXCEL2003 VBA リストボックス

    お世話になります。 質問の内容についてですが、 現在VBAの勉強をしながらデータベースを組んでいます。 そこで、次のようなものを作っています。 Sheet1に於いて、     A    B     C 1  追番  名称   個数 2   1   りんご   1個 3   2   みかん  2個 4   3   なし    3個 5   4   なす    5個 というような表があるとします。 そして、VBAでフォームをつくり、TextBox1(名称入力用)、TextBox2(個数入力用)、ListBox1(すでに入力されているもの及び追加分のリスト用)、CommandButton1(入力された「名称」と「個数」をSheet1の表の一番下に追加)、CommandButton2(フォームを閉じる)という構成にしています。 また、Sheet1上にコマンドボタンを作っており、そのボタンを押すとフォームを呼出すようにしています。 流れとしては、既存の表に追加する場合、コマンドボタンを押してフォームを呼出し、テキストボックスに入力した内容をSheet1の一番下に追加する。また、フォーム上のリストボックスでも現在の表の内容を見る事ができる、というものです。 フォームでのコードは以下のようにしています。 Private Sub CommandButton1_Click() If TextBox1.Value = "" Then MsgBox "「名称」は必須項目です。" End If If TextBox2.Value = "" Then MsgBox "「個数」は必須項目です。" End If If TextBox2.Value = "0" Then MsgBox "「個数」に0は登録できません。" End If Lrow = Range("B2").CurrentRegion.Rows.Count Range("B" & Lrow + 1).Value = TextBox1.Value Range("C" & Lrow + 1).Value = TextBox2.Value End Sub Private Sub CommandButton2_Click() Unload UserForm1 End Sub Private Sub UserForm_Initialize() Dim b As Long Dim a() As String ReDim a(1 To 100) UserForm1.ListBox1.ColumnCount = 2 UserForm1.ListBox1.List = Worksheets(Sheet1).Range("B2:C").Value For i = 2 To 104 If Range("B" & i) = "" Then ListBox1.AddItem Range("B" & i).Value ListBox1.AddItem Range("c" & i).Value b = b + 1 a(b) = Range("C" & i).Value End If Next i End Sub このコードでSheet1上のコマンドボタンを押して実行しようとするとエラーが出てしまいます。 エラーの原因は何なのでしょうか? (なお、コマンドボタンのコードは「UserForm1.Show」のみです。 コード自体は本などを読みながら似たようなVBAを使った物を参考にしています。

  • Excel2000 VBA シート名の変更

    なかなかうまくいかずに困っています。 Excel2000  OS:WindowsXp ユーザーフォーム(UserForm1)上に ・Textbox1 ・Textbox2 ・Commandbutton1 があります。 Commandbutton1をクリックすると、Textbox1とTextbox2の値をつなげた文字列を、 アクティブなワークシートの名前にしたいと思っています。 今現在の、うまく動かないコードは以下のとおりです。 Private Sub CommandButton1_Click() 'ユーザーフォーム上のCommandButton1 Dim snday As Variant 'Textbox1に入力される、『日』を取得するための変数 Dim snyoubi As Variant 'Textbox2に入力される『曜日』を取得するための変数 Dim namae As Variant 'シート名になる変数。 Dim Sh As Worksheet snday = UserForm1.TextBox1.Value snyoubi = UserForm1.TextBox2.Value namae = snday & snyoubi Sh.Name = namae End Sub これを実行すると、 実行時エラー’91’ オブジェクト変数または withブロック変数が設定されていません のエラーが出ます。 Sh.Name = namae のところを with ActiveSheet ~End with で挟んでみてもだめでした。 どなたかご教授ねがえませんか。 よろしくお願いいたします。

  • 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

  • VBAにてリストボックスで選択すると別ブックにあるデータを個別の窓へ表示させるには?

    はじめまして、ゴールデンウィーク中にVBAを勉強していますが、上手くいきません。内容は、「UserForm1を使って別シートにあるデーターから検索を行い、ListBox1に抽出されたリストを選択すると個別のTextBox2に関連する詳細を表示させる」というものです。別シートには「顧客データ」があり、A列より「担当、氏名、カタナカ、住所、電話番号・・・」とデーターが並んでいます。中途半端な状態ですが、これ以上進めません。だれか助けてください。 Private Sub CommandButton1_Click() Dim Namae As String Dim MeNamae As Object Dim ken As String Namae = TextBox1.Text Set MeNamae = UserForm1 Call 検索(Namae, MeNamae) End Sub '受付画面に検索画面窓を出し、顧客データから検索した結果を出すマクロ Public Sub 検索(ByVal Namae As String, ByRef MeNamae As Object) Dim Nagasa As Integer Dim i As Long Dim MaxRows As Long Dim kensaku As Object Dim KensakuChar As String Dim ListNamae As String Dim ListChar As String Dim KBanme As Integer Dim LBanme As Integer Set kensaku = Worksheets("顧客データ") MaxRows = kensaku.UsedRange.Rows.Count Nagasa = Len(Namae) MeNamae.ListBox1.Clear For i = 3 To MaxRows ListNamae = kensaku.Cells(i, 3) KBanme = 0 LBanme = 0 Do Do While Nagasa >= KBanme KBanme = KBanme + 1 KensakuChar = Mid(Namae, KBanme, 1) If KensakuChar <> " " Then Exit Do End If Loop Do While Nagasa >= LBanme LBanme = LBanme + 1 ListChar = Mid(ListNamae, LBanme, 1) If ListChar <> " " Then Exit Do End If Loop If KensakuChar = ListChar Then If Nagasa = KBanme Then With MeNamae .ListBox1.AddItem (ListNamae) End With End If Else Exit Do End If Loop Until Nagasa <= KBanme Next End Sub Private Sub ListBox1_Click() With ListBox1 If .ListIndex > -1 Then TextBox2.Value = .List(.ListIndex, 0)’←これでは何の意味も無い ' TextBox2.Value = kensaku.Cells(kensakuIndex, 3) ' TextBox2.Value = kensaku.Cells(kensaku, 3) ' TextBox2.Text = kokyaku.Hoken4 '      TextBox2.Text = kokyaku.Cells(i, 5) End If End With End Sub

  • ExcelVBA TextBoxの値を取得できない

    Excel2010です。 2つのUserFormがあり(UserForm1・UserForm2とします)、UserForm1にはTextBox1~100を配置し、UserForm2にもTextBox1~150を配置しています。 それぞれのUserFormにおいて、そのUserForm名を変数に格納しておき、TextBoxの値を取得するコードを別のプロシージャ(「TextBoxチェック」)に書き、それを呼び出してTextBoxの値を格納しようとしましたができませんでした。 該当箇所のコードは以下のとおりです。 Public UFName As String 'UserFormの名前 Sub UserForm1処理() Const Num = 100 UFName = "UserForm1" Call TextBoxチェック(Num) End Sub Sub UserForm2処理() Const Num = 150 UFName = "UserForm2" Call TextBoxチェック(Num) End Sub Sub TextBoxチェック(Num As Integer) Dim i As Integer Dim Con As Control With UserForms.Add(UFName) For i = 1 To Num Set Con = .Controls("TextBox" & i) Debug.Print Con.Name Debug.Print .Controls("TextBox" & i).Value   (その他の処理のコードは省略) Next i End With End Sub 上のコードでは1つ目のDebug.Printの結果(TextBox名)は取得できていますが、2つ目のDebug.Printの結果(TextBoxの値)は空欄になってしまいます。 つまり、 With UserForms.Add(UFName)が、 Set Con = .Controls("TextBox" & i) では反映されているのに、 .Controls("TextBox" & i).Value では反映されていないということだと思います。 また、 Debug.Print .Controls("TextBox" & i).Value を Debug.Print UserForm1.Controls("TextBox" & i).Value とすると、UserForm1の値を取得できます。 また、 With UFName_UF を With UserForm1 にすると、 Debug.Print .Controls("TextBox" & i).Value の値は取得できます。 UserForm1とUserForm2において、TextBoxの値を取得する部分は共通しているため、その部分を別プロシージャにして呼び出して処理したいのですが、うまくいきません。 TextBoxの値を取得できない理由や、対処法が分かれば教えていただきたいです。

  • テキストボックスを配置したいのですが

    以下のコードですと、失敗します。 Private Sub CommandButton3_Click() Dim nu7 As MSForms.TextBox Set nu7 = UserForm1.Controls.Add("Forms.TextBox.1", "TextBox1", True) With nu7 .Left = 20 .Top = 50 End With End Sub 間違いをご指摘頂けると、助かります。 どうぞ、宜しくお願い致します。

専門家に質問してみよう