- ベストアンサー
マクロ ユーザーフォームについて
いつも回答して頂き、ありがとうございます。 フレームの中にオプションボタンを設定し、更に別のフレームの中にオプションボタンを設定。 上記の時、各フレームのオプションボタンを押すと、各フレームにあるどれか1つだけオプションボタンを同時にTRUEに出来ますが、これを片方をTRUEにした時、もう片方のフレームにあるオプションボタンをFALSEにしたいのですが、こんな事可能なのでしょうか?ネットで確認しましたが、分からない為、出来るか出来ないか教えて頂けないでしょうか?宜しくお願い致します。 ※自分はフレームをただ用途に応じて分け、見た目を良くしたいだけなのです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#2、3、cjです。追加レスです。 #2で提示したサンプルコードですが、 中途半端で動作も重く若干問題アリなので丸ごと書き換えました。 本題から逸れているのかも知れませんが、放置できなかったので、、、。 それから、説明が不足していた点を補足します。 Labelの上にOptionButtonを配置する、という言葉通りのことは出来ません。 正確には、Labelより前面にOptionButtonを配置する、でした。 初期デザインの際、 Frameの場合は、Frameを移動するだけで配下のOptionButtonも移動しますが、 LabelとOptionButtonの場合、一緒に移動させるには、 添付画像のように 一旦、LabelとOptionButtonの一群を、すべて覆うようにドラッグして選択してから、 一番外の黒く見える枠の部分をドラッグして、まとめて移動します。 この点は少しだけ、Frameより扱い難いかも知れませんね。 以下、#2の差し替え分です。 今お使いのままのデザインを維持して実現するサンプルについて、 レスポンスの遅さを解消しました。 OptionButton1 から OptionButton10 まである条件で書いてありますが、 OptionButtonの数や、オブジェクト名に合わせて試してみてください。 ' ' ====================Userformモジュール====================== ' ' ----宣言部-------------------------------------------------- Private colcFrames As Collection ' ' ----イベント------------------------------------------------ Private Sub OptionButton1_Click() Call CrossGroup End Sub Private Sub OptionButton2_Click() Call CrossGroup End Sub Private Sub OptionButton3_Click() Call CrossGroup End Sub Private Sub OptionButton4_Click() Call CrossGroup End Sub Private Sub OptionButton5_Click() Call CrossGroup End Sub Private Sub OptionButton6_Click() Call CrossGroup End Sub Private Sub OptionButton7_Click() Call CrossGroup End Sub Private Sub OptionButton8_Click() Call CrossGroup End Sub Private Sub OptionButton9_Click() Call CrossGroup End Sub Private Sub OptionButton10_Click() Call CrossGroup End Sub ' ' ・ ' ' ・ ' ' ・ Private Sub UserForm_Initialize() Dim oCtrl As MSForms.Control Dim cnt As Long Set colcFrames = New Collection For Each oCtrl In Controls If TypeName(oCtrl) = "Frame" Then cnt = cnt + 1 oCtrl.Tag = cnt colcFrames.Add oCtrl, oCtrl.Name End If Next End Sub Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) Set colcFrames = Nothing End Sub ' ' ----メソッド------------------------------------------------ Private Sub CrossGroup() Dim nSkipIdx As Long Dim i As Long nSkipIdx = Val(ActiveControl.Tag) On Error Resume Next For i = 1 To colcFrames.Count If i <> nSkipIdx Then colcFrames(i).ActiveControl.Value = False Next i On Error GoTo 0 End Sub ' ' ============================================================
その他の回答 (3)
- cj_mover
- ベストアンサー率76% (292/381)
#2、cjです。すみません訂正が1点。 誤> (順番が前後した場合はOptionButtonを切り取りFrame上に貼付け、とか) 正 (順番が前後した場合はOptionButtonを切り取りLabel上に貼付け、とか) でした。失礼しました。
お礼
修正ありがとうございます。
- cj_mover
- ベストアンサー率76% (292/381)
こんにちは。お邪魔します。 まず、 デザインそのままで実現するなら、こんな感じ。 ' ' ============================================================ ' ' Userformモジュール Private Sub OptionButton1_Click() Call ClossFrames End Sub Private Sub OptionButton2_Click() Call ClossFrames End Sub Private Sub OptionButton3_Click() Call ClossFrames End Sub ' ' ・ ' ' ・ ' ' ・ Private Sub ClossFrames() Dim oCtrl As MSForms.Control Dim sFrame As String sFrame = ActiveControl.Name ' ★ On Error Resume Next ' ◆ For Each oCtrl In Controls ' ★ If TypeName(oCtrl) = "Frame" Then If oCtrl.Name <> sFrame Then ' If Not oCtrl.ActiveControl Is Nothing Then ' ◇ With oCtrl.ActiveControl If .Value Then .Value = False End With ' End If ' ◇ End If End If Next End Sub ' ' ------------------------------------------------------------ ' ' ※もしもUserformモジュールとは別にクラスモジュールを設定している場合は ' ' sFrame = Userform1.ActiveControl.Name ' ★ ' ' For Each oCtrl In Userform1.Controls ' ★ ' ' 2カ所、親オブジェクトを指定してあげてください。 ' ' ※コメントブロックしている ' ◇マークの2行は、 ' ' ◆行の(どちらかを選ぶ)オプションです。 ' ' On Error の方が効率的ですが、 ' ' 食わず嫌いの方が結構いらっしゃるので、念の為添えておきます。 ' ' ============================================================ ただ、Frameコントロールは、そもそも、 配下に複数のOptionButtonを配置して、 排他的・閉鎖的なグループを構成した選択肢を実現する為にあるものですから、 端からその必要がないのなら、Frameコントロールを使うのは、 目的が違ってしまいます。 上に挙げたコードでの対応は、Frameを越えて、 OptionButtonのグループを可変に、する為のものです。 グループが固定でいいなら、Frameを使わなければ簡単なのです。 #1さんご回答のように、 Userformの初期デザインの段階で、まずラベルを配置してから その上にOptionButtonを配置するようにすれば簡単に実現できます。 (順番が前後した場合はOptionButtonを切り取りFrame上に貼付け、とか) 或いは、Userform全体として複数のグループを設け、 それぞれに装飾的な枠を表現したい、という場合は、 まず、グループ単位でFrame、その上にLabel、その上にOptionButtonのようにします。 時間のある時にでも、Userformのデザイナー画面で、 各種コントロールの初期設定可能なプロパティを プロパティウィンドウを弄りながら覚えておくと、 色々な可能性が見えてくると思います。 誰に教わるでなく弄りながら覚えた、という人が多いと思いますが、 私もその内の一人です。
お礼
色々説明して頂きありがとうございました。 ネットで見てもあまり書いている事が少ないので、自分で色々弄ってみるのもありかなと思いました。大変参考になりました。
- m3_maki
- ベストアンサー率64% (296/460)
見た目だけの問題なら フレームを使用せずに ラベルをフレームのように見せかければ良いでしょう。 フレームの枠の部分は ラベルのプロパティ BackStyle : 0 SpecialEffect : 3 Caption : (削除してください。) フレームの標題部分にはもう1個ラベルを重ねます。 プロパティは、多分デフォルトのままで大丈夫でしょう。 その後、オプションボタンを配置します。
お礼
ラベルに枠とか設定できたんですね。知りませんでした。これで十分です。ありがとうございました。
お礼
返事が遅れて申し訳ありません。 フレームを使用しても、記述の方法で十分かのうだったんですね。しかも高速化までして頂きありがとうございました。