• ベストアンサー

エクセルのユーザーフォームのマクロ内でコマンドボタンを作成する

エクセルのユーザーフォームで、読み込んだときにコマンドボタンを作成する方法を教えてほしいです。 通常は、先にユーザーフォーム内でボタンを作成して、キャプション等を設定すると思うのですが、ボタンの数が決まっていないので、フォームを読み込むたびにボタンの数を変えたいと思っています。 似たようなことでは、先にボタンを作っておいて可視、不可視にしようかとも思ったのですが、あまりそれはやりたくないです。 よろしくお願いします。 環境は、XPでエクセルは2003です。

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

  • ベストアンサー
  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.4

追加したボタンをクリックしたときに動くモジュールはどうするつもりですか? 予め追加するボタンの分だけ  Private Sub CommandButton*_Click()  End Sub を書いておいても、うまくいくかどうか? …です。もう試されましたか? 追加したボタンをクリックしたときに処理を動かすためには、他の回答者さまも述べているように、クラスモジュールを使う必要があるように思います。あまり得手ではないのですが試しにサンプルを書いてみました。 まずユーザーフォーム右下にコマンドボタン1つを配置します。ユーザフォームはボタンを追加するので、少し大きめに作っておくとよいです。このコマンドボタンは「ボタン追加」の意味があります そして以下をユーザーフォームモジュールシートとユーザフォームシートにそれぞれ貼り付けます。後は  Userform1.Show でユーザフォームを呼び出して、ボタンをクリックしてみてください (Office2003で確認済みです) ユーザーフォームモジュール Dim myCb() As Class1 Private Sub CommandButton1_Click() Dim ctrl As Control Dim cnt As Integer  For Each ctrl In UserForm1.Controls   If TypeName(ctrl) = "CommandButton" Then    cnt = cnt + 1   End If  Next  With Me.Controls.Add("Forms.CommandButton.1")   .Top = cnt * 40   .Left = 20   .Width = 80   .Caption = .Name  End With Call UserForm_Initialize End Sub Private Sub UserForm_Initialize() Dim cnt, i As Integer For Each ctrl In UserForm1.Controls If TypeName(ctrl) = "CommandButton" Then cnt = cnt + 1 End If Next ReDim myCb(1 To cnt) For i = 1 To cnt Set myCb(i) = New Class1 Set myCb(i).opt = Me.Controls("CommandButton" & CStr(i)) Next i End Sub クラスモジュール(モジュール名:Class1)に貼り付け Public WithEvents myCb As MSForms.CommandButton Public Property Set opt(setcb As MSForms.CommandButton)  Set myCb = setcb End Property Public Property Get opt() As MSForms.CommandButton End Property Sub myCb_Click()  MsgBox myCb.Name & " がクリックされました" End Sub これを見て「わからん」なら可視、不可視で実現する方をお薦めしますが…

koolm
質問者

お礼

今回、初めてクラスモジュールというものを使いました。 まだ、わかっていませんが、ぼちぼちやりたいと思います。 コード、ご意見ありがとうございました。 自分だけでは、不可能でした。 ありがとうございました。

その他の回答 (3)

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

私もやってみました。 ラベルの例では http://sunrise2001.dip.jp/coo/lactic.html に例があります。 ーー しかし、質問者は#1のご回答者が、 >追加するボタンが不定ならクラスモジュールを使わないと イベント処理できませんよ? Click イベントとか とおっしゃっている、難しさに気づいていないのではないでしょうか。私もそうですが、質問者には荷が重いことをやろうとしているということです。 ラベルのように、実行中に、情報をラベルに表示をさせて、役割を果たせるものは、それで良いが、コマンドボタンは、それにイベント・プロをくっつけてこそ、フォームにそれを作った意味があります。しかし作るのは進んだスキルがいるようですね。 ちなみに、下記では実行が終わったらユザーフォーム1上に何も残っていませんでしょ。 ーー Private Sub UserForm_Initialize() Me.Height = 300 For i = 1 To 5 s = "ボタン" & i With Me.Controls.Add("Forms.CommandButton.1", , True) .Top = (i - 1) * 40 + 10 .Left = 20 .Width = 50 .Height = 30 .Caption = "ボタン" & i End With Next i End Sub

koolm
質問者

お礼

ご指摘のとおり、甘く見ていました。 最終的には、zap35さんのを参考にしました。 ご意見、ありがとうございました。

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

> もし、ラベルを作成したいとするととかだとどうなるのでしょうか? bstrProgID に指定する文字列。VBA ヘルプからの引用です。 Forms.CheckBox.1 Forms.ComboBox.1 Forms.CommandButton.1 Forms.Frame.1 Forms.Image.1 Forms.Label.1        <---- ラベル Forms.ListBox.1 Forms.MultiPage.1 Forms.OptionButton.1 Forms.ScrollBar.1 Forms.SpinButton.1 Forms.TabStrip.1 Forms.TextBox.1 Forms.ToggleButton.1 > Meというのはどういった意味があるのでしょうか? Me キーワードは簡単に言えばオブジェクトモジュールの代名詞です。 ここでは、Userform モジュールで Me と書いているので、Userform のことになります。例えば、   Userform1.Caption = "Test" と書くところを   Me.Caption = "Test" と書くことができます。 この利点は、前者はモジュールの名前を変更するとコード全体を修正 することになりますが、後者の場合は影響を受けません。 Me キーワードが何の代名詞となるかは、Me キーワードがどこに書か れているかで決まります。

koolm
質問者

お礼

理解できました。 ありがとうございました。

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.1

動的に Userform にボタンを追加するなら、下記のようなコードで できますけど...     With Me.Controls.Add(bstrProgId:="Forms.CommandButton.1")       .Caption = "TEST"       .Width = 200       .Height = 18       .Top = 10       .Left = 10     End With でも、追加するボタンが不定ならクラスモジュールを使わないと イベント処理できませんよ? Click イベントとか。

koolm
質問者

補足

回答ありがとうございます。 出来ました。 それで、コードについてもう少し聞きたいのですが、 With Me.Controls.Add(bstrProgId:="Forms.CommandButton.1") という文の中で"Forms.CommandButton.1"がコマンドボタンを作成するということでしょうか? もし、ラベルを作成したいとするととかだとどうなるのでしょうか? 試しにLabelに変えただけではだめでした。 あと、Meというのはどういった意味があるのでしょうか? 度々、申し訳ありませんが、よろしくお願いいたします。

関連するQ&A

専門家に質問してみよう