[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『VBA フォーム 動的に生成したボタンのプロパティを後から変更したい』(ほわ)
フォームに「縦n」「横n」というテキストボックスがあり、そこに数字を入力して「作る」というボタンを押すとその分だけボタンが生成されます。
フォームの名前は「Form」です。
Private Sub 作る_Click()
Dim gyo As Long: gyo = 縦n.Value
Dim retu As Long: retu = 横n.Value
Dim i As Long, j As Long
For i = 1 To gyo
For j = 1 To retu
ReDim Btn(i, j)
Dim BtnName As String: BtnName = "Btn_" & i & "_" & j With MineSweeperForm Set Btn(i, j) = .Controls.Add("Forms.CommandButton.1", BtnName, True)
With Btn(i, j) .Top = 15 * i + 30 .Left = 15 * j - 5 .Height = 15 .Width = 15 .Font.Size = 8 End With End With Next j Next i
End Sub
「塗る」というボタンがあり、「縦n」「横n」に入力したボタンのキャプションを空欄から「●」へ変更したいです。
試したコードは下記のとおりです。
Private Sub 塗る_Click()
Dim gyo As Long: gyo = 縦n.Value
Dim retu As Long: retu = 横n.Value
BtnName = "Btn_" & gyo & "_" & retu
Form.BtnName.Caption = "●"
End Sub
「メソッドまたはデータメンバーが見つかりません」のエラーが出て
Form.BtnName.Caption = "●"
の行で止まってしまいます。
試しに3×3のボタンを生成して
Form.Btn_3_3.Caption = "●"
としても同じエラーが出てしまうので、オブジェクトの指定方法が誤っている可能性があります。
フォームに手動で「Btn_3_3」という名前でボタンを作ってみると同様の書き方でキャプション変更できました。
< 使用 Excel:Office365、使用 OS:Windows10 >
参考
http://officetanaka.net/excel/vba/variable/05.htm
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/modifiers/withevents
(きまぐれおじさん) 2021/12/04(土) 16:09
参考に
Private Sub 塗る_Click() Dim gyo As Long: gyo = 縦n.Value Dim retu As Long: retu = 横n.Value Dim BtnName As String
BtnName = "Btn_" & gyo & "_" & retu Me.MineSweeperForm.Controls(BtnName).Caption = "●" End Sub
(ピンク) 2021/12/04(土) 17:10
ピンクさんとまる被りですが、せっかく書いたので、
Private Sub 塗る_Click() Dim gyo As Long: gyo = 縦n.Value Dim retu As Long: retu = 横n.Value Dim btnName As String btnName = "Btn_" & gyo & "_" & retu Me.Controls(btnName).Caption = "●" End Sub
MineSweeperFormというのはユーザフォーム名という前提。
マインスイーパーを作ろうとしているなら、 クラスモジュールによるイベントの共通化について調べるといいでしょう。
(hatena) 2021/12/04(土) 17:16
>MineSweeperForm ユーザフォーム名でしたか、てっきりフレーム名かと早とちり(;^_^A Me.Controls(BtnName).Caption = "●" で十分でしたね
(ピンク) 2021/12/04(土) 17:31
フレーム名かも知れないですね。
> フォームの名前は「Form」です。
と質問者さんは言われているので。
(hatena) 2021/12/04(土) 17:46
ピンク様、hatena様
フォームの名前で混乱させてしまい、すみません。
いただいたコードで想定通りの動きになりました。
大変助かりました。
Controls()とは何なのか...?もう少し勉強します。
数日悩んでいたことが(理解は追いついていませんが)とりあえず解決して幸せです。
本当にありがとうございました。
(ほわ) 2021/12/04(土) 19:39
解決済みですが、いくつか、補足を。
UserForm.Controls はフォーム上のコントロールのコレクション(配列のようなもの)です。
.Controls(1) とインデックスで特定のコントロールを参照できます。 また、.Controls("コントロール名") というようにコントロールの名前の文字列で参照することも可能です。 今回の回答は、この名前の文字列で参照する方法を使っています。
最初の質問のコードでちょっと気になる部分があったので、指摘しておきます。
For i = 1 To gyo For j = 1 To retu ReDim btn(i, j) Dim BtnName As String: BtnName = "Btn_" & i & "_" & j With Me Set btn(i, j) = .Controls.Add("Forms.CommandButton.1", BtnName, True) With btn(i, j) .Top = 15 * i + 30 .Left = 15 * j - 5 .Height = 15 .Width = 15 .Font.Size = 8 End With End With Next j Next i
上記のコードですが、ループ内で、繰り返し、ReDim btn(i, j) してますが、 意味ないです。ReDim すると配列の内容はリセットされるので、中身は空っぽの 配列の最後に、コマンドボタンを一つ代入しているだけです。
ここは配列にしなくても、CommandButtonオプジェクトの変数として宣言すればOKです。
Dim btn As MSForms.CommandButton
For i = 1 To gyo For j = 1 To retu Dim BtnName As String: BtnName = "Btn_" & i & "_" & j With MineSweeperForm Set btn = .Controls.Add("Forms.CommandButton.1", BtnName, True) With btn .Top = 15 * i + 30 .Left = 15 * j - 5 .Height = 15 .Width = 15 .Font.Size = 8 End With End With Next j Next i
あるいは、変数宣言じたいせずに、下記のようにWithステートメントで参照するようにできます。
Dim i As Long, j As Long For i = 1 To gyo For j = 1 To retu Dim btnName As String: btnName = "Btn_" & i & "_" & j With Me.Controls.Add("Forms.CommandButton.1", btnName, True) .Top = 15 * i + 30 .Left = 15 * j - 5 .Height = 15 .Width = 15 .Font.Size = 8 End With Next j Next i
もし、配列を使うなら、モジュールレベルの変数として宣言しておいて、 後から利用できるようにするといいでしょう。
Option Explicit Private Btn() As MSForms.CommandButton
Private Sub 作る_Click() Dim gyo As Long: gyo = 縦n.Value Dim retu As Long: retu = 横n.Value ReDim Btn(1 To gyo, 1 To retu)
Dim i As Long, j As Long For i = 1 To gyo For j = 1 To retu Dim BtnName As String: BtnName = "Btn_" & i & "_" & j Set Btn(i, j) = Me.Controls.Add("Forms.CommandButton.1", BtnName, True) With Btn(i, j) .Top = 15 * i + 30 .Left = 15 * j - 5 .Height = 15 .Width = 15 .Font.Size = 8 End With Next j Next i End Sub
Private Sub 塗る_Click() Dim gyo As Long: gyo = 縦n.Value Dim retu As Long: retu = 横n.Value Btn(gyo, retu).Caption = "●" End Sub
なお、現状のコードは、作るボタンは1回のみクリックするという前提です。 何回もクリックするなら、最初に追加したコントロールを削除するコードが必要になります。
(hatena) 2021/12/04(土) 21:48
御礼が遅くなりました。
ご指摘ありがとうございます。
大変勉強になります。
理想のマインスイーパーに一歩近づきました。
(ほわ) 2021/12/06(月) 14:48
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.