プロが教える店舗&オフィスのセキュリティ対策術

エクセルのユーザーフォームで、読み込んだときにコマンドボタンを作成する方法を教えてほしいです。

通常は、先にユーザーフォーム内でボタンを作成して、キャプション等を設定すると思うのですが、ボタンの数が決まっていないので、フォームを読み込むたびにボタンの数を変えたいと思っています。

似たようなことでは、先にボタンを作っておいて可視、不可視にしようかとも思ったのですが、あまりそれはやりたくないです。
よろしくお願いします。

環境は、XPでエクセルは2003です。

A 回答 (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

これを見て「わからん」なら可視、不可視で実現する方をお薦めしますが…
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/08/09 10:35

私もやってみました。


ラベルの例では
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
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/08/09 10:33

> もし、ラベルを作成したいとするととかだとどうなるのでしょうか?



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 キーワードがどこに書か
れているかで決まります。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/08/08 15:11

動的に Userform にボタンを追加するなら、下記のようなコードで


できますけど...

    With Me.Controls.Add(bstrProgId:="Forms.CommandButton.1")
      .Caption = "TEST"
      .Width = 200
      .Height = 18
      .Top = 10
      .Left = 10
    End With

でも、追加するボタンが不定ならクラスモジュールを使わないと
イベント処理できませんよ? Click イベントとか。

この回答への補足

回答ありがとうございます。
出来ました。

それで、コードについてもう少し聞きたいのですが、
With Me.Controls.Add(bstrProgId:="Forms.CommandButton.1")
という文の中で"Forms.CommandButton.1"がコマンドボタンを作成するということでしょうか?

もし、ラベルを作成したいとするととかだとどうなるのでしょうか?
試しにLabelに変えただけではだめでした。

あと、Meというのはどういった意味があるのでしょうか?
度々、申し訳ありませんが、よろしくお願いいたします。

補足日時:2007/08/08 13:54
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!