[[20150921174014]] 『ユーザーフォームのコントロールの背景色を取得す』(田吾作) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『ユーザーフォームのコントロールの背景色を取得する』(田吾作)

 こんにちは、よろしくお願いいたします。

 ユーザーフォーム上のコントロールを特定のコントロール(クリックしたボタン)を除き使用不可にし、戻す、という
 コードを組んでいる途中です。

 コード実行でコントロールの使用不可、使用可を切替えます。
 また、使用不可を視覚的にわかりやすくするため、コントロールの背景をグレーにしています。

 使用可に戻した時に、コントロールの背景色をプロパティで指定している色に戻したいのですが、指定方法が
 分かりません。
 現状は、便宜的に白(VbWhite)にしていますが、プロパティで指定している色は白以外の色もあります。

 配列に色をグレーにする前の色を格納して置き、色を戻す時に配列から読み込んで戻す、というのもできると
 思いますが、プロパティで指定している色を取得する方法があったらその方法を取りたいと思います。

 ご存知の方、ご教示お願いいたします。

 Private Sub CommandButton2_Click()
  Dim con As Object
  Dim condic As Object
   Set condic = CreateObject("Scripting.Dictionary")
   condic.Add "CommandButton", ""
   condic.Add "ListBox", ""
   condic.Add "TextBox", ""
   condic.Add "ComboBox", ""
   condic.Add "Label", ""
   condic.Add "OptionButton", ""
   condic.Add "ToggleButton", ""
   condic.Add "ListView", ""
   condic.Add "Image", ""
   condic.Add "CheckBox", ""
   condic.Add "SpinButton", ""
   condic.Add "TabStrip", ""
   condic.Add "MultiPage", ""
   condic.Add "WebBrowser", ""
   condic.Add "ScrollBar", ""
   For Each con In Me.Controls
    If con.Name <> Me.CommandButton2.Name Then
       If con.Enabled = True Then
          If condic.exists(TypeName(con)) Then con.BackColor = &HC0C0C0
          con.Enabled = False
       Else
           If condic.exists(TypeName(con)) Then con.BackColor = vbWhite 'ここを、プロパティで指定している色に戻す記述にする
           con.Enabled = True
       End If
    End If
   Next con
   condic.RemoveAll
   Set condic = Nothing
 End Sub

< 使用 Excel:Excel2007、使用 OS:WindowsVista >


 コードに不具合がありましたので少し変えました。
 WEBBROWSERがあるとエラーになりました。

 Private Sub CommandButton2_Click()
  Dim con As Object
  Dim condic As Object
   Set condic = CreateObject("Scripting.Dictionary")
   condic.Add "CommandButton", ""
   condic.Add "ListBox", ""
   condic.Add "TextBox", ""
   condic.Add "ComboBox", ""
   condic.Add "Label", ""
   condic.Add "OptionButton", ""
   condic.Add "ToggleButton", ""
   condic.Add "ListView", ""
   condic.Add "Image", ""
   condic.Add "CheckBox", ""
   condic.Add "SpinButton", ""
   condic.Add "TabStrip", ""
   condic.Add "MultiPage", ""
   'condic.Add "WebBrowser", ""
   condic.Add "ScrollBar", ""
   For Each con In Me.Controls
    If con.Name <> Me.CommandButton2.Name Then
       If condic.exists(TypeName(con)) Then
          If con.Enabled = True Then
             con.BackColor = &HC0C0C0
             con.Enabled = False
          Else
              If condic.exists(TypeName(con)) Then con.BackColor = vbWhite
              con.Enabled = True
          End If
       End If
    End If
   Next con
   condic.RemoveAll
   Set condic = Nothing
 End Sub
(田吾作) 2015/09/21(月) 17:59

 配列に格納して置きそこから取り出す、という方法は↓で出来ました。
 プロパティを取得する方法ありましたら引き続きご教示お願いいたします。

 Dim condicB As Object

 Private Sub CommandButton2_Click()
  Dim con As Object
  Dim condic As Object
   Set condic = CreateObject("Scripting.Dictionary")
   condic.Add "CommandButton", ""
   condic.Add "ListBox", ""
   condic.Add "TextBox", ""
   condic.Add "ComboBox", ""
   condic.Add "Label", ""
   condic.Add "OptionButton", ""
   condic.Add "ToggleButton", ""
   condic.Add "ListView", ""
   condic.Add "Image", ""
   condic.Add "CheckBox", ""
   condic.Add "SpinButton", ""
   condic.Add "TabStrip", ""
   condic.Add "MultiPage", ""
   'condic.Add "WebBrowser", ""
   condic.Add "ScrollBar", ""
   For Each con In Me.Controls
    If con.Name <> Me.CommandButton2.Name Then
       If condic.exists(TypeName(con)) Then
          If con.Enabled = True Then
             con.BackColor = &HC0C0C0
             con.Enabled = False
          Else
              If condic.exists(TypeName(con)) Then con.BackColor = condicB(con.Name)
              con.Enabled = True
          End If
       End If
    End If
   Next con
   condic.RemoveAll
   Set condic = Nothing
 End Sub

 Private Sub UserForm_Initialize()
  Dim condic As Object
  Dim con As Object 
   Set condic = CreateObject("Scripting.Dictionary")
   condic.Add "CommandButton", ""
   condic.Add "ListBox", ""
   condic.Add "TextBox", ""
   condic.Add "ComboBox", ""
   condic.Add "Label", ""
   condic.Add "OptionButton", ""
   condic.Add "ToggleButton", ""
   condic.Add "ListView", ""
   condic.Add "Image", ""
   condic.Add "CheckBox", ""
   condic.Add "SpinButton", ""
   condic.Add "TabStrip", ""
   condic.Add "MultiPage", ""
   'condic.Add "WebBrowser", ""
   condic.Add "ScrollBar", "" 
   Set condicB = CreateObject("Scripting.Dictionary")
   For Each con In Me.Controls
    If condic.exists(TypeName(con)) Then
       If condicB.exists(con.Name) Then
       Else
          condicB.Add con.Name, con.BackColor
     End If
    End If
   Next con
 End Sub

 Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  condicB.RemoveAll
  Set condicB = Nothing
 End Sub
(田吾作) 2015/09/21(月) 18:23

 >>プロパティを取得する方法ありましたら引き続きご教示お願いいたします

 プロパティがあるかどうかの判断ですか?
 ないと思います。

 ところで、Enabled のみで、十分ではないですか? 色を変えずとも、見た目もはっきりとわかりますので。

 また書いておられるように、WebBrowserはEnabledもないですし、BackColor もないですよね。
 もしかしたら、コントロールの追加で、思いもしないコントロールもでてくるかもしれません。

 なので【汎用的なコード】として準備されるのであれば、エラートラップをかけて処理をするということに
 なるのでは? 

 あるいは、以下では、あまりに、あまりですかねぇ。

 Private Sub CommandButton2_Click()
    Dim ctrl As MSForms.Control

    For Each ctrl In Controls
        If ctrl.Name <> "CommandButton2" Then ctrl.Visible = Not ctrl.Visible
    Next

 End Sub

(β) 2015/09/21(月) 19:10


 βさん、ありがとうございます。

 オブジェクトを非表示ですと、エラートラップが不要になりますのでコード
 が簡素化出来ますね。こちらの方でコードを組んでみようと思います。

 一部のブックに、隠しコントロール(作業用に使っているListBox)がありますが、
 このブックは別途考えてみます。

 ありがとうございました。
(田吾作) 2015/09/21(月) 20:03

 独り言です。

 βさんご教示のコントロールを非表示にする方法で解決してますが、しつこく他の
 方法も試してみました。

 ↓はコマンドボタンクリックでラベルを表示しユーザーフォームのサイズいっぱいに
 拡げ、最前面化、ラベルWクリックでラベルを非表示にする、というものです。

 結果は、いくつかの種類のコントロールはラベルの前面に出てしまい、この方法は
 使えませんでした。

 Private Sub CommandButton2_Click()
  With Me.Label1
   .Caption = ""
   .ZOrder (0)
   .Visible = True
   .BackColor = &HC0C0C0
   .Top = 0
   .Left = 0
   .Width = Me.Width
   .Height = Me.Width
  End With
 End Sub

 Private Sub Label1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
  Me.Label1.Visible = False
 End Sub
(田吾作) 2015/09/22(火) 08:58

 そうですね。コンテナコントロール他、前面にでてしまうものがありますね。

 Label ではなく、Frame を使えば、すべてが覆い隠されると思います。

 なお、クリック時のプロパティのセットですが、デザインで設定しておけば
 割愛できるものが多そうですね。

(β) 2015/09/22(火) 09:26


 βさん、独り言におつきあいいただきありがとうございました。
 Frameで確認できました。
 ありがとうございました。
(田吾作) 2015/09/22(火) 10:33

 2015/09/22(火) 08:58のコードでおかしなところがありました。

 .Height = Me.Width

 .Height = Me.Height

 でした。
(田吾作) 2015/09/22(火) 15:13

こんにちは。

> プロパティで指定している色を取得する方法があったら

できると思います。
フォームモジュールオブジェクトのフォームオブジェクト、
そのコントロールに対してプロパティを取得するという手順になります。
(ユーザーフォームのコントロールではありません)

奥歯に物の挟まったような言い方になっているのはこれがちょっとアブナイ技術だからです。
上手に検索すればいろいろ見つかると思いますが、間違えてアブナイところに行かないように
気をつけてください。

( 佳 ) 2015/09/27(日) 08:45


 To 佳さん

 後学のため、教えてください。

 まず

 >>プロパティで指定している色を取得する方法

 これは、単純にといいますか、通常に コントロール.BackColor 等で取得できますよね。
 現在の、田吾作さんのQである、

 >>プロパティを取得する方法

 は、指定のコントロールに、たとえば BackColor というプロパティがあるかどうか。
 1つには、エラートラップをかませるということだろうと思いますが、そうしないで有無をチェックできないかということだろうと思います。

 で、仮に

 Set myControl = Application.VBE.ActiveVBProject.VBComponents("UserForm1").Designer.Controls("Image1")

 こんなコードでコントロールを取得したとして、確かにその配下には、様々なプロパティが存在するわけですが
 その中に BackColor があるかどうか、これは、やはり有無判定は不可能で、やるならエラートラップかなぁと そう思うんですが。

 Designer.Controls("コントロール名") 以外のオブジェクトなら配下のプロパティ名を取り出すということができるということでしょうか?

(β) 2015/09/27(日) 09:19


こんにちは。
βさん、コメントありがとうございます。

> >>プロパティを取得する方法
> は、指定のコントロールに、たとえば BackColor というプロパティがあるかどうか。
とは、わたしは考えませんでした。
単純に初期値の色に戻したい、と理解しています。

あるコントロールのBackColorを変更して、元の色に戻すときに
そのコントロールにBackColorプロパティがあるかどうか確認する必要があるでしょうか。

> これは、単純にといいますか、通常に コントロール.BackColor 等で取得できますよね。
はい、まえもって取得しておいて、元の色に戻すときに使うのですね。
ですが、前もって取得しなくても、必要なときにズバッと取得できるほうがよさげな感じが
するときもありますよね。(本当によいかどうかは別として)

そんなことがもし可能なら方法を知りたい、というご質問だと思います。

> プロパティで指定している色を取得する方法があったら
> >>プロパティを取得する方法
二度目は少し言葉を節約されたのでしょう。

( 佳 ) 2015/09/27(日) 10:19


こんにちは。

本件そもそもの目的は
 コントロールの使用可・不可を視覚的にわかりやすくする
ということだったはずなので

BackColorプロパティがない場合、じゃあどうやってそのコントロールの使用可・
不可を視覚的にわかりやすくできるのか気になります。エラーを回避しても
視覚的に表現できなければこのコードの意味がありません。
(βさんもおっしゃるとおり、Visible = Falseはあまりにも、、、です)

ともあれ、田吾作さんは大きな紙を1枚バサッと被せる方法をとられたので、それ
でいいのなら、Me.Heigth = 20 '数値は適宜 (いわゆるフォームの折り畳み)
でも良いのかもしれません。

( 佳 ) 2015/09/27(日) 12:48


 佳さん、βさん、書き込みありがとうございます。
 実は、最終目的は、↓と同じです。

[[20150821004804]] 『ユーザーフォームの全ての種類のコントロールに同』(田吾作)

 ユーザーフォームのどこでもドラッグ&ドロップできるように、ユーザーフォーム上のコントロール
 を一時的に使用不可にして、かつ、色を変える、終わったらコントロールの色を戻し、コントロール
 を使用可にする、ということです。

 詳細は割愛させていただきますが、↓のような感じでコントロールの情報が取得できました。

[[20150305215400]] 『フォーム内にあるテキストボックスのオブジェクト』(ななな)

 別エクセルを立ち上げ、そこに自ブックを読み取り専用で開き、ユーザーフォームの
 コントロールのプロパティを取得、ブックを閉じる、という方法です。

 まだコントロールの情報を取得するところまでしか作っていませんが、あとはなんとかできそうです。

 ※全てのコントロールを非表示にする、という方法で初期の目的は達成しています。

 >> プロパティで指定している色を取得する方法があったら 
 >> >>プロパティを取得する方法 
 >二度目は少し言葉を節約されたのでしょう。 

 分かりにくい書き方でした。
 佳さんのおっしゃる通り、最初の
 >プロパティで指定している色を取得する方法があったら 
 という意味でした。

 ↓でご教示いただきましたことも組み込んでいます。
[[20150922190811]] 『ユーザーフォームのキーイベントでマウス右クリッ』(田吾作)

 ユーザーフォーム上で右クリックでコントロールを非表示、右クリックや左クリック、
 またはESCキーでコントロール再表示、としました。
(田吾作) 2015/09/27(日) 14:40

 >>佳さんのおっしゃる通り、最初の
 >>>>プロパティで指定している色を取得する方法があったら 
 >>という意味でした。

 あぁ、βの早とちりだったようですね。

 で、そのテーマでいうと、(β) 2015/09/27(日) 09:19 で、

 >>仮に
 >>Set myControl = Application.VBE.ActiveVBProject.VBComponents("UserForm1").Designer.Controls("Image1")

 と、「仮に」とコメントさせていただいた通り、Designerは、文字通り、ユーザーフォームをデザインするための
 プラットフォームでしょうから、ユーザーフォーム表示中は、そのオブジェクトの取得はできないので
 別のアクセス経路が(もしあれば)必要ですね。

(β) 2015/09/28(月) 08:06


 βさん、レスありがとうございます。

 >Designerは、文字通り、ユーザーフォームをデザインするための
 >プラットフォームでしょうから、ユーザーフォーム表示中は、そのオブジェクトの取得はできないので
 >別のアクセス経路が(もしあれば)必要ですね。

 まだ検証不足なのかもしれませんが、ユーザーフォーム表示中でも、 2015/09/27(日) 14:40のレス
 の中の↓のようにすれば取得できました。

 >別エクセルを立ち上げ、そこに自ブックを読み取り専用で開き、ユーザーフォームの
 >コントロールのプロパティを取得、ブックを閉じる、という方法です。
(田吾作) 2015/09/28(月) 08:26

 >>別エクセル

 見おとしていました。了解です。
 (別エクセルを立ち上げるなら VBIDEを使わずとも、通常のコードでもできますね)

(β) 2015/09/28(月) 09:26


 >(別エクセルを立ち上げるなら VBIDEを使わずとも、通常のコードでもできますね)

 そうでしたか、勉強になります。ありがとうございました。
(田吾作) 2015/09/28(月) 09:32

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.