- ベストアンサー
エクセルVBAでオプションボタンを無効にする方法
フォームで作成したオプションボタンを一定の条件下で無効にするにはどのような記述をすればよいのでしょうか? たとえばsheets("Sheet1").Range("A1")がFalseのときにShapes("Option Button 1")を無効にするという記述です。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんなのでは? ActiveSheet.Shapes("Option Button 1").Select Selection.Enabled = False ボタン1と2が同グループの場合、ボタン1をTrue状態のまま操作できなくしても、 ボタン2が選択されるとボタン1はFalseになりますが。
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
merlionXXさん、こんにちは。 Enabled に関しては、フォームでも、コントロールツールでも、同じだと思います。それよりも、むしろ、そのイベントをどこで取るかということだと思います。新たにボタン等を設けるのでしょうか? #2 で書いたとおりで、イベントを発生させたコントロールで Enabled =False にしたら、そのコントロールでは、復帰はできなくなります。 もちろん、ワークシート・イベントやコマンド・ボタンなど外部に、イベントを取ればよいだけのことですが、そのキーになる部分は書かれていませんから、私は、コントロールそのものでイベントを考えました。 その点で、フォームのほうが、VBAでも取り扱いが易しいです。私は、フォームのコントロールを多用します。コントロールツールの場合は、イベントの種類が豊富ですが、通常、VBAからではイベントを簡単に設定することが出来ないようです。ですから、クラス/インスタンスで、以下のような可能ですが、かなり取り扱いが面倒です。 >Shapes(OBname).DrawingObject.Value = Empty ではオプションボタンのリンク先セルが0になってしまい、前の状態が保持されなくなってしまいます。 >選択できないようにはするけど、前の状態は保持したいのです。 これ自体は、LinkedCellを空にしたら、OnAction で値を出力するか、しないかだけのことではありませんか? 前回とそっくり入れ替えです。 '<Sheet1 モジュール> Option Explicit Sub TestSampe1() Dim OB As OptionButton Dim i As Long i = 1 For Each OB In OptionButtons OB.OnAction = "Sheet1.MyOBAction" 'コントロールの名前を変更 OB.Name = "OB" & i i = i + 1 Next End Sub Private Sub MyOBAction() Dim OBname As String OBname = Application.Caller If Range("A1").Value = False Then Shapes(OBname).DrawingObject.Value = Empty Else 'リンク先セル Range("F1").Value = Mid(OBname, InStr(OBname, "OB") + 2) End If End Sub '----------------------------------------------------- 同じスタイルで、コントロールツールのコントロールを擬似コントロール配列にして、インスタンスを作りました。こちらは、Index を新しいプロパティとして付け加えています。Excelでは、ふだんは使わないコードですが、これも一興かもしれません。 '<標準モジュール> Option Explicit Option Base 1 Dim myClass1() As New Class1 Sub TestSample2() Dim myBtns As New Collection Dim ctrl As Object Dim i As Integer Dim mySh As Worksheet Set mySh = Worksheets("Sheet1") For Each ctrl In mySh.OLEObjects If TypeOf ctrl.Object Is MsForms.OptionButton Then With myBtns .Add Item:=ctrl.Object End With End If Next ctrl For i = 1 To myBtns.Count ReDim Preserve myClass1(i) Set myClass1(i) = New Class1 With myClass1(i) .mProperty = myBtns(i) .Index = i End With Next Beep End Sub '<Class1 モジュール> Private WithEvents myOBtn As MsForms.OptionButton Private myIndex As Integer Public Property Get OBtn() As MsForms.OptionButton Set OBtn = myOBtn End Property Public Property Let mProperty(ByVal OBtnNewValue As MsForms.OptionButton) Set myOBtn = OBtnNewValue End Property Public Property Get Index() As Integer Index = myIndex End Property Public Property Let Index(ByVal intNewValue As Integer) myIndex = intNewValue End Property Private Sub myOBtn_Click() If Worksheets("Sheet1").Range("A1").Value = False Then myOBtn.Value = Empty Else 'リンク先 Worksheets("Sheet1").Range("F1").Value = myIndex End If End Sub
お礼
ありがとうございました。 今回はNo5さんの方法であっけなく解決しました。 今回はボタン操作で行うマクロですのでイベントは考えなくて良かったのです。 最初からそう書いておけばよかったですね、お手数をおかけしました。 すみません。
- taocat
- ベストアンサー率61% (191/310)
こんばんは。 なぜ、メソッド、プロバティが多くあるコントロールツールボックスを使わないのですか? で、Sheet1上にコントロールツールボックスのオプションボタンをいくつか配置。 但し、OptionButton1を無効にするタイミング(イベント)が書いてないのでコードは標準モジュール。 A1に値があれば(True)、OptionButton1 を有効にし、 何も入ってなければ(False)、無効とする。 ------------------------------------------------- Sub Test() With Sheets("Sheet1") If .Range("A1").Value Then .OLEObjects("OptionButton1").Enabled = True Else .OLEObjects("OptionButton1").Enabled = False End If End With End Sub ------------------------------------------------ ま、これでは汎用性がないので、ボタンの番号部分を変数にしてサブルーチン化等した方がいいかも知れませんね。 .OLEObjects("OptionButton" & N).Enabled = False 以上です。
お礼
ありがとうございます。 コントロールツールボックスならEnabled = Falseでいけるんですね。 今までフォームばっかりつかってきたので残念ながらコントロールツールボックスの方はうといんです。
- Wendy02
- ベストアンサー率57% (3570/6232)
#2 の追伸です。 また、サンプルコードを考えてみました。 以下は、フォーム独特だと思います。コントロールツールの場合は、OLEObjectsで制御しますので、この点で違ってきます。(と言って、まだ考えていません。まったく、違うコードのような気がします。) Sheet1 の A1 に、 =IF(A2=0,FALSE,TRUE) としてして、A2 に、数値を入力して、TRUE/FALSE を表示します。 '<Sheet1 モジュール> または、 '<ThisWorkbook モジュール>の Private Sub Workbook_Open()に登録 Private Sub Worksheet_Activate() Dim OB As OptionButton For Each OB In OptionButtons OB.OnAction = "Sheet1.MyOBAction" Next End Sub '<Sheet1 モジュール> Private Sub MyOBAction() Dim OBname As String OBname = Application.Caller If Range("A1").Value = False Then Shapes(OBname).DrawingObject.Value = Empty End If End Sub これで、試してみてください。
お礼
Wendy02 さん、いつもありがとうございます。 Shapes(OBname).DrawingObject.Value = Empty ではオプションボタンのリンク先セルが0になってしまい、前の状態が保持されなくなってしまいます。 選択できないようにはするけど、前の状態は保持したいのです。 現在はリンク先のセルの前の状態を別セルにコピーしておき、オプションボタンを押された場合、別セルの値をリンク先にコピーして対応しています。
- Wendy02
- ベストアンサー率57% (3570/6232)
merlionXX さん、こんばんは。Wendy02 です。 しばらく考えてみましたが、二つのロジックが考えられます。 (ちょっとお話がむつかしくなるかと思いますが) 最初に、そのオプションボタンを無効にするという、Range("A1")に、True/False を与えるものは、入力なのですか?式なのですか?それによって、設定が出来るような気がしています。式ですと、やっかいですね。それ自体には、イベントを発生させることはできませんので、常に、Now で Calculateイベントを発生させなくてはならなくなります。実用性が今ひとつ落ちます。 それから、もうひとつは、そのオプションボタンのイベントのコードは、OnAction ですね。だから、OnAction で、オプションボタンそのものを Enabled= False にするというのはできますが、それを、今度はEnabled =True と復帰する方法がなくなりますから、この選択はできませんが、少なくとも、OnAction で出力値そのものは、無効にすることが出来ますね。 どれか、ひとつで出来るはずです。この方法は、コントロールツール側でも、大きく変わることはないはずです。
- misatoanna
- ベストアンサー率58% (528/896)
ActiveSheet.Shapes("Option Button 1").Visible = False で、非表示にしてしまうとか.....。
お礼
さっそくありがとうございます。 Visible = Falseはわたしも考えたのですが、やはり一定条件下では選択できないことを明確にしたいので、その前の状態を保持しつつボタンが効かない状態にしたいのです。
お礼
ありがとうございました! ばっちりです。