★★★★Access2000VBA・Excel2000VBA独学~(ユーザーフォーム上ではなく)「シート上」に作った、「フォームコントロール」と「ActiveXコントロール」の違いやオブジェクト取得の仕方など~
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
目次
★ 「ActiveXコントロール」の場合
▼ シート上に配置したActiveXコントロールの参照例(オプションボタンの場合・階層省略ほぼ無しで・Valueで。)」
▼ 「~~.OptionButton1」と「~~.OLEObjects("OptionButton1").Object.」の違いをどう捉えたら良いか? ~また、その使い分け方法について ~
★ 「フォームコントロール」の場合
★ シート上に作った、「フォームコントロール」と「ActiveXコントロール」のオブジェクト取得の仕方
※Shift+TABキー、もしくは、Homeキー、Homeキー+TAB数回、を押すと、目次付近に戻れます。
★ 「ActiveXコントロール」の場合
■■■ ActiveXコントロール ■■■
「MSForms」ライブラリの各コントロールと同じとみなして良いっぽいです。
結果、オジェクトブラウザもヘルプも使えます。
VBAコードがVBEから普通に書けます。
シート上に作った「ActiveXコントロール」の選択方法→デザインモードにしてクリックすると選択できます。
シート上に作った「ActiveXコントロール」は・・・、例えば「Sheet1」に作った「ActiveX系」の「オプションボタン」の場合、「VBAProject」ライブラリの「Sheet1」に、「OptionButton1プロパティ」として出てきます。
なぜかプロパティとして出てきます。
で、説明ペインを見ると「Property」で始まっていないので、「OptionButton1を取得するプロパティ」という感じではなさそう?です。よくわかりませんが・・・。
また、VBEのプロパティウィンドウでNameを変更して、例えば「OptionButton001」と変えると、オブジェクトブラウザの同じ場所に、「OptionButton001プロパティ」として出てきます。
そしてその説明ペインには「OptionButton001 As OptionButton」と出てきます。
ここでも「Property」や「Function」で始まっていなく、いきなり、「OptionButton001 」から始まっていますので、「単一オブジェクト」として捉えていいのかな~???という感じです。
でも(後述しますように)、「オブジェクトにジャンプする」「ジャンプするとオブジェクトに行きつく」ということは、結局は、単に「Property」が先頭に記述されていないだけで、「プロパティ」なのかもしれません。アイコン自体はプロパティのアイコンなので・・・。
もともとはワークシートに含まれるオブジェクトではなく、OLEObjectを介しての他のライブラリのオブジェクトだから、ということも何か関係しているのかもしれません。よくわかりませんが・・・。(埋め込みグラフの場合は、ChartObject埋め込み用オブジェクトを介しているとはいえ、一応、埋め込まれるのは「一応同じ ” Excel.exe ” のライブラリ」の中に保持される「グラフ」だから・・・。)
で、「As OptionButton」の「OptionButton」のグリーンのリンクを押すと、「Class OptionButton MSForms のメンバー」へ飛びます。
「Class OptionButton MSForms のメンバー」という記述から、オブジェクトモデルで表現できるオブジェクトであり、また、MSForms(ユーザーフォーム)のメンバであることが明確に分かります。
▼ シート上に配置したActiveXコントロールの参照例(オプションボタンの場合・階層省略ほぼ無しで・Valueで。)」
※プロパティウィンドウで「OptionButton001」という名前に変更したモノの場合。2つめの「OptionButton002」も作った場合
◎ Valueプロパティを設定する例
ワークシート上に作った「ActiveX系」のコントロールを扱うには、基本的には、MSForms(ユーザーフォーム)と同じなので、そのヘルプを読めばOKです。
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton001.Value = Ture
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton001.Value = False
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton002.Value = Ture
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton002.Value = False
以下のように「OLEObjectsコレクション」経由?でも書けるっぽいです。「.Object」を付加して。
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects("OptionButton001").Object.Value = Ture
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects("OptionButton001").Object.Value = False
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects("OptionButton002").Object.Value = Ture
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects("OptionButton002").Object.Value = False
「名前」ではなく「インデックス番号」を使うことももちろん可能です。
(※なお、CodeNameプロパティはもともとありません。それは、Chart、Workbook、WorkSheet、にしか無いようです。)
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects(1).Object.Value = False
また、「OLEObjectsコレクション」を使わない最初の書き方にも「.Object」を適用・付加して書くことができます。
つまり、
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton1.Object.Value
とも書けます。
が、後述しますような、「.Object を付けると出るエラー」と同じように、
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton1.Object.Name
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects("OptionButton1").Object.Name
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects(1).Object.Name
は、「そのプロパティはサポートしてない」というエラーになります。
「.Object」を付けるとValueプロパティはエラーが出ないのですが、Nameなどでエラーとなり、
つまりは、「~~.Worksheets("シート名").OptionButton1.」と書くメリットが無くなってしまいます。
「.OptionButton1」をダイレクトに書くだけにしておけば、すべてのプロパティやメソッドでエラーは出ないわけですので。
なお、「Nameプロパティ」の場合は、エラーを出さないようにするには、「.Object」を取って、
Application.Workbooks("ブック名").Worksheets("シート名").OptionButton1.Name
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects("OptionButton1").Name
Application.Workbooks("ブック名").Worksheets("シート名").OLEObjects(1).Name
とします。
基本、「OLEObjectsコレクション」を使うときは、上記のように、「.OLEObjects("コントロール名 or Index")」のあとに、「.Object」を付けたほうが良い場合と良くない場合があります。
「.Worksheets("シート名").OptionButton001.」ではなく「.Worksheets("シート名").OLEObjects("OptionButton001").」の書き方をした場合は、Valueプロパティなどは「.Object」を付けないとエラーになります・・・。
一方、Nameプロパティのように、『 逆に、「.Object」を付けるとエラーになる 』と、そういうプロパティもあります。(ActiveX系のオプションボタンの場合、AutoLoadプロパティほか。とか。)
これは、例えば、純粋にユーザーフォーム上にコントロールを作った場合は、埋込オブジェクトの「OLEObject」は生成されないわけなので、NameもValueも両方ともがOptionButtonオブジェクトのプロパティとして保持されるんだと思いますが、ユーザーフォームではなくて「シート上に作った場合に限って」は、埋込のOLEObjectだけにNameプロパティが付いていき、「.Object」のほうにはNameプロパティは保持されないっぽいです。(同様に、AutoLoadプロパティほか、も。)
「ChartObjects コレクション(あるいはChartObject単一オブジェクト)」とChart(グラフシート)との関係に似ているかも。
Chartオブジェクトの中には複数のグラフが存在できるけど、ワークシート上の「ChartObjectオブジェクト(埋め込み用オブジェクト)」の中にはグラフが1つしか存在できない・・・という、ちょっとオリジナルのChartオブジェクト(グラフシート)とは一部・異なった動きをする・・・みたいな。
ワークシート上には「ChartObject埋込用オブジェクト」は複数存在できるけど、その中のグラフは1個まで・・・みたいな。
結局のところ・・・、
「~~.Worksheets("シート名").OLEObjects("OptionButton001").Object.Value」は、
True/Falseが返ってきますが、
「~~.Worksheets("シート名").OLEObjects("OptionButton001").Object.Name」は、
「そんなプロパティはサポートしてない」とエラーになります。(あくまでも「シート上に」オプションボタンを作った時は。=なので、多分、他のActveX系のコントロールを作った時も注意。)
なので、シート上に「ActveX系の」コントロールを作ったときは、使いたいプロパティやメソッドが「OLEObject側(.OLEObjects(×××)側)」に保持されるのか、それとも、「OLEObject.Object側(.OLEObjects(×××).Object側)」に保持されるのかを事前にチェックしておく必要があるかもしれません。
もう少し別の言い方をすると、「OLEObjects埋込用コレクション側」に保持されるのか、それともその中身に含まれる「各種の個々の単一オブジェクト」に保持されるのかを、事前チェックしないといけない・・・、という意味です。
でないと、意図しないエラーが出ることになると思います。
なお、同様に、
? Application.Workbooks("ブック名").Worksheets("シート名").OptionButton1.Object.Value
と、最初に示した書きかたに「.Object」を付けて書くこともできます。
そしてこの場合は、「OLEObjectコレクション」を利用したときと同様に、Ture/Falseが返ってきますが、
? Application.Workbooks("ブック名").Worksheets("シート名").OptionButton1.Object.Name
は、これまた同様に、「そんなプロパティはサポートしてない」とエラーになります。
ところで、「.Object」と付けるのは、例えばAccessのサブフォーム指定に、「~~("埋め込みコントロール名").Form」と、「.Form」と書くのと同じだと思います。多分・・・。
「OLEObjects」はコンテナっぽいもの?・・・シート上の埋め込みグラフの「ChartObjects」のようなものかもしれないですね。
→調べたらヘルプに書いてありました。「OLEObjectsコレクションオブジェクト」。
→「各 OLEObject オブジェクトは、ActiveX コントロール、リンクされた OLE オブジェクト、または埋め込まれている OLE オブジェクトを表します。」とのことです。どうやらほぼ正解のようです。
なお、「OLEObjects」はプロパティではなく、「Worksheet.OLEobjects」という「メソッド」でした。
いずれにしましても、コレクションを取得しているので、Addとか、Copyとか、Deleteなど、コレクション系の命令も使えます。
TypeName関数での調査:イミディエイトでは、何故か 「フォームコントロールとして」のオプションボタンと同じ単語が返ってきます。
同じ単語だからと言って、同じものではないかもしれないし、同じかもしれないです。ちょっとわかりません。
? TypeName(Worksheets("Sheet1").OptionButton001)
OptionButton
▼ 「~~.OptionButton1」と「~~.OLEObjects("OptionButton1").Object.」の違いをどう捉えたら良いか? ~また、その使い分け方法について ~
まず、
「~~.OptionButton1」と「~~.OLEObjects("OptionButton1").Object.」
は、
「~~.ActiveX系コントロール名」と「~~.OLEObjects("ActiveX系コントロール名").Object.」
として、
捉えてください。
で、「考え方」の結論としては以降のようになるのではなないか?・・・と思います。
「Application.Workbooks("book1").Worksheets("Sheet1").OptionButton1」のような書き方・・・、つまり、「~~.OptionButton1」=「~~.ActiveX系コントロール名」のような書き方は、「VBE」の「プロパティウィンドウ」に「表示されたもの」を意味しています。
逆に言うと、VBEのプロパティウィンドウに表示されたモノ・・・とは(つまりユーザーフォーム上ではなくワークシート上に作ったActiveX系のコントロールとは)、「~~.OptionButton1」=「~~.ActiveX系コントロール名ダイレクト」、というようなオブジェクト式の書き方を意味している=それが想定されている=それが前提・・・ということです。
(※これはワークシートにおける
「Application.Workbooks("ブック名").Sheet1.××××・・・」
という書き方と似ているかもです。)
で、その書き方であれば、
「使えるプロパティ等々が変わってくる」
=プロパティ等々によって「エラーが出る・出ないが左右される」ということは起こりません。
「~~.ActiveX系コントロール名」 のあとに、普通にすべてのプロパティやメソッドがエラー無く、全部、書けます。
エラーは起こりません。
でも一方で、その書き方は、
・「コレクションとしての処理」
・「各コントロールのインデックス番号などを利用したい時」
・「コントロール名を変数で扱いたい時」
などに不便です。
なので、そのようなこをしたい時は、
「~~.OLEObjects("OptionButton1").Object.」・・・・
つまり、「~~.OLEObjects("ActiveX系コントロール名").Object.」
という、「OLEObjectsコレクションオブジェクト」を使った書き方を利用した方がいいんだと思います。
ただしその場合は、プロパティ等々を使う時に、「.Object」を付けた場合と付けない場合で「エラーが出る・出ない」が左右され、結果、「使えるプロパティなど」が変わってきてしまいます。
またVBEのプロパティウィンドウに表示されているモノとは「似て非なるもの」と思ったほうがいいです。
ですので、事前に、自分が使いたいプロパティ等が、「.Object」を付けたほうがいいモノなのか・それとも付けないほうがいいモノなのか?、をチェックしておく必要があります。
(前述しましたように、自分の使いたいプロパティ等が、「埋込用のOLEObjectsコレクションオブジェクト」に紐ついているモノなのか、逆に、その中に含まれる「単一オブジェクト」に紐ついているモノなのか、事前チェックする必要があります。)
ヘルプの「MsForms」ライブラリのActiveXコントロールのヘルプページで、オブジェクトメンバを調べ、それらのどれが、どちらになるかを、イミディエイトウィンドウなども利用して事前チェックしておく・・・・という感じです。
(※以上のことは、「~~.ActiveX系コントロール名」のあとに「.Object」を付けた場合も同じです。実は、例えば、「~~.OptionButton1.Object.~~」のようにも書けるからです。ただ、この書き方ではコレクションも使えないし、エラーが出る出ないも起こるので基本的には使いません。逆に、「使ってはいけない」、と言ったほうがいいかもです。)
=========================
=========================
★ 「フォームコントロール」の場合
■■■ フォームコントロール ■■■
調べてもよくわかりませんでした。
といいますのも、なぜか、オジェクトブラウザもヘルプも使えませんでした(ヘルプでは途中のダイアログまでは出るのに、最終的な内容が出ません)。
いずれにしましても、シート上に作った「フォームコントロール系」のコントロールの場合、VBAコードが、VBEから普通に・直接は書けません。
ひとまずは、マクロの登録か、新規の自動記録、しかできません。
ただし、記録されたり・新規マクロ登録をしてからならば、そのSubプロシージャ自体は、もちろん「マクロ」メニューの「編集」ボタンからVBEにて編集できます。
しかし、ActiveXコントロールのように、「コントロールのダブルクリックでいきなりVBEを開く」、というようなことはできないようです。
シート上に作った「フォームコントロール」の選択方法→デザインモードにしなくても大丈夫です。右クリックで選択できます。
※フォームコントロールのコントロール名は、ActiveX系のものとは似た名前ですが異なります。スペースを含みます。(バージョンによっては、英語ですらなく、カタカナかもしれません。)
Nameプロパティで調べられます。
が、逆に、VBEのプロパティウィンドウは使えず、
Nameプロパティでしか調べたり設定したりができません。
もちろん、VBEのプロパティウィンドウでは名前の書きかえはできません。
※保持・保有するプロパティなどもActiveX系のものとは異なるっぽいです。ActiveXコントロールのほうのプロパティを試したら、エラーが出たので・・・。出ないものもありますが・・・。
※また、もちろん「OLEObjectsコレクション」の中に埋め込まれるかたちではなく、「各フォームコントロール毎」に、「コレクションが存在する」形っぽく見えます。
※2010では、ヘルプが開きそうで途中の選択ダイアログが出るのに、そこから先が出ません。
オブジェクト式としては、(もちろん埋込み形式ではなく)普通の単一オブジェクトのように指定できます。
たとえば次のように。
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons(インデックス番号).Value = True
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons("コントロール名").Value = False
そして、OLEObjectsコレクションのように、埋込オブジェクトがコレクションになるのではなく、オプションボタン、テキストボックス、リストボックス、等々「毎に」、コレクションが存在します。
以下、その例です。
◎インデックス番号での指定の例
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons(1).Value = True
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons(1).Value = False
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons(2).Value = True
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons(2).Value = False
◎コントロール名での指定の例
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons("Option Button 1").Value = True
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons("Option Button 1").Value = False
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons("Option Button 2").Value = True
Application.Workbooks("ブック名").Worksheets("シート名").OptionButtons("Option Button 2").Value = False
※コントロール名はNameプロパティで調べられます。
が、逆に、VBEのプロパティウィンドウは使えず、
Nameプロパティでしか調べたり設定したりができません。
もちろん、VBEのプロパティウィンドウでは名前の書きかえはできません。
TypeName関数での調査:イミディエイトでは、何故か 「ActiveXコントロールとして」のオプションボタンと同じ単語が返ってきます。
同じ単語だからと言って、同じものではないかもしれないし、同じかもしれないです。これもちょっと分かりません。
? TypeName(Worksheets("Sheet1").OptionButtons(1))
OptionButton
★ シート上に作った、「フォームコントロール」と「ActiveXコントロール」のオブジェクト取得の仕方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
' ' Attribute VB_Name = "シートのコントロールの取得" Option Explicit '################################################################# 'TEST:「一応すべて」の「ActiveXコントロール」のチェックボックスを '「チェックON」かどうか調べ、チェックONのものがあったら、 'その時点で(途中であっても)終わる。 '################################################################# Sub checkbox() Dim 埋込コントロール As OLEObject Dim チェック状態 As Boolean チェック状態 = False ' For Each 埋込コントロール In Controls '質問者記入:エラーメッセージがでる。 For Each 埋込コントロール In Worksheets("sheet1").OLEObjects If TypeName(埋込コントロール.Object) = "CheckBox" Then ' If 埋込コントロール.Value = True Then If 埋込コントロール.Object.Value = True Then チェック状態 = True Exit For End If End If Next If チェック状態 = False Then MsgBox "選択されていません。" Exit Sub End If End Sub '################################################################# 'チェックボックスが「ActiveXコントロール」の場合の '「チェックON」されたコントロール名の取得。チェックONのものがあったら、 'その時点で(途中であっても)終わる。 '################################################################# Sub checkbox02() Dim 埋込コントロール As OLEObject Dim チェック状態 As Boolean Dim s_CtlName As String チェック状態 = False For Each 埋込コントロール In Worksheets("sheet1").OLEObjects If TypeName(埋込コントロール.Object) = "CheckBox" Then If 埋込コントロール.Object.Value = True Then チェック状態 = True s_CtlName = 埋込コントロール.Name Exit For End If End If Next If チェック状態 = True Then MsgBox s_CtlName & "にチェックが入っているっぽいです。" ElseIf チェック状態 = False Then MsgBox "選択されていません。" Exit Sub End If End Sub '################################################################# 'チェックボックスが「フォームコントロール」の場合の '「チェックON」されたコントロールの取得。チェックONのものがあったら、 'その時点で(途中であっても)終わる。 '################################################################# Sub checkbox03() Dim コントロール As checkbox Dim チェック状態 As Boolean Dim s_CtlName As String チェック状態 = False For Each コントロール In Worksheets("sheet1").CheckBoxes If TypeName(コントロール) = "CheckBox" Then If コントロール.Value = 1 Then チェック状態 = True s_CtlName = コントロール.Name Exit For End If End If Next If チェック状態 = True Then MsgBox s_CtlName & "にチェックが入っているっぽいです。" ElseIf チェック状態 = False Then MsgBox "選択されていません。" Exit Sub End If End Sub '################################################################# 'TEST '################################################################# Sub checkbox0あああ3() Dim コントロール As Object Dim チェック状態 As Boolean チェック状態 = False For Each コントロール In Worksheets("sheet1").CheckBoxes '質問者記入:エラーメッセージがでる。 If TypeName(コントロール) = "CheckBox" Then If コントロール.Value = 1 Then 'チェックONなら1、チェックOFFなら-4146 チェック状態 = True Exit For End If End If Next If チェック状態 = False Then MsgBox "選択されていません。" Exit Sub End If End Sub '################################################################# 'TEST '################################################################# Sub test99() Dim chk01 As checkbox Set chk01 = Worksheets("sheet1").CheckBoxes(1) Debug.Print chk01.Caption End Sub ' ' |
- 投稿タグ
- 「ニセモノ」への道, 「本物」に近づくために, AccessVBA, Accessの独学, Access操作の基礎, Accesの独学, ExcelVBA, Excelの独学, Excel操作の基礎, Excel連携VBA, パソコンでの自動化, マクロ, 独学, 自動化