質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

918閲覧

VBAのボタンの色に関して

kumikumi550

総合スコア16

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2018/12/07 02:58

前提・実現したいこと

VBAで
50個あるボタンに対して
それぞれ5個ずつのグループを作り
各グループに対して1つのボタンしか押せない(色がつかない)
→グループ内では1度ボタンを押した後に別のボタンを押すと、ほかのボタンは元の色に戻る
ようにしたい
そのために、とりあえずは押したボタンを自動認識し、色が変わるようにしたい

発生している問題・エラーメッセージ

エラーはないが機能しない

VBA

1~class1~ 2Public WithEvents myBtn As MSForms.CommandButton 3Private Sub myBtn_Click() 4 Dim i As Integer 5 i = myBtn.Index 6 n = "CommandButton" & i & ".BackColor" 7 If i <= 5 Then 8 n = RGB(255, 0, 0) 9 ElseIf i <= 10 Then 10 n = RGB(255, 0, 0) 11 End If 12End Sub 13~module~ 14Public myClass As New Class1 15Sub Auto_Open() 16 Dim ctrl As Object 17 Dim i As Integer 18Static myClass() As Class1 19 For Each ctrl In Worksheets("Sheet1").OLEObjects 20 If TypeOf ctrl.Object Is MSForms.CommandButton Then 21 ReDim Preserve myClass(i) 22 Set myClass(i) = New Class1 23 Set myClass(i).myBtn = ctrl.Object 24 i = i + 1 25 End If 26 Next 27End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kumikumi550

2018/12/07 04:06

Userform.controlの存在を知りましたが、Userformは使えないので、通常のSheetでも使えるほうほうをしりたいです。
guest

回答2

0

解決済みになっちゃいましたが、興味深い内容なので作ってみました。

今回の要件は、
複数のボタンをグループ化して、その中の一つだけを選択できるようにするということですね。

せっかくクラスにするのですから、できるだけ汎用性のあるものにしたいので、
下記のような設計を考えてみました。

SelectButtonクラス
クリックすると選択状態(背景色 赤)になる
・Selectedプロパティ 選択=True / 非選択=False

SelectButtonGroupクラス
SelectButtonのグループ
・Addメソッド コマンドボタンをグループに追加する。

このクラスを作ることによって各グループごとにボタンの数が異なる場合でも簡単に対応できます。

SelectButtonクラス

Option Explicit Private WithEvents btn As MSForms.CommandButton Private Slected_ As Boolean '選択 Private GroupBtns_ As Collection 'クラスにコマンドボタンと属するグループ(Collection)を登録する。 Public Sub setBtn(ByVal cb As MSForms.CommandButton, ByVal GroupBtns As Collection) Set btn = cb Set GroupBtns_ = GroupBtns End Sub '選択状態の設定 Public Property Let Slected(ByVal new_Slected As Boolean) If Slected_ <> new_Slected Then Slected_ = new_Slected If Slected_ Then btn.BackColor = vbRed Else btn.BackColor = vbButtonFace End If End If End Property '選択状態の取得 Public Property Get Slected() As Boolean Slected = Slected_ End Property Private Sub Btn_Click() Dim ctl As SelectButton For Each ctl In GroupBtns_ ctl.Slected = False Next Slected_ = True btn.BackColor = vbRed End Sub

SelectButtonGroupクラス

Option Explicit Private BtnGrp As Collection Public Sub Add(ByVal btn As MSForms.CommandButton) Dim selBtn As SelectButton Set selBtn = New SelectButton selBtn.setBtn btn, BtnGrp BtnGrp.Add selBtn End Sub Private Sub Class_Initialize() Set BtnGrp = New Collection End Sub Private Sub Class_Terminate() Dim selBtn As SelectButton For Each selBtn In BtnGrp selBtn.Slected = False Set selBtn = Nothing Next Set BtnGrp = Nothing End Sub

Sheet1 に、CommandButton1 ~ 10 の10個のコマンドボタンがあり、
1 ~ 5, 6 ~ 8, 9 ~ 10 の3グループに分ける、
Sheet2 に、CommandButton1 ~ 5 がありすべて一つのグループにする、
場合のコード例

ThisWorkBookモジュール

Option Explicit Private SelBtnGrp(3) As SelectButtonGroup Private Sub Workbook_BeforeClose(Cancel As Boolean) Set SelBtnGrp(0) = Nothing Set SelBtnGrp(1) = Nothing Set SelBtnGrp(2) = Nothing Set SelBtnGrp(3) = Nothing End Sub Private Sub Workbook_Open() Dim i As Integer With Worksheets("Sheet1") Set SelBtnGrp(0) = New SelectButtonGroup For i = 1 To 5 SelBtnGrp(0).Add .OLEObjects("CommandButton" & i).Object Next Set SelBtnGrp(1) = New SelectButtonGroup For i = 6 To 8 SelBtnGrp(1).Add .OLEObjects("CommandButton" & i).Object Next Set SelBtnGrp(2) = New SelectButtonGroup For i = 9 To 10 SelBtnGrp(2).Add .OLEObjects("CommandButton" & i).Object Next End With With Worksheets("Sheet2") Set SelBtnGrp(3) = New SelectButtonGroup For i = 1 To 5 SelBtnGrp(3).Add .OLEObjects("CommandButton" & i).Object Next End With End Sub

一応、最小限の雛形です。今後、拡張したいこととして、下記が考えられます。

SelectButtonクラスに
Countプロパティ、
SelectIndexプロパティ、
Changeイベント
などの実装

投稿2018/12/07 17:12

編集2018/12/08 03:58
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kumikumi550

2018/12/08 00:06

class1,class2を作成して、それぞれペースト ThisWorkBookに該当範囲をペースト したところ、 ThisWorkBookのSelBtnGrp(2) As SelectButtonGroupにユーザ定義型が定義されていませんとエラーが出ますが、なぜでしょうか
hatena19

2018/12/08 00:39

class1, class2 のオブジェクト名をそれぞれ、SelectButton、SelectButtonGroup に変更してください。 クラス名は既定のままでなく、その目的、機能が分かる名前に変更したほうがいいです。
hatena19

2018/12/08 00:50

ThisWorkBookモジュールのコード例を、複数のシートにコマンドボタンを配置した場合のコード例に修正しました。
kumikumi550

2018/12/08 01:28

SelectButyonGroup内の selBtn.setBtn btn, BtnGrp の.setBtnにメソッドまたはデータメンバーが見つかりません エラーが出ます
kumikumi550

2018/12/08 01:38 編集

ボタン番号の問題でした SelBtnGrp(1).Add .OLEObjects("CommandButton" & i).Object にオブジェクト変数またはwithブロック変数が設定されていません エラーが出ます
guest

0

ベストアンサー

修正してみました。
似ているようで若干違います。
クラスの使い方ですかね。
見比べてみてください。

Class1

VBA

1Private WithEvents Btn As MSForms.CommandButton 2 3Public Sub myBtn(ByVal cb As MSForms.CommandButton) 4 Set Btn = cb 5End Sub 6 7Private Sub Btn_Click() 8 Dim i As Integer 9 i = Btn.Index 10 If i <= 1 Then 11 Btn.BackColor = RGB(255, 0, 0) 12 ElseIf i <= 2 Then 13 Btn.BackColor = RGB(0, 255, 0) 14 ElseIf i <= 3 Then 15 Btn.BackColor = RGB(0, 0, 255) 16 End If 17End Sub

Module1

VBA

1Public myClass() As Class1 2 3Sub Auto_Open() 4 5 Dim ctrl As Object 6 Dim i As Integer 7 8 i = 0 9 For Each ctrl In Worksheets("Sheet1").OLEObjects 10 If TypeOf ctrl.Object Is MSForms.CommandButton Then 11 ReDim Preserve myClass(i) 12 Set myClass(i) = New Class1 13 myClass(i).myBtn ctrl.Object 14 i = i + 1 15 End If 16 Next 17 18End Sub

投稿2018/12/07 04:50

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kumikumi550

2018/12/07 05:11

例えば、 2を押す→2が赤くなり1,3,4,5が黒くなる 3を押す→3が赤くなり1,2,4,5が黒くなる としたい場合はどうすれば良いでしょうか
ttyp03

2018/12/07 05:45

簡単なのはクリックイベントで一旦全部黒にして、押されたボタンだけを赤にする方法でしょうか。 Private Sub Btn_Click() Dim ctrl As Object For Each ctrl In Worksheets("Sheet1").OLEObjects If TypeOf ctrl.Object Is MSForms.CommandButton Then ctrl.Object.BackColor = vbBlack End If Next Btn.BackColor = vbRed End Sub しかし理由はわからないのですが、どうも動きが鈍いというか、元赤のボタンの描画が3回発生しているような。。。 黒にしたあと赤になって黒になる。 時間があれば調べてみますが、ひとまずはこんな感じで。
jawa

2018/12/07 08:37 編集

横から失礼しますm(_ _)m Btn_Click時に押したボタンに対して色付けをするだけではなく、同じグループのボタンの色付けも必要ですよね。 ttyp03さんのコードを元にして、Class1のBtnをPublicで宣言し、myClassに格納したボタンコントロールを参照できるようにしてみてはどうでしょうか? そのうえで、Btn_Click時にはグループ単位でmyClassをループ処理してそれぞれに色設定を行う、といった具合です。 ``` Public WithEvents Btn As MSForms.CommandButton '外部から参照できるようにPublicで宣言 Public Sub myBtn(ByVal cb As MSForms.CommandButton) Set Btn = cb End Sub Private Sub Btn_Click() Dim i As Integer Dim i2 As Integer Dim iGrpSt As Integer '押したボタンのグループの先頭 Const GRP_CNT = 5 '1グループのボタン数 i = Btn.Index - 1 iGrpSt = Int((i) / GRP_CNT) * GRP_CNT 'グループ内のボタンだけループ処理 For i2 = iGrpSt To iGrpSt + GRP_CNT - 1 If i2 = i Then myClass(i2).Btn.BackColor = RGB(0, 0, 200) Else myClass(i2).Btn.BackColor = RGB(200, 200, 200) End If Next End Sub ``` 参考になれば幸いです。
kumikumi550

2018/12/07 12:49

できました ありがとうございます 純粋な、質問なのですが 各グループごとにボタンの数が異なる場合のアイデアなどありますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問