全てのコマンドボタンの名前を変更する方法

このQ&Aのポイント
  • フォームに乗っているコマンドボタンの名前を変更する方法について教えてください。
  • 以前の質問で解決した「オブジェクト(コントロール)の名前を変更する方法」の応用に関して詰まっています。
  • コードの実行中にエラーが発生し、エラーメッセージ「実行時エラー2465 - 指定した式で参照されている 'Controls' フィールドが見つかりません」と表示されます。問題の解決方法を教えてください。
回答を見る
  • ベストアンサー

全てのコマンドボタンの名前を変更したい

先日質問した「オブジェクト(コントロール)の名前を変更したい」 http://okwave.jp/qa/q7896863.html?by=datetime&order=DESC の応用で、 前回はDexMachina様にご回答いただいて解決したのですが今度は違う部分で詰みました。 フォームに乗っかっているコマンドボタンの名前を変更しつつ、 インデックスを付けていこうと思うのですが ************************************** Sub オブジェクト名変更() Dim ctl As Control Dim i As Long Dim f As String f = "フォーム1" i = 1 DoCmd.OpenForm f, acDesign 'デザインビューで開く For Each ctl In Forms(f).Controls If ctl.ControlType = acCommandButton Then Forms(f)!Controls(ctl.Name).Caption = i Forms(f)!Controls(ctl.Name).Name = i End If Next ctl DoCmd.Close acForm, "フォーム1", acSaveYes '保存する End Sub ************************************** のControls(ctl.Name).でエラーになります。 エラー内容は 実行時エラー2465 指定した式で参照されている’ Controls’フィールドが見つかりません。 です。 イミディエイトで?ctl.Nameして見ると コマンド0となるので問題ないと思うのですが文法がおかしいのでしょうか? Forms(f)!コマンド0.Caption にすると問題なく動作します。 ご回答よろしくお願いします。

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

  • ベストアンサー
  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.3

先日のご質問の回答者です。 18~21日は新潟の親戚宅(ネット接続環境なし)で雪下ろしの手伝いをしておりました(汗) > 指定した式で参照されている’ Controls’フィールドが見つかりません。 先日の回答で提示したURLから、更にその前へ、その前へ・・・と辿っていった先のQ&A: http://okwave.jp/qa/q7778972.html で提示したこちらのサイト: http://www.f3.dion.ne.jp/~element/msaccess/AcTipsVbaDotVsBangOperator.html に、「.」と「!」の意味の違いについての詳細な説明がありますので、時間と気持ちに余裕が あれば、目を通してみてください。 (期限を切られた業務などでは、そうもいかないことも多いかとは思いますが(汗)) 要は、   「Forms(f).Controls」と、「.」を使用した場合は、Controlsコレクション(又はプロパティ)を、   「Forms(f)!Controls」と、「!」を使用した場合は、Controlsという名前のコントロールを、 それぞれ参照していることになるため、実際に「Controls」という名前のコントロールがなければ ご質問のようなエラーになる、ということです。 ですので、既にpirion654さんから回答がある通り、構文としては   Forms(f).Controls(ctl.Name).Caption = i が正しい形となります。 また、これも既出ですが、せっかく「For Each ~ Next」により「Forms(f).Controls」のメンバを 変数「ctl」で受けているのですから、   ctl.Caption = i とした方が、(今回の例で体感できるかは別として、ですが(汗))処理速度も向上します。 (「Controls(ctl.Name)」だと、既に「ctl」として参照しているコマンドボタンを、改めてControls  コレクションの中で名前が一致するものを探すという、余計な動作をしていることになります) なお、今回のコードは動作確認用のサンプルということで簡略化されているのだとは思いますが、 コントロール名を「数字のみ」にするのは、避けた方が無難です。 (例えば、コマンドボタンの名前を「1」とした場合、VBA上では、数値の「1」と区別するために、  同コマンドボタンは「Ctl1」という形で参照する必要が生じます:  クリック時のサブプロシージャは、「Private Sub 1_Click()」ではなく「Private Sub Ctl1_Click()」  になる、と) ※更に既出の、「i = i + 1」による「同名重複の回避」もお忘れなく・・・ 【余談(前回の補足)】 > これは、該当フォームから実行してる事にはならないのですか? 「当該フォームから実行」とは、「ボタン名の変更を行うフォームのコマンドボタンのクリック時イベント などに、提示したコードを記述して実行」という意味です。 (標準モジュールにSubまたはFunctionとして記述した上で、コマンドボタンからそれを呼び出す  場合も含みます) > 要するに > Form_フォーム1 > と > Forms("フォーム1") > は別物のようですね。 はい。 「Form_フォーム1」は、VBA上で定義された「フォーム1」を参照します。 (「Form_フォーム1.Name」などを参照すると、インスタンスが生成され(≒メモリに読み込まれ)ます) 一方、「Forms("フォーム1")」は、「表示/非表示を問わず、展開済みのフォーム群を格納する Formsコレクション」から、キー(≒フォーム名)が一致するフォームを参照します。 前者は「定義」なので、同名フォームがあれば(但し『コード保持』(HasModule)プロパティが 「はい」(True)である必要あり)、いつでも参照可能ですが、 後者は「(『コード保持』の値に関係なく、展開済みのフォームを格納する)Formsコレクション」に 追加済みでない場合、参照するとエラーになる、といった違いがあります。

PVTETEJPB8
質問者

お礼

ありがとうございました。

PVTETEJPB8
質問者

補足

雪下ろし御苦労様です^^

その他の回答 (2)

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.2

No1です。 最初の部分の、 'Forms(f)!Controls(ctl.Name).Caption = i 'Forms(f)!Controls(ctl.Name).Name = i としている部分はコメントアウトしています。 したがってこの部分は使わないということです。 お間違えのないように。

PVTETEJPB8
質問者

お礼

ありがとうございました。

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.1

以下のように。 For Each ctl In Forms(f).Controls If ctl.ControlType = acCommandButton Then 'Forms(f)!Controls(ctl.Name).Caption = i 'Forms(f)!Controls(ctl.Name).Name = i ctl.Caption = i ctl.Name = i i = i + 1 End If Next ctl 以下簡単な説明。 >If ctl.ControlType = acCommandButton Then の部分でctlはフォーム1のボタンとしているので >Forms(f)!Controls(ctl.Name).Caption = i >Forms(f)!Controls(ctl.Name).Name = i ではなく、 ctl.Caption = i ctl.Name = i とします。それに >Forms(f)!Controls という参照の仕方は違います。本来は Forms(f).Controls のようにドットで参照します。 それから、iを加算しないと新たなるエラーが生じるはずです。

PVTETEJPB8
質問者

お礼

ありがとうございました。

関連するQ&A

  • フォームモジュールだとエラーになる理由は?

    http://okwave.jp/qa/q7837097.html でも質問した者ですが別の事がやりたくなってきちゃいました。 と言うのは、 ページのインデックスと同じ番号をページ名とページの表題に設定したいと思いました。 フォームにタブ0を置き、ページを5つくらいにしました。 その際、ページインデックスが0の時にページの名前はページ1になり、 ページインデックスが1の時にページの名前はページ2になり・・・ とひとつずつずれてるのを前回の質問で学習しました。 そしてさらにコマンドボタンを置いてそのコマンドボタンを押下すると ページインデックスの値を ページ名とページの表題に設定するVBAコードを作ったのですがエラーになってしまいます。 フォームモジュールに ********************************************************** Private Sub コマンド_Click() 'SetFocusメソッドはデザインビューでは使えない Dim ctl As Control Dim i As Long DoCmd.OpenForm "フォーム1", acDesign For Each ctl In Forms("フォーム1").Controls If ctl.ControlType = acPage Then Forms("フォーム1").タブ0.Pages(i).Name = "ページ" & i Forms("フォーム1").タブ0.Pages(i).Caption = i i = i + 1 End If Next ctl End Sub ********************************************************** としました。 これを実行すると Forms("フォーム1").タブ0.Pages(i).Name = "ページ" & i の部分で 実行時エラー 29054 「指定のコントロールを追加 名前の変更 または削除することはできません」 となります。 終了(E)しか選択できない状態でデバッグ(D)は選択できないです。 でも、これと全く同じコードを標準モジュールに貼り付けて実行すると問題なく動きます。 なぜフォームモジュールだとエラーになるのでしょうか? 2003でも2007でもエラーになります。 ご回答よろしくお願いします。

  • オブジェクト(コントロール)の名前を変更したい

    諸事情があり、フォーム上のコマンドボタン40個くらいの名前を変更したいのですが まず、一つだけ変更できるか実験してみたのですがうまくできません。 Sub オブジェクト名変更() DoCmd.OpenForm Form_フォーム1.Name, acDesign Form_フォーム1.コマンド0.Name = "あああ" DoCmd.Save acForm, Form_フォーム1 End Sub を実行すると メモリが不足しています。(Error 7) と出たり、 実行時エラー 29054 指定のコントロールを追加、名前を変更、または削除することはできません。 と出たりします。 これって無理って事でしょうか? バージョンは2007です。

  • Access-フォームのCaption変更

    お願い致します。 Access97のフォームのクラスモジュールでCaptionの変更を行うコードを書いたのですが、いまいちうまくいきません。 ご指導お願い致します。 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓ *********************************************** Private sub Form_Load() DoCmd.OpenForm "F_OPEN" Forms!F_OPEN!Msg.Caption="お待ちください" ************************************************ このForms!F_OPEN!Msg.Caption="お待ちください" のところで、エラーメッセージ 「'Item'メソッドは失敗しました:'Forms'オブジェクト」がでてしまうのです。 お願い致します。

  • なぜエラーになるのでしょう?アクティブコントロール

    ちょっと変なやり方かもしれないのですが、都合上こうやりたいので教えてください。 フォーム1の中にフォーム2を入れてサブフォームとして フォーム2の中にコマンドボタンを一つ置きました。 そのコマンドボタンを押した時に、そのコマンドボタン名を取得したいのですがうまくできません。 フォームは20個ぐらいあってこれと同じ動きをしたいので、 フォームモジュールには Private Sub コマンド0_Click() Call アクティブコントロール名を取得する End Sub として、 標準モジュールにコードは書いています。 Sub アクティブコントロール名を取得する() Dim フォーム As String フォーム = Screen.ActiveForm.Name MsgBox "アクティブコントロール名" & Forms(フォーム).ActiveControl.Caption End Sub にすると、オブジェクトは、このプロパティまたはメソッドをサポートしていません。(Error 438)になります。 そもそも、フォーム = Screen.ActiveForm.Nameの時点で、フォーム1になっています。 実際のコマンドボタンはフォーム2にあるのに。 なので、無理矢理 MsgBox "アクティブコントロール名" & Forms("フォーム2").ActiveControl.Caption にしたら、 実行時エラー2450 マクロの式またはVisualBasicコードで参照されている'フォーム2'が見つかりません。 という違うエラーになりました。 Sub アクティブコントロール名を取得する() Dim フォーム As String フォーム = Screen.ActiveForm.Name Forms("フォーム2").SetFocus MsgBox "アクティブコントロール名" & Forms("フォーム2").ActiveControl.Caption End Sub にすればいいのかな?と思ったら Forms("フォーム2").SetFocusでアウトでした。 もともとはサブフォームのコントロールから発信したイベントなのに、 サブフォームのコントロールの値が取れないのでしょうか? 実際のmdbファイルではコマンドボタンではなくテキストです。 ご回答よろしくお願いします。

  • アクセス For Eachの時点 絞る

    For Eachの時点で、コマンドボタンのみに絞ることは可能ですか? Sub Sample() Dim myFormName As String Dim ctl As Control myFormName = "フォーム1" For Each ctl In Forms(myFormName).Controls Debug.Print ctl.Name Next ctl End Sub これでフォーム上の全てのコントロール名を取得できますが ループの時点でコマンドボタンのみを抽出できますか? For Each ctl In Forms(myFormName).Controls If ctl.ControlType = acCommandButton Then Debug.Print ctl.Name End If Next ctl こうすれば、コマンドボタンのみ絞れますが コントロールの数が多すぎて、処理に時間がかかります。 なので For Each ctl In Forms(myFormName).Controls の部分の、ループの時点でコマンドボタンを絞りたいのですが 絞れる方法があれば教えてください。

  • フォーム上のコントロールの名前を配列に格納したい

    アクセスです フォーム上のコントロールの名前を配列に格納したいのですが もっとスマートな方法はありますか? 私が考えたコードは Dim avarContorol As Variant Dim ctl As Control Dim mystr As String For Each ctl In Forms(Me.Name).Controls mystr = mystr & ctl.Name & "," Next ctl '右から1文字消す mystr = Left(mystr, Len(mystr) - 1) avarContorol = Split(mystr, ",") なのですが、 ループのみで格納できる方法があれば教えてください。

  • フォーム上のすべてのコマンドボタンの名前を取得

    エクセルvbaでフォームを開く時に、フォーム上のすべてのコマンドボタンの名前を取得したいのですが、 コードがわかりません。 Private Sub UserForm_Initialize() Dim objcmd As Object For Each objcmd In Me.ActiveControl Debug.Print objcmd.Name Next だと、Me.ActiveControlでエラーになります。 適切なコードを教えてください。

  • {アクセス}全てのフォームの名前を取得したい

    ひとつのMDBファイルに入っている全てのフォームの名前を取得したいのですが Sub 全てのフォームの名前を取得() Dim i As Integer For i = 1 To Forms.Count Debug.Print Forms.Name Next End Sub このコードだと オブジェクトは、このプロパティまたはメソッドをサポートしていません。(Error 438) となってしまいます。 どうすればいいでしょうか よろしくお願い致します。

  • コントロールを削除すると、一つ飛ぶ アクセス

    こんばんは。よろしくお願いします。 フォーム上のイメージを削除してるのですが Sub test() Dim ctl As Control Dim FormName As String FormName = "フォーム2" DoCmd.OpenForm FormName, acDesign For Each ctl In Forms(FormName).Controls If ctl.Name Like "イメージ*" Then Debug.Print ctl.Name DeleteControl FormName, ctl.Name End If Next ctl End Sub これをすると、コントロールが一つ飛ばされます。 イミディエイトウインドウで値を確認すると イメージ0 イメージ2 イメージ4 になりました。 1、3、5が飛ばされました。 実行結果は画像のような感じです。 なぜ飛ばされちゃうのでしょうか? 普段、For Each ctl In Forms(FormName).Controlsを使う分には値が飛ばされる事はないので DeleteControl FormName, ctl.Nameが原因だと思うのですが、 全ての「イメージ」で始まるコントロールを削除したい場合、どうすえばいいですか?

  • VBAでタブのページを削除するには?アクセスです

    フォームにタブコントロールを置いて、ページを6つにして、コマンドボタンを置きました。 3から6ページをVBAで削除する事は可能でしょうか? (1・2は残したいです) 「ページを削除する」というVBAコードがわかりません。 Private Sub コマンド7_Click() Dim ctl As Control For Each ctl In Forms(Me.Name).Controls If ctl.ControlType = acPage Then Debug.Print ctl.Name 'ここでページを削除したい End If Next ctl End Sub あと、もしかしてデザインビューでないと削除できないですか? であれば、DoCmd.OpenForm Me.Name, acDesign を追加しようと思っています。 ご回答よろしくお願いします。

専門家に質問してみよう