★★★ Access2000VBA・Excel2000VBA独学~「オブジェクトを取得する」とは?02 ~「色々な」「オブジェクトの取得方法」について(単一オブジェクトのプロパティやメソッドから取得する以外の方法も)~
  
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。

参考記事
★★★ Access2000VBA・Excel2000VBA独学~「オブジェクトを取得する」とは?01 ~「オブジェクトモデルの階層構造図」について~
用語:「オブジェクト変数」とは?(ついでに「コレクション」についても少し・・・)


  
  

「オブジェクトを取得する」とは、「オブジェクトをGETする」、「=パーツ、部品、ミニミニロボットをGETする」「1つ選択する」という感じでもあります。
(あるいは、オブジェクトに「接続する」というイメージでもいいかもしれません。)

イコール、「オブジェクト式を書く」ということでもあります。

そしてその「オブジェクト(=オブジェクト式)=パーツ、部品、ミニミニロボットをGETする」には(=各オブジェクトに接続するには)、以下のような方法があります。

(a)1階層「上位」の「単一オブジェクト」のプロパティが取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする。(位置関係などは上図もご参考に)
(例えば、Application.Workbooksプロパティや、Workbook.Worksheetsプロパティ、Worksheet.Rangeプロパティ、などを使い、それらが投げ返してくれるものをGETする。)

(b)1階層「上位」の「単一オブジェクト」のメソッドが取ってきてくれてユーザー側に投げ返して(渡して)くれるものをGETする。(こちらも位置関係などは上図もご参考に)
(例えば、Range.FindNextメソッド、Worksheet.PivotTablesメソッド、Workbook.NewWindowメソッド、Application.Unionメソッドなどを使い、それらが投げ返してくれるものをGETする。)

(c)(直接の)「上位」「ではない」、その他のオブジェクト(例えばコレクションなど)のプロパティやメソッドが取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(例えば、Workbooks.Itemプロパティ、Workbooks.Addメソッド、Worksheets.Itemプロパティ、Worksheets.Addメソッドなどを使い、それらが投げ返してくれるものをGETする。※AddメソッドやOpenメソッドなどは、「新規作成」や「開く」といった動作をしながら、「同時に」、それらの動かしたモノたちを「オブジェクトとしても投げ返してくれます」。)

(d)VBA(VBE6.DLL、あるいはVBA7.DLLなど)に属する関数が取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(例えば、CreateObject関数やGetObject関数などを使い、それらが投げ返してくれるものをGETする。)
※CreateObject関数やGetObject関数なども、メソッドと似てて、何らかの動作をしながら、同時に、それらのモノをオブジェクトとしても投げ返してくれます。例えばCreateObject関数は何かを「新規作成」をしながら、同時にそれをオブジェクトとしてエンドユーザー側に投げ返してくれます。
※「(VBE6.DLL、あるいはVBA7.DLLなど)に属する・属さない」はオブジェクトブラウザを見るとわかります。

(e)Office全体(MSO××.DLL)のオブジェクトに属するプロパティやメソッドが取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(例えば、CommandBars.Itemプロパティ、CommandBars.Add メソッド、などを使い、それらが投げ返してくれるものをGETする。)

(f)イベントの引数からオブジェクトをGETする
(例えば、Worksheet.SelectionChangeイベントなどの引数の「Target」、などを使い、それらが投げ返してくれるものをGETする。)

※1階層「上位」=親、1階層「上位」の「単一の」オブジェクト=親オブジェクト

※例えば、Rangeプロパティには、『 同名・かつ・「単一のセル・あるいは・セルの集まり」を取得してくれるプロパティ 』だけども、「でも少し性格の異なる」Rangeプロパティが存在します。
例えば「Worksheet.Rangeプロパティ」、「Range.Rangeプロパティ」、「AutoFilter.Rangeプロパティ」はすべて、「単一のセル・または・セルの集まり」を取得できるプロパティ(=「単一のセル・または・セルの集まり」に接続できるプロパティ)ですが、少しずつ性格が異なります。
親オブジェクトが異なるからです。
通常、親オブジェクトが変わると、性格も少しだけ異なってきます。なので、RangeはRangeでも「ワークシートのセルの集まり」の場合なら、「Worksheet.Range プロパティ」と表現して「ワークシートのRange(セルの集まり)ですよ」と明示的に表現しなければ「誤解を招いてしまいます」し、そもそも意図したプログラム動作になりません。
また、プロパティによっては、親オブジェクトの、さらに「親オブジェクト」もちゃんと書かないとエラーになる場合もあります。
このような親オブジェクトとセットでのプロパティの階層構造については、2010のヘルプには「Worksheet.Rangeプロパティ」、「Range.Rangeプロパティ」、「AutoFilter.Rangeプロパティ」といった形でしっかりと書いてあります。(2013のヘルプは一応出てくる場合の方が多いですが、2010のヘルプと比べると全然ちゃんとしてないし、誤作動みたいなものをよく起こします。2016のヘルプはわかりませんが2013と似ているかもしれません。)
4流以下の講師や4流以下の市販書籍著者、4流以下のライター、4流以下の編集者は、こういうところを説明しません。
なので、ExcelVBAが一向に上達しない・自力のエラー解決ができない生徒さんが量産されてしまいます。



では以下、若干の詳細説明です。

(a)1階層「上位」の「単一オブジェクト」のプロパティが取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(Excel、Word、Access、ユーザーフォーム、多くがこのパターンです。ExcelならWorksheet.Rangeプロパティ、Worksheet.QueryTablesプロパティ、Workbook.Worksheetsプロパティ、Application.Workbooksプロパティ、など。
Accessなら、Application.Formsプロパティなど。ユーザーフォームならUserForm.Controlsプロパティ、など。Accessやユーザーフォームのヘルプは、Excelのヘルプのように「 ×××オブジェクトを取得するには、×××プロパティを使用します」などと明確に書かれていないので間違えてしまいそうですが、例えばAccessならFormsプロパティというものが存在して、そこから単一フォームを取得しているようです。僕自身、今までコレクションで直接、フォームを取得していると誤解していました。)

※1階層「上位」=親、1階層「上位」の「単一の」オブジェクト=親オブジェクト



(b)1階層「上位」の「単一オブジェクト」のメソッドが取ってきてくれてユーザー側に投げ返して(渡して)くれるものをGETする
(Excelの場合、Application.Unionメソッド、Worksheet.PivotTablesメソッド、など。)
※1階層「上位」=親、1階層「上位」の「単一の」オブジェクト=親オブジェクト



(c)(直接の)「上位」「ではない」、その他のオブジェクト(例えばコレクションなど)のプロパh値やメソッドが取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(Excelの場合、Workbooks.Openメソッド、Workbooks.Addメソッド、QueryTables.Addメソッド、PivotTables.Addメソッド、など。OpenやAddは、ExcelのみならずOffice全体でも多くのコレクションオブジェクトが保持・保有・内包しているメソッドです。Openはどんなオブジェクトでもたいていは既存のものを開きながら、Addの場合は新規作成追加をしながら、それをオブジェクトとしてユーザー側に投げ返してくれます。プロパティも同様に存在します。)
※「コレクション=コレクションオブジェクト」です。

コレクションについて→→『~用語:ExcelVBA~「コレクション(=コレクションオブジェクト)」とは?~

※★★★ 超超超・重要事項!!!★★★ →→→ 1階層「上位」=親、1階層「上位」のオブジェクト=親オブジェクト、なんですが、コレクションオブジェクトは単一オブジェクトの「親」=「上位」という位置関係にはありません。
そして、階層が「親であること=1階層分、上であること」と、「複数の単一オブジェクトたちを束ねる・含む(束ねて管理しているだけ)」ということ、実は「まったくの別の事柄・べつもの」であり、もっと言うとまったくの「無関係」です。
このことは、VBAの学習(特に独学)にとって、「超重要事項」ですので、必ず意識しておきます。
でないと、ヘルプとオブジェクトブラウザの意味が通じなくなってしまう(=読めなくなってしまう)からです。


コレクションオブジェクトは、「複数の単一のオブジェクトを束ねる機能・単一オブジェクトたちをゴソと一括処理する機能」を有してはいますが、束ねてはいますが・でも・「親」の位置には「居ない」のです。「兄弟」的な位置に居るイメージです。
「兄弟」的な位置、「同じ階層」に居つつ・・・、でも、複数の単一オブジェクトたちを束ね・含み・管理している・・・というイメージです。
それは「オブジェクト式」の「ドット」の位置・・・、といいますか、「ドットからドットまでの間に記述されているもの」、を「よく観察」すれば、おそらく多くの方が「言われてみると確かにそうなっている・・・」とイメージ・実感できるのではないかと思います。
もともと、VBAにおける、オブジェクト式における、「1階層分」とは、「ドットからドットまで!」を指します。
もしコレクションオブジェクトが、単一オブジェクトの「1つ上の階層」に位置することになっているのであれば、コレクションだけででもドットからドットまでが占有されていないといけません。つまり、コレクションと単一オブジェクトの間にドットが無いといけない、ということになります。逆に、もしそうなっていれば『 コレクションは単一オブジェクトの「親」だ 』と言えます。
でも現実にはそんな風になってはいません。
例えばコレクションを指定したいときはカッコや引数を書かず、一方、単一オブジェクトを指定したいときはカッコや引数(名前やインデックス番号)を書く、という風に、「書き分けの違いがあるだけ」で、ドットからドットまでにもうひとつ、「コレクションの階層専用のドット」が入る・増えるわけではありません。
繰り返しになりますが、VBAにおける、オブジェクト式における、「1階層分」とは、「ドットからドットまで!」を指します。

「コレクションは複数の単一オブジェクトを含んでいる」「単一オブジェクトたちはコレクションに含まれている」という表現がよくなされます。当サイトでもそういう言い方をよくしますが、でも、だからといって、コレクションが単一オブジェクトの「親=1階層分、上」に位置しているわけではないのです。同じ階層(あるいは別の空間)に居る感じです。同じ階層(あるいは別の空間)に居つつ、単一オブジェクトたちを含み、管理しているイメージです。
そう、「含む」というより、「束ねて管理しているだけ」というイメージのほうが強いと思います。
(その証拠と言っては何ですが、たとえば「Sheetsコレクションオブジェクト」なんて、階層構造を全く無視して、ワークシートもグラフシートも含んで束ねて管理してしまっています。WorksheetオブジェクトやChartオブジェクトは同じ階層に居てお互いに上下関係は無いのに、両方をいっしょくたに管理しています。)
コレクションが単一オブジェクトの「1階層上」のオブジェクトだと誤解すると、VBAのオブジェクト構造の全体像がわからなくなり、オブジェクトブラウザやヘルプも読めなくなります(=意味が通じなくなります。)
結果(またまた繰り返しになりますが)、階層が「親であること=1階層分、上であること」と、「複数の単一オブジェクトたちを束ねる・含む(束ねて管理しているだけ)」ということ、実は「まったくの別の事柄・べつもの」「無関係」と考えるほうがいいと思います。そうすれば、オブジェクトブラウザやヘルプが読めるようになります(=意味が通じてきます。)




(d)VBA(VBE6.DLL、あるいはVBA7.DLLなど)に属する関数が取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(Excel、Word、Access、PowerPoint等共通で、GetObject関数や、CreateObject関数、など。GetObject関数は既存のファイルを開きつつ、それをオブジェクトとして投げ返してくれます。CreateObject関数は、新規のファイルを作りつつ、それをオブジェクトとして投げ返してくれます。なお、GetObject関数は、すでに開いている既存ファイルをパスがわからなくてもApplicationオブジェクトを取得できます。なので、それ経由で既に開いているファイルもオブジェクトとして取得できます。)


(e)Office全体(MSO××.DLL)のオブジェクトに属するプロパティやメソッドが取ってきてくれて、ユーザー側に投げ返して(渡して)くれるものをGETする
(Excel、Word、Access、PowerPoint等共通で、古いオブジェクトとメソッドですが例えば CommandBars.Addメソッド、など。プロパティも同じように存在します。)


(f)イベントの引数からオブジェクトをGETする
イベントの引数にオブジェクトが含まれる場合、そこからもオブジェクトをGETできることがあるそうです。
例えば、ワークシートをBeforeDoubleClickイベントには「Target」というRangeオブジェクトを表す引数があります。
なので、ダブルクリックしたセルのアドレスなどを、イベントプロシージャの実行中に調べることができます。
ThisWorkbookのSheetBeforeDoubleClickイベントでも同じことができます。すべてのシート共通にやれます。

  

※ちなみにですが、「一般変数」にとっての「生データ」は、「文字列や数値、日付データやTrue・False」といった文字ベースの値ですが、「オブジェクト変数」にとっての(言わば)「生データ」に相当するものは「オブジェクト式」・・・という感じになります。
「文字ベースの一般データ」は変数に代入しないと生のままでは扱いにくいのに、オブジェクトは変数に代入しなくても扱えてしまうので、それがVBA初心者にとっての混乱を招くもと・・・、かもしれません。
逆に言うと、『 常に、オブジェクトもできるだけオブジェクト変数に代入する 』というクセにしておく・それをちゃんと先生に習う、と、疑問点も的をついたものが増えはじめ、コピペばかりしている人と比べると十数倍か人によっては数十倍のスピードで上達すると思います。特に階層構造に疑問をもち、それが頭の中で省略せずにきちんとイメージでき、かつ、本記事でも言っていますように、「5つの機能」は「全部オブジェクトの中に内包されているんだ!それを命令や機能として内側から引き出して使うんだ!」ということが明確になると、さらに上達が早まると思います。それくらい、オブジェクト変数に代入することと、階層構造を省略しないことは、VBA初心者の学習にとって、死ぬほど重要です。ExcelVBAが上達しない人は、100%、オブジェクト変数が扱えず・”階層構造”や”内包”の「意味」が理解できていません。(教える側がしっかり教えないのである意味「犠牲者」、なんだと思いますけど・・・。)そのため、他の重要なほとどんどのことが理解できません。上達するわけがないのです。VBA(DAO、ADOも)のオブジェクトはどこもかしこも「階層構造」が「ベース」になっているのですから。「ベース」が理解できない人が上達するわけないのです。そしてそれが理解できないために設計に対しても無頓着になり、無駄な「絆創膏プログラム」を量産することになります。設計ができないために無駄なプログラムを書きすぎる羽目に陥るため、かえってメンテやらなんやらのコスト・その他のコストを上げてしまうという・・・。外注さんに任せることになったときもデータの持ち方からしてムダだらけで、払う必要のない・例えば「数十万以上の無駄料金」を払わされる羽目になってしまいます。