• ベストアンサー

VBAのコントロールなんかをコレクションとして扱える?

フォームに複数のコントロールを配置したときにその選定によって条件分岐やイベント処理を行いたいときに同じようなコードを羅列する必要が生じました。コントロールをコレクション?(もしかして?クラス?<クラスは全く解っていません>)として、一くくりに扱う方法ってありますか? ご指導のほどよろしくお願いいたします。

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

  • ベストアンサー
  • e10go
  • ベストアンサー率38% (47/122)
回答No.3

OptionButton1,OptionButton2,OptionButton3・・・の様に、末尾の数字がカウントできる場合は、 UserForm1.Controls("OptionButton" & 数字)という形で、コントロールを指定することができます。 簡単な例として、オプションボタン3つのどれかにチェックが入っているかを調べるマクロを作りました。 '-------マクロコード-------始まり Option Explicit Sub test() Dim inta As Integer, stra As String   stra = "OptionButtonにチェックが入っていません"   For inta = 1 To 3     If UserForm1.Controls("OptionButton" & inta).Value = True Then       stra = "OptionButton" & inta & "にチェックが入っています"       Exit For     End If   Next inta   MsgBox stra End Sub '-------マクロコード-------終わり この例では、UserForm1の中にOptionButton1~3があるとして、そのどれにチェックが入っているかをメッセージボックスで知らせます。 試される場合は、UserForm1の中にOptionButton1~3と、コマンドボタン(CommandButton1)を追加して、UserForm1に下のコードを追加して下さい。 コマンドボタンを押すと、上のマクロが実行されます。 '-------マクロコード-------始まり Private Sub CommandButton1_Click()   test End Sub '-------マクロコード-------終わり UserForm1.Controls("OptionButton" & 数字)を応用すれば、コントロールを配列化?できます。 その為には、UserForm1で、コントロールの配列宣言を行ない、クラスモジュールで、コントロールの配列化とコントロール毎の配列番号を設定します。(この説明で合っているかな?) 以下に例を示します。 この例では、UserForm1の中にCommandButton1~8があるとして、コマンドボタンそれぞれに配列番号をインデックスとして割り振っています。 まず、UserForm1に以下のコードを記入します。 '-------UserForm1コード-------始まり Option Explicit Private CommandButtonNo(1 To 8) As New Class1 Private Sub UserForm_Initialize() Dim inta As Integer   For inta = 1 To 8     CommandButtonNo(inta).CommandButton_Set UserForm1.Controls("CommandButton" & inta), inta   Next inta End Sub '-------UserForm1コード-------終わり 次に、Class1モジュールに以下のコードを記入します。 '-------Class1コード-------始まり Option Explicit Private WithEvents CommandButton_Array As MSForms.CommandButton Private intIndex As Integer Public Sub CommandButton_Set(NewCommandButton As MSForms.CommandButton, Index As Integer)   Set CommandButton_Array = NewCommandButton   intIndex = Index End Sub Private Sub CommandButton_Array_Click()   sub_処理 intIndex '下に説明 End Sub '-------Class1コード-------終わり これで、コマンドボタンを配列化できました。 Class1コードの、 「 sub_処理 intIndex '下に説明」は、標準モジュールのマクロ「sub_処理」で、コマンドボタンを押した時の処理したいマクロを記入します。 この時、「intIndex」がどのコマンドボタンを押したかを見分けるキーになります。 なお、一例として、以下に標準モジュールのマクロコードを載せます。 (UserForm1には、コマンドボタンの他にラベル「Label1」を追加してください) この例では、CommandButton1~8に「1,2,3,4,5,10,20,30」と数字を打って、それぞれのボタンを押すと、その数字を足します。 また、一度押したボタンを再度押すとその数字を引きます。 その結果を「Label1」に表示します。 押したボタンの色も変るようにしています。 '-------標準モジュールコード-------始まり Option Explicit Public byta(9) As Byte Sub sub_処理(intIndex As Integer) Dim inta As Integer, intb As Integer   byta(intIndex) = IIf(byta(intIndex) = 0, 1, 0)   inta = Choose(intIndex, 1, 2, 3, 4, 5, 10, 20, 30)   intb = Val(UserForm1.Label1.Caption)   With UserForm1.Controls("CommandButton" & intIndex)     If byta(intIndex) = 1 Then       .BackColor = &H80000012       .ForeColor = &HFFFFFF       intb = intb + inta     Else       .BackColor = &H8000000F       .ForeColor = &H80000012       intb = intb - inta     End If   End With   UserForm1.Label1.Caption = intb End Sub '-------標準モジュールコード-------終わり #この回答に載せているそれぞれのコードの先頭の空白は、全角にしています。 #もし、コピーして使用される場合は、全角空白を半角に直してください。 #だらだらと、長く書いてすみません。

vba_minarai
質問者

補足

>だらだらと、長く書いてすみません。 勿体無いお言葉!!有難う御座います。大変ためになります。っと本来ならば言いたいのですが、全体を理解するには今の実力では、超~難解です。しかし、いつの日か必ず解読しご指導の内容を自分のものにしたいと考えています。何気なくふと思いついた質問だったのですが、とんでもなく奥深いことだったのですね?正直言って皆さんが凄く努力して努力して習得された知識を惜しげもなく披露されご指導頂けることに心から感謝いたします。特に、オブジェクトにControls("OptionButton" & inta)などと、数式が使えることは目から鱗が落ちました。(落ちるほどの実力はありませんが!)即、実際に役立てて行きたいと思います。有難う御座いました。今後ともよろしくお願いいたします。このご指導のために費やした時間を考えると短文でそっけないお礼しか出来ないことをお詫び申し上げます。有難う御座いました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんにちは。Wendy02です。 1つは、フォームのイニシャライズ時に、 例えば、 Dim TextBoxes As New Collection TextBoxes.Add 個々のコントロール で入れて行く方法で、もう1つは、クラスを扱う方法です。 Mougで紹介されている http://www.moug.net/skillup/opm/opm08-05.htm 擬似コントロール配列の作成 私は、正直なところ、この両方とも、一体、何のために、そんな面倒なことをしなければならないのか、良く分らないです。しょせん、VBのようには使えないとすれば、単にテクニックだけしかないような気がします。 とはいえ、VBAの勉強や練習では、絶対一度はやってみる必要はあると思います。上級テクニックの1つですからね。 (私は、絶対使わないわけではありませんから、誤解しないでくださいね。以下でも触れているように、必要なときもありますから) 実際のコードで、私は、 単に、コントロール名をなるべくユニーク(一意)なものにし、その名前の最後を数字にしてあげれば、そんなに困ることははありません。 Dim i As Integer For i = 1 To 10  Me.Controls("TextBox" & i).Text = CStr(i) Next このようにして切り抜けています。 ただ、イベントの時は、そうはいきませんね。統一化できませんから、その場合はクラスが必要になります。 しかし、以前、プロ?の人の実際のオープンにされたコードをみたら、どうしていたかというと、同じコードをコピー&ペーストしていましたから、私も、実務的には、基本に沿って凝ったことや複雑なことは、なるべくしないようにしています。

vba_minarai
質問者

お礼

追伸!今回3名の方から、貴重なご指導を受けましたが、せめてものお礼の気持ちを表す点数の持分が2つしかありませんので、今回は、ご勘弁のほど、お詫び申し上げます。今後ともよろしくお願いいたします。

vba_minarai
質問者

補足

いつも、いつも、いつも有難うございます。 今回のご指導も心を打たれました。日本の文化として、一つのものを極める技術力の高さと国民資質があると聞いたことがあります。日本刀などその頂点と思いますが、結局!機関銃には勝てないわけですし、槍10本で一気に突かれたらかわすことは難しいでしょう?(意味のないたとえかも知れません?すみません。)また、あとで読み返した時に意味がわからなかったり、改変の時に融通が効かなかったりと・・・!色々弊害もありそうで・・?ご指導通り、シンプルが一番いいと言う点に一人で、妙に納得してしまいました。と、同時に技術力アップのためには考えることも必要である。心に命じます。有難うございました。

全文を見る
すると、全ての回答が全文表示されます。
  • masa_019
  • ベストアンサー率61% (121/197)
回答No.1

下記のサイトを見ると参考になるかも知れません。

参考URL:
http://www.h3.dion.ne.jp/~sakatsu/Breakthrough_P-Ctrl_Arrays.htm
vba_minarai
質問者

補足

早速のご指導有難うございます。 感謝、感謝の限りです。でも、正直言って、禁断の土地への案内状を頂いた感じです。(笑) VBAを最近始めたばかりで、ヘルプの見方がなんとなく判ってきたのですが、もう少し上をと考えていましたが、もう少し今の場所で自己研鑽に励みます。何にも判っていないことを判りました。教えて頂いたサイトは、今後じっくりと熟読し必ず自分のものにしたいと思います。本当に、本当に有難うございました。 後に、ご報告することもあろうかと思いますので、補足の欄を利用させて頂き、お礼を申し上げます。 有難うございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VB2008でユーザーコントロールのイベントについて

    VB2008でユーザーコントロールのイベントについて 作成したユーザーコントロールを(1)フォームに配置した時のみ実行される (2)フォームを実行した時のみ実行される それぞれ処理を分けたいのですが、適切なイベントが見つかりません。 何か区分けのできる方法はあるのでしょうか? 何方か教えていただけませんか

  • UserFormコレクション

    UserForm1内に配置されたコントロールを操作するのに、UserForm2を使うことは有りますか。 コレクションで指定する時に・・・UserForm1.Controls("OptionButton1").Value等。 学習教材で、画像はUserForm1だが、コードにはUserForm2と有る。 どうぞ宜しくお願いします。

  • アクセス+vb 複数コントロールに同じ処理する場合

    アクセス+VBです。 空のフォームにラベルを複数ランダムに配置します。(多ければ500個くらい) そのラベルにクリックイベントを発生させて処理させる場合、ラベルの数だけイベント処理を書かなくてはいけませんよね。 もし、処理内容が同じならひとつの処理記述ですませる方法はないですか。 例えば学校の教室だとすれば、ラベルを机の代わりにしてフォームに配置します。 ラベル(机)をクリックしたら、その生徒のデータが表示される。 良い方法はないでしょうか?

  • VBAにていろいろ質問させてください

    VBAの処理です。 本来なら別々に質問しなければいけないのですが、 どれでも良いのでお分かりになるものを教えてください。 (1)複数のフォームを起動する場合、既にそのフォームが起動中であるとしる方法。またそのフォームを画面最前線に表示する方法。 (2)ExcelシートのコントロールにはLostFocusが使用できるのですが、VBAのActiveXコントロールにはありません。代替機能はありますか?(必須チェックなどしたいのですが) (3)フォームで[?]ボタンでヘルプを出力したいです。 [?]は閉じるボタンの横に配置できたのですが、 [?]に対する各コントロールのヘルプはどう設定すればよいのですか? すみません。どれでも良いので教えてください

  • VB2005 コードでのコントロールのコピーについて

    いつもお世話になっています。 独学でVBの勉強をしているものなのですが、 どうしてもわからないことがあるので教えてください。 デザイナの画面で配置したテキストボックスなどのコントロールを、 コードでコピーして複数配置するようにしたいんです。 そこで、デザイナでTextBox1を配置して、 コードで以下のように記述しました。 Dim MyTextBox1 As New TextBox MyTextBox1 = TextBox1 Me.Controls.Add(MyTextBox1) すると、デザイナ画面で配置したテキストボックスが無くなって、 新たにコードで作成したテキストボックスだけが、 画面に表示されてしまうんです。 実際に行いたいことは、複数のコントロールをパネル上に配置して、 そのパネルをコードで複数作成することなのですが、 そもそもそのようなことはできないのでしょうか? かなり的外れな質問になってしまっているかもしれませんが、 お分かりでしたら教えてください。 よろしくお願いします。

  • ユーザコントロールのイベント取得について(C#)

    環境:Visual Studio 2005 C# Windows Application フォームに自作のユーザコントロールを貼り付けてそのイベントを取得する勉強をしているものです。 フォームでのユーザコントロールイベントを取得して処理をする方法が分かりません。 状況 ユーザコントロールにはテキストボックスを追加しています。 また、フォームにそのユーザコントロールを追加しています。 確認したいことは、ユーザコントロールのテキストボックスになにか値を入力したタイミングでチェンジイベントをフォーム側で察知し、処理をするというものです。 どなたか、要点だけでもいいので教えていただけないでしょうか? 宜しくお願いいたします。

  • VB6 ユーザコントロールでクリックイベント

    コンボボックスにclickイベントを書いたのち(この段階ではprivate) このコントロールをユーザコントロールにしました。 フォーム上に上記のユーザコントロールを配置したところ クリックイベントが発生しません クリックイベントを発生させるには 何か特殊な記述が必要ですか?(例えばオーバライドとか) どうすればクリックイベントを発生させられますか

  • WEBユーザーコントロール

    ASP.NETで開発をしております。fw2.0です。 WEBユーザーコントロールでDBの読み込み画面AとDBの書き込み画面Bを作ったとします。 WEBフォームにAとBをのっけた場合、Bの書き込み処理が終わった後にAの表示を更新させる にはどうしたらいいのでしょうか? イベントのとり方がわからなくて困っています。 ユーザーコントロールを使わなければ普通にイベントを取れるのですが。。。 出来ればユーザーコントロールを使いたいので WEBフォームでユーザーコントロールのイベントを取る方法があれば教えてください。

  • もしフォームヘッダーにコントロールがあるのなら

    アクセスのフォームの、フォームヘッダーに検索用テキストボックスとコンボボックスがあり、 詳細エリアにレコードソース(コントロールソース)に紐付いたテキストボックスが複数あります。 フォームヘッダーのフィルタを解除するコマンドを実行して、 フォームヘッダーのテキストボックスとコンボボックスをnullにしたいのですが、 vbaで「もしフォームヘッダーなら」ってするにはどうすればいいでしょうか? フォームヘッダーのコントロール名も詳細エリアのコントロール名も 区別のないコントロール名でなのでコントロール名で条件分岐をすることは不可能です。 Private Sub フィルタを解除コマンド_Click() Dim ctl As Control For Each ctl In Me.Controls If (ctl.ControlType = acTextBox) Or (ctl.ControlType = acComboBox) Then 'ここで、もしフォームヘッダーにコントロールがあるのならってしたい Me.Controls(ctl.Name) = Null End If Next ctl Me.Form.FilterOn = False End Sub このコードに付け加えてくれませんか? Debug.Print ctl.Name でコントロール名を取得するとフォームヘッダーも詳細もどちらのコントロール名も取得されてしまいます。 On Error Resume Next 以外でお願いします。

  • VBAのイベント処理について

    VBAのイベント処理について お世話になってます。現在、VBAでアプリケーションを作成しています。 1つのフォームに4つのテキストボックスと1つのボタンが配置されており、それぞれイベントが設定されています。 その中のテキストボックスに関するイベントなのですが、1つのテキストボックスに対してKeyPress、KeyDown、MouseUp、AfterUpdate、以上4つのイベントを作成します。 フォームに配置されている4つのテキストボックスすべてに、上記で示したイベントを作成する必要がありますが、各イベントにおける処理の内容はオブジェクト名が違うだけで全く同じです。 ひとつひとつイベントを作成していけば、処理目的は満たせそうですが、ソースがかなり長くなってしまいます。ひとつのオブジェクトに対してこれらの処理をひとまとめにする様な記述方法はありませんでしょうか?考え方だけでも教えていただければ幸いです。 質問が長くなってしまい申し訳ありません。回答宜しくお願い致します。

専門家に質問してみよう