- ベストアンサー
VBAのコントロールなんかをコレクションとして扱える?
フォームに複数のコントロールを配置したときにその選定によって条件分岐やイベント処理を行いたいときに同じようなコードを羅列する必要が生じました。コントロールをコレクション?(もしかして?クラス?<クラスは全く解っていません>)として、一くくりに扱う方法ってありますか? ご指導のほどよろしくお願いいたします。
- みんなの回答 (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 '-------標準モジュールコード-------終わり #この回答に載せているそれぞれのコードの先頭の空白は、全角にしています。 #もし、コピーして使用される場合は、全角空白を半角に直してください。 #だらだらと、長く書いてすみません。
その他の回答 (2)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。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 このようにして切り抜けています。 ただ、イベントの時は、そうはいきませんね。統一化できませんから、その場合はクラスが必要になります。 しかし、以前、プロ?の人の実際のオープンにされたコードをみたら、どうしていたかというと、同じコードをコピー&ペーストしていましたから、私も、実務的には、基本に沿って凝ったことや複雑なことは、なるべくしないようにしています。
お礼
追伸!今回3名の方から、貴重なご指導を受けましたが、せめてものお礼の気持ちを表す点数の持分が2つしかありませんので、今回は、ご勘弁のほど、お詫び申し上げます。今後ともよろしくお願いいたします。
補足
いつも、いつも、いつも有難うございます。 今回のご指導も心を打たれました。日本の文化として、一つのものを極める技術力の高さと国民資質があると聞いたことがあります。日本刀などその頂点と思いますが、結局!機関銃には勝てないわけですし、槍10本で一気に突かれたらかわすことは難しいでしょう?(意味のないたとえかも知れません?すみません。)また、あとで読み返した時に意味がわからなかったり、改変の時に融通が効かなかったりと・・・!色々弊害もありそうで・・?ご指導通り、シンプルが一番いいと言う点に一人で、妙に納得してしまいました。と、同時に技術力アップのためには考えることも必要である。心に命じます。有難うございました。
- masa_019
- ベストアンサー率61% (121/197)
下記のサイトを見ると参考になるかも知れません。
補足
早速のご指導有難うございます。 感謝、感謝の限りです。でも、正直言って、禁断の土地への案内状を頂いた感じです。(笑) VBAを最近始めたばかりで、ヘルプの見方がなんとなく判ってきたのですが、もう少し上をと考えていましたが、もう少し今の場所で自己研鑽に励みます。何にも判っていないことを判りました。教えて頂いたサイトは、今後じっくりと熟読し必ず自分のものにしたいと思います。本当に、本当に有難うございました。 後に、ご報告することもあろうかと思いますので、補足の欄を利用させて頂き、お礼を申し上げます。 有難うございました。
補足
>だらだらと、長く書いてすみません。 勿体無いお言葉!!有難う御座います。大変ためになります。っと本来ならば言いたいのですが、全体を理解するには今の実力では、超~難解です。しかし、いつの日か必ず解読しご指導の内容を自分のものにしたいと考えています。何気なくふと思いついた質問だったのですが、とんでもなく奥深いことだったのですね?正直言って皆さんが凄く努力して努力して習得された知識を惜しげもなく披露されご指導頂けることに心から感謝いたします。特に、オブジェクトにControls("OptionButton" & inta)などと、数式が使えることは目から鱗が落ちました。(落ちるほどの実力はありませんが!)即、実際に役立てて行きたいと思います。有難う御座いました。今後ともよろしくお願いいたします。このご指導のために費やした時間を考えると短文でそっけないお礼しか出来ないことをお詫び申し上げます。有難う御座いました。