• ベストアンサー

マクロ ユーザーフォームについて

いつも回答して頂き、ありがとうございます。 フレームの中にオプションボタンを設定し、更に別のフレームの中にオプションボタンを設定。 上記の時、各フレームのオプションボタンを押すと、各フレームにあるどれか1つだけオプションボタンを同時にTRUEに出来ますが、これを片方をTRUEにした時、もう片方のフレームにあるオプションボタンをFALSEにしたいのですが、こんな事可能なのでしょうか?ネットで確認しましたが、分からない為、出来るか出来ないか教えて頂けないでしょうか?宜しくお願い致します。 ※自分はフレームをただ用途に応じて分け、見た目を良くしたいだけなのです。

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

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.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 ' ' ============================================================

kero1192kero
質問者

お礼

返事が遅れて申し訳ありません。 フレームを使用しても、記述の方法で十分かのうだったんですね。しかも高速化までして頂きありがとうございました。

その他の回答 (3)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.3

#2、cjです。すみません訂正が1点。 誤> (順番が前後した場合はOptionButtonを切り取りFrame上に貼付け、とか) 正 (順番が前後した場合はOptionButtonを切り取りLabel上に貼付け、とか) でした。失礼しました。

kero1192kero
質問者

お礼

修正ありがとうございます。

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

こんにちは。お邪魔します。 まず、 デザインそのままで実現するなら、こんな感じ。 ' ' ============================================================ ' ' 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のデザイナー画面で、 各種コントロールの初期設定可能なプロパティを プロパティウィンドウを弄りながら覚えておくと、 色々な可能性が見えてくると思います。 誰に教わるでなく弄りながら覚えた、という人が多いと思いますが、 私もその内の一人です。

kero1192kero
質問者

お礼

色々説明して頂きありがとうございました。 ネットで見てもあまり書いている事が少ないので、自分で色々弄ってみるのもありかなと思いました。大変参考になりました。

  • m3_maki
  • ベストアンサー率64% (296/460)
回答No.1

見た目だけの問題なら フレームを使用せずに ラベルをフレームのように見せかければ良いでしょう。 フレームの枠の部分は ラベルのプロパティ  BackStyle : 0  SpecialEffect : 3  Caption : (削除してください。) フレームの標題部分にはもう1個ラベルを重ねます。 プロパティは、多分デフォルトのままで大丈夫でしょう。 その後、オプションボタンを配置します。

kero1192kero
質問者

お礼

ラベルに枠とか設定できたんですね。知りませんでした。これで十分です。ありがとうございました。

関連するQ&A

専門家に質問してみよう