• ベストアンサー

エクセルVBAでオプションボタンを無効にする方法

フォームで作成したオプションボタンを一定の条件下で無効にするにはどのような記述をすればよいのでしょうか? たとえばsheets("Sheet1").Range("A1")がFalseのときにShapes("Option Button 1")を無効にするという記述です。

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

  • ベストアンサー
回答No.5

こんなのでは? ActiveSheet.Shapes("Option Button 1").Select Selection.Enabled = False ボタン1と2が同グループの場合、ボタン1をTrue状態のまま操作できなくしても、 ボタン2が選択されるとボタン1はFalseになりますが。

merlionXX
質問者

お礼

ありがとうございました! ばっちりです。

その他の回答 (5)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

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

merlionXX
質問者

お礼

ありがとうございました。 今回はNo5さんの方法であっけなく解決しました。 今回はボタン操作で行うマクロですのでイベントは考えなくて良かったのです。 最初からそう書いておけばよかったですね、お手数をおかけしました。 すみません。

  • taocat
  • ベストアンサー率61% (191/310)
回答No.4

こんばんは。 なぜ、メソッド、プロバティが多くあるコントロールツールボックスを使わないのですか? で、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 以上です。  

merlionXX
質問者

お礼

ありがとうございます。 コントロールツールボックスならEnabled = Falseでいけるんですね。 今までフォームばっかりつかってきたので残念ながらコントロールツールボックスの方はうといんです。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

#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 これで、試してみてください。

merlionXX
質問者

お礼

Wendy02 さん、いつもありがとうございます。 Shapes(OBname).DrawingObject.Value = Empty ではオプションボタンのリンク先セルが0になってしまい、前の状態が保持されなくなってしまいます。 選択できないようにはするけど、前の状態は保持したいのです。 現在はリンク先のセルの前の状態を別セルにコピーしておき、オプションボタンを押された場合、別セルの値をリンク先にコピーして対応しています。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

merlionXX さん、こんばんは。Wendy02 です。 しばらく考えてみましたが、二つのロジックが考えられます。 (ちょっとお話がむつかしくなるかと思いますが) 最初に、そのオプションボタンを無効にするという、Range("A1")に、True/False を与えるものは、入力なのですか?式なのですか?それによって、設定が出来るような気がしています。式ですと、やっかいですね。それ自体には、イベントを発生させることはできませんので、常に、Now で Calculateイベントを発生させなくてはならなくなります。実用性が今ひとつ落ちます。 それから、もうひとつは、そのオプションボタンのイベントのコードは、OnAction ですね。だから、OnAction で、オプションボタンそのものを Enabled= False にするというのはできますが、それを、今度はEnabled =True と復帰する方法がなくなりますから、この選択はできませんが、少なくとも、OnAction で出力値そのものは、無効にすることが出来ますね。 どれか、ひとつで出来るはずです。この方法は、コントロールツール側でも、大きく変わることはないはずです。

回答No.1

ActiveSheet.Shapes("Option Button 1").Visible = False で、非表示にしてしまうとか.....。

merlionXX
質問者

お礼

さっそくありがとうございます。 Visible = Falseはわたしも考えたのですが、やはり一定条件下では選択できないことを明確にしたいので、その前の状態を保持しつつボタンが効かない状態にしたいのです。

関連するQ&A