● Access2000VBA・Excel2000VBA独学~★★★超重要!!!「実際の機能や画面等々」と「VBAオブジェクト」との対応。例えば「Application」って何?Workbookとの関係は?
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
目次
★ はじめに
★ (01)「Applocationオブジェクト」
★ (02)「Workbookオブジェクト(単一)」
★ (03)「Workbooksコレクションオブジェクト(=Workbooksコレクション)」
※Shift+TABキー、もしくは、Homeキー、Homeキー+TAB数回、を押すと、目次付近に戻れます。
本記事は、VBA初心者の方への記事です。
以下の記事もお読みなって、「オブジェクトって何?、オブジェクト変数って何?、コレクションって何?」、ということをなんとなくでイメージしてもらえると、本記事もなんとなくわかっていただけるかもしれません。
● 「オブジェクト」について
用語:VBAプログラミングでの「オブジェクト」 について
『用語:「オブジェクト変数」とは?(ついでに「コレクション」についても少し・・・) 』
● 「プロパティ」について
用語:VBAプログラミングでの「プロパティ」 について
● 「メソッド」について
用語:VBAプログラミングでの「メソッド」 について
『Access2000VBA・Excel2000VBA独学~VBAプログラミングとはどんなプログラミング方式なのか?(簡易版)』
『Access2000VBA・Excel2000VBA独学~VBAプログラミングとはどんなプログラミング方式なのか?~その2(詳細版:巷では意外と分類・整理・説明されていないこと)』
↑この2000のヘルプによる「オブジェクトモデルの階層構造図の全体図は、ちょっと形が変わりますが、Webにもあります。
MSサイト→こちら /少し見やすく横につなげたもの→こちら /Excel2000の色付きの見やすいものを全部つなげたもの→こちら
うまく説明できていないですけど、よろしくお願いいたします。
前々から、「実際の画面や機能・各種設定等々」の「絵」と、「VBAオブジェクトやプロパティ」とオブジェクトモデルの階層構造図というか、対応表みたいなのがあればなあ・・・、と思っていました。
僕はExcelVBAはそれほど詳しくないんですけど、これだけ使う人が多くて、20年以上も経ってるのに、なんでそういう情報が少ないのかがよく分かりません。
なんで誰も絵にしないんですかね?
なんで、適当な絵図じゃなくて、もっと詳しい「絵」で説明してくれないんですかね?
Excelのレジェンドさんたちは。
ここでは、「こんな本出してくれよ」とレジェンドさんたちに伝えたい絵図を書いていきます。
とはいうものの・・・
本記事ではほんとうはそういった絵図を作ってみたいなあ、と思ったんですが、量が膨大すぎてできないので、でも、少し気になるとことを逐次、メモっていこうかなと思ってます。
というわけで、まずは「Applocationオブジェクト」から・・・。
======================================
★ (01)「Applocationオブジェクト」
Excelは2010までは親ウィンドウと子ウィンドウがあります。2013以降はそれが無くなりました。
2010まででは「Applocationオブジェクト」は「ガワ」というか、その親ウィンドウのことをさしていると考えて良いと思います。
↓この、子ウィンドウがないやつ。
この絵(画面)は、Excelの設定によっては「非表示」にもできるので、この絵の「表示されたもの、のみならず、非表示にされたもの、の両方」が、「Applocationオブジェクトだ」ということになります。
※「非表示にされたもの」は、あくまでも「非表示になっただけ」でして、「裏方ではちゃんと起動して・かつ・開かれた状態」、と思って頂ければ結構です。ただ、その挙動は、もしかしたら「表示された状態」と多少、異なる部分も出てくるかもしれません(僕は未経験なのでわかりませんが・・・。)
コンピュータはアホというか「人間っぽい部分」もあって、「いつも同じ動きをするとは限らない」ので、そのことを是非、頭の中に入れておいてください。
このような考え方は「エラーや不具合解決」などにとても有効です。
2013以降は(図が2010ですみませんが)、こんな感じで、シート(というかブック)が一緒にくっついてきてしまい、シートが見えてない状態は「無い」感じです。そんな感じで「Applocationオブジェクトが見えてしまっている状態・・・だと思います。
でも、この場合でも、シート以外の(リボンとか数式バーとかを含む)「ガワ」のへんの絵の部分が、「Applicationオブジェクトだ」ととらえればよいと思います。
(もしかしたらリボンはExcelとは別物で「Office全体のためのもの」かもしれませんが。ただ、初心者のうちは暫定的に含めて考えてしまってもよいと思います。リボンを操作するプログラムを作るようになるまでは。リボンのボタンを自由に入れ替えするようなプログラムを作りたくなったとき、切り離して考えればよいと思います。)
『オブジェクトモデルとしてはApplocationオブジェクトとWorkbookオブジェクトは分かれているんだけれども、表示だけが統合されて一緒にしか表示できなくなってしまった・・・分けて表示できなくなってしまった・・・・』、という感じで理解してもOKだと思います。
「Applicationオブジェクト」は、Excelのオブジェクトモデルの階層構造図の「トップレベル」「最上階」のオブジェクトとなります。つまり、これが「ガワ」です。
VBAプログラムに書く「オブジェクト式」としては、
Application
と書くだけです。
「Applicationオブジェクトでできること」は、「Application メンバ Excel」という検索語句でGoogle検索すると一覧が出てきます。(このWebページ内の検索機能で「オブジェクト名 メンバー Excel」で検索しても色々と出てきます。そのほうがGoogle検索するよりも確実かも?例えば「Workbook メンバー Excel」で検索。トップに出てこないときもあるので数ページ見てみます。
列挙を調べる場合は、
https://docs.microsoft.com/ja-jp/office/vba/api/excel(enumerations)
にアクセスすると、列挙の一覧があるので、そこからCtrl+Fで検索してリンクをクリック。列挙だけでなく、オブジェクトのヘルプもここから見れます。定数を調べたいときは、先にオブジェクトブラウザでどの列挙に属する定数かを調べてから、それが判明したら、上記URLで列挙を探し、定数を探します。なお、列挙や定数は、Mso(Officeのもの)Vb(VBA?のもの)などxl(Ecelのもの)と異なる分類の定数や列挙もありますので、そちらの場合は、Google検索や2010のヘルプがいいと思います。)
そこに出てきた、「イベント」「メソッド」「プロパティ」の各要約を読めば、なんとなく、「Applicationオブジェクト」が・どんなことができるオブジェクトなのかがイメージできると思います。また、リボンや右クリックメニューなどと結びつくような内容も見えてくると思います。
「イベント」「メソッド」「プロパティ」、は、それぞれのオブジェクトが「保持・保有・内包」しているものです。(というイメージです。つまり、「メンバ」=「オブジェクトに内包されるもの」=「イベント」「メソッド」「プロパティ」という意味でもあります。)
なお、「イベント」「メソッド」「プロパティ」はオブジェクトによっては「イベント」だけが無かったり、「メソッド」だけが無かったり、あるいは両方無かったり、ということがあります。ただ、「プロパティ」だけは絶対にあります。
なので、プログラミング的に言うと「プロパティ」を持つものは「絶対にオブジェクトだ」とも言えます。(ついでに言うと階層構造を持つもの、そもそもオブジェクトモデルの階層構造図に載っているものも絶対にオブジェクトです。)
あと、オブジェクトには、セルやシートのように、画面上に目に見えるものと、裏方で動く目に見えないものがあります。で、(ちゃんと確認していないのですみませんが)「イベント」は、目に見えるオブジェクトたちのほうがたくさん持ってて、目に見えないオブジェクトたちでは少ないかもしれません。ご自分でもチェックしてみてください。(後述の「コレクション」と呼ばれるオブジェクトは目に見えないことが多いです。)
どのオブジェクトがどんなイベントを持っているかをある程度把握できていれば、プログラムの全体像を作りやすかったり、何かの役に立つかもしれません。
なお、「イベント」「メソッド」「プロパティ」についての簡単な説明は以下のとおりです。
▲「イベント」→「プログラムを自動的に動かせるよ!自動実行できるよ!」という合図・信号のことです(意訳)。あるいは、各オブジェクトにおける「そのオブジェクトがらみの何らかのプログラムを ” 自動実行する ”」ための機能、と考えても良いと思います。
なので当サイトでの「××××××イベントが発生します。」という文は、「××××××イベントが発生し、そのタイミングでプログラムを自動実行できます。」と読み替えて下さい。(ヘルプでも同様です。)
あるいは、少し長ったらしく書くと、『 ××××××イベントという ”プログラムを自動的に動かせるよ!” という合図・信号が発生しますので、そのタイミングでプログラムを自動実行できます。』という感じです。
なお、「イベント」で自動実行できるのは「イベントプロシージャ」と呼ばれるタイプのプログラムだけです。
※「イベントプロシージャ」は、Subプロシージャの仲間ですが、原則、(標準モジュールには書いたSubプロシージャのように)他の場所から簡単に呼び出すことができません。イベントが発生したときだけに動くSubプロシージャで、普通には呼び出すことができません。(ただし、少し工夫をすると呼び出すこともできます。その場合、イベントが発生していなくても、さもイベントが発生したかのように、イベントプロシージャを好きな時に動かすことができます。)
なお、イベント保有していないオブジェクトもあります。
▲「メソッド」→特定のオブジェクトに紐付いた、そのオブジェクトだけで使える命令語句です。オブジェクトを「具体的に動かす」ための機能、という感じです。
「開く、閉じる、印刷する、サイズを変える、コピー、貼り付け・・・」等々の画面で、「リボン」「メニュー」「右クリックメニュー」「コマンド」として目に見えるものもあれば、裏方で働く目に見えない命令もあります。
「オブジェクトを動かす」といった場合、この命令語句を使うことが多いです。
「オブジェクトを動かす」ために、その中心となる命令語句です。
(文字ベースの一般データ、つまり、文字列・数値・日付・2値などを操作するときには原則、使いません。オブジェクトに対してだけ、使います。)
なお、メソッドを保有していないオブジェクトもあります。
参考:実際のメニューとメソッドの関係
(下リンクの図は、「セル」を右クリックした場合限定です。右クリックするオブジェクトがグラフやオートシェイプだと、画面の見た目的には同じ「コピー」や「切り取り」のメニューでも、VBAプログラム的には、親オブジェクトがRangeではなく、グラフ(ChartObject=ワークシートへのグラフの埋め込み枠)やオートシェイプ(Shape)に変わります。)
『Access2000VBA・Excel2000VBA独学~用語:”目に見える”「メソッド・プロパティ・列挙(=Enum)・定数(=Const)」と右クリックメニューの画面の関係について~』
▲「プロパティ」→そのオブジェクトの特性・性質・性格・状態、を決めるための各種の設定値です。あるいは、オブジェクトに対してそういう「各種設定をする」ための機能、と考えても良いと思います。
大きさ、色、位置、形状、明るさ、枠線の状態、塗りつぶしの状態、その他、いろんな性格・状態を決めることができます。また、ExcelのセルやWordのシート、横書きテキストボックスなどのオブジェクトだと、そのなかにユーザーからの入力値も保持します。
位置などは1秒ごとに値を変えていくと、上下左右に動いてるようにも見せることもできます。
直接オブジェクトを動かすわけではありませんが、命令語句の一種といえばもしかしたらそう言えるかもしれません。
(こちらも、文字ベースの一般データ、つまり、文字列・数値・日付・2値などを操作するときには原則、使いません。オブジェクトに対してだけ、使います。)
なお、プロパティを保有していないオブジェクトはありません。
▲ついでに「オブジェクト」→イメージで言うと「複数の機能が集合したユニット」のことです。短く「複合機能体」「複数の機能の集合体」ととらえてもよいと思います。
ある意味、「ミニミニロボット」というイメージかもしれません。
オブジェクトは、「大きい・小さい・目に見える・見えない」にかかわりません。大きくても小さくても、目に見えても見えなくても、「複数の機能が集合したユニット・複合機能体・複数の機能の集合体」であるなら、それは「オブジェクト」です。(プログラミング的に言うと、最低限、プロパティか階層構造を保持していればそれは必ず”オブジェクト”です。)
例えば目に見えるモノなら、例えばExcelなら、セル、ワークシート、グラフ、図(シェイプ)、画像、各種メニュー、ボタン、リボン・ダイアログ画面に関するもの、などがあります。
目に見えない・見えにくいものは、例えば「Errオブジェクト」「WorksheetFunctionオブジェクト」「FileSearchオブジェクト」「Namesオブジェクト」などがあります。
目に見えない・見えにくいオブジェクトは、Excelの画面ではなく、「プログラムコードや各オブジェクト自体、オブジェクト間の通信、ネットワーク通信など」を管理・操作する、かなり内部的なものが多いかもしれません。
なお、「オブジェクト」には「単一オブジェクト」と、それを(同種/異種関係なく)複数 束ねた「コレクション」の、2種類があります。「コレクション」も目に見えないオブジェクトであるものが多いです。
▲ついでに「列挙」と「定数」
参考:『Access2000VBA・Excel2000VBA独学~用語:”目に見える”「メソッド・プロパティ・列挙(=Enum)・定数(=Const)」と右クリックメニューの画面の関係について~』
イメージですみませんが、ダイアログや各種のメニューなどで設定する「項目」が「列挙」で、その項目の中にある各種の「設定値」が「定数」です。実際にチェックを入れたり、ドロップダウンやリストボックスの中にある各値たちが「定数」です。
「列挙」と「定数」もオブジェクトの中に保持・保有されるイメージです。
(ほんとうにそうなのかどうかはちょっとチェックできていません!すみません!でもオブジェクトブラウザでも見られるし、あるオブジェクトからのリンクで見れるのでそうなんではないかなと思います。)
例えば「値を選択して貼り付け」というメニュー(ダイアログ)の中の、「貼り付け」という項目部分(「演算」じゃなくて)に相当する列挙の名前は、「XlPasteType 列挙」です。そしてこの列挙が保持する定数たちには以下のようなものがあります。
xlPasteAll -4104 すべてを貼り付けます。
xlPasteAllExceptBorders 7 輪郭以外のすべてを貼り付けます。
xlPasteAllMergingConditionalFormats 14 すべてを貼り付け、条件付き書式をマージします。
xlPasteAllUsingSourceTheme 13 ソースのテーマを使用してすべてを貼り付けます。
xlPasteColumnWidths 8 コピーした列の幅を貼り付けます。
xlPasteComments -4144 コメントを貼り付けます。
xlPasteFormats -4122 コピーしたソースの形式を貼り付けます。
xlPasteFormulas -4123 数式を貼り付けます。
xlPasteFormulasAndNumberFormats 11 数式と数値の書式を貼り付けます。
xlPasteValidation 6 入力規則を貼り付けます。
xlPasteValues -4163 値を貼り付けます。
xlPasteValuesAndNumberFormats 12 値と数値の書式を貼り付けます。
このとき、数字は定数を数値として表現し変えたものです。定数は単語と数値とどちらでも好きなほうが使えます。通常は数値だとわかりにくいので単語のほうを使います。
例えば「値の貼り付け」なら、「xlPasteValues」を使う・・・ということになります。
※列強や定数は、Excel専用のものは「xl・・・」で始まり、MicrosoftOffice共通のものは「mso・・・」で始まります。
※ヘルプの中では「列挙」は「列挙体」とも書かれています。一般には「列挙型」とも呼ぶようです。(そのへんはプロの人に聞いてください。)
あと、オブジェクト、オブジェクト式、オブジェクト変数・・・等々の関係について、少しご説明させていただきます。
それらの関係は基本、以下の(a)のような感じです。イメージしやすいように(b)・(c)のように並べ替えてもみました。(Setの意味などは今はわからないかもしれませんが、しかるべきところでご説明させていただきます。)
(a)絵=オブジェクト=オブジェクト式=Setしたオブジェクト変数=「5つの機能」を包含するもの
(b)Setしたオブジェクト変数=絵=オブジェクト式=オブジェクト=「5つの機能」を包含するもの
(c)オブジェクト式=絵=Setしたオブジェクト変数=オブジェクト=「5つの機能」を包含するもの
なお、ここで言う、「5つの機能」とは・・・、
1:階層構造
(階層構造上下自由往来機能、上下オブジェクトの機能流用機能)
2:プロパティ
(下位のオブジェクト・あるいはコレクションの取得や、属性・性質の設定等の機能)
3:メソッド
(コピぺ、印刷、削除、新規作成、等々、何らかの動作をするため命令、的な機能)
4:イベント
=「今・この瞬間に、プログラムを自動実行できるよ!」という信号。
(プログラムを自動実行できるタイミング・シーン、
あるいは、自動起動信号・自動実行信号・的な機能)
5:ユーザー入力値
(Excelのセルの値やWordシートの文章、横書きテキストボックスの値など)
・・・のことを指しています。
また、この「5つの機能」は、「各オブジェクト」の「外側」に存在するわけではありません。すべて、「各オブジェクト」の「中」にあります。「各オブジェクト」の「中」に、保持・保有・内包、されています。(あ、階層構造はオブジェクトの外かな・・・?でもまあ内包していると考えてしまってください。)
※「プロパティ、メソッド、イベント」、それぞれで何ができるのかは、ヘルプで目的のオブジェクトのヘルプページを開き、「×××オブジェクトのメンバー」というリンクをたどって、その一覧表を見るとなんとなくわかると思います。
※メンバー=要素、の意味。構成要素。構成要員。
例:『Applicationオブジェクトのメンバ』、『Worksheetオブジェクトのメンバ』、『Workbookオブジェクトのメンバ』
★プロパティ
(下位のオブジェクト・あるいはコレクションの取得や、属性・性質の設定等の機能)
★メソッド
(コピぺ、印刷、削除、新規作成、等々、何らかの動作をするため命令、的な機能)
★イベント
=「今・この瞬間に、プログラムを自動実行できるよ!」という信号。
(何らかのプログラムを自動実行できるタイミング、シーン。)
※イベントが発生したタイミングでプログラムを自動実行できます。
だから、「オブジェクトを代入したオブジェクト変数」の中にも、「5つの機能」が保持・保有・内包、されることになります(↓下図のようなイメージです)。 そして「オブジェクト変数」のほうも代入したオブジェクトと同様に、この「5つの機能」を使って動かすことができるようになります。
※イメージ図↓
※厳密には、オブジェクト変数に代入されるのは「オブジェクトへの参照」だそうです。
「メモリ上に読み込まれたオブジェクトたちへのショートカットアイコンを作成して代入する」というイメージでも良いかもしれません。
でもVBAの習い始めのうちは、上図のようにイメージしたほうがわかりやすいので、図のように考えてもOKです。
厳密な意味は、どうしてもそれが必要な時にだけ思い出せばOKです。適当に覚えればいいという意味ではなくて、いつかはしっかり学習したほうが飛躍的に腕があがるので、そうしたほうがよいです。ただ、そうなれるまでには少し時間がかかるので、ゆっくりしっかり、学習する・わからなければ何回でも質問する、ということが必要です。
(「オブジェクトへの参照」とは、「オブジェクトへのショートカットアイコンのようなもの」、とか、「オブジェクトへのリンクトンネル」、あるいは「リモコン操縦するための電波」、と思えばいいと思います。実際には多分、メモリ上のアドレスになるのではないかと思います。
例えばブックもシートも、開いた瞬間にメモリ上に読み込まれているイメージで、オブジェクト変数にオブジェクト式を代入すると、そのメモリ上のブックやシートへ通ずるトンネルが空く=ショートカットアイコンが空く=ドアのカギが開く・・・、という感じなのではないかと思います。)
ちょっと話が逸れてすみません。
戻します。
というわけで、一般的な話で言うと・・・
「絵」 ↓
=オブジェクト
=オブジェクト式
=Setしたオブジェクト変数
=「5つの機能」を包含するもの・・・・
・・・という感じです。
「Applicationオブジェクト」の場合なら以下のようになると思います。
この絵 ↓
=Applicationオブジェクト
=Applicationオブジェクトを表すオブジェクト式
(=「Application」、か、「Excel.Application」と書くだけ。)
=Setしたオブジェクト変数(「Applicationオブジェクト」をSetしたオブジェクト変数)
例えば、
Dim ObjApp01 As Application
Set ObjApp01 = Excel.Application
(Set ObjApp01 = Application でもOKです。)
というプログラムを書いた場合の
「ObjApp01 」が、「Setしたオブジェクト変数」です。
つまり、「ObjApp01 」=「Applicationオブジェクト」です。
なお、
「Set ObjApp01 = Excel.Application」の部分は、
「Set ObjApp01 = GetObject("既存Excelファイルのフルパス")」
(=既存ファイルを開く)と書いたり、
「Set ObjApp01 = CreateObject("Excel.Application")」
(=新規空白ファイルを開く)と書く場合もあります。
=「5つの機能」を包含するもの
つまり、以下の5つの機能を内包する「Applicationオブジェクト」。
・階層構造、
・プロパティ、
・メソッド、
・イベント、
・ユーザーの入力値
順序を入れ替えても同じです。
「5つの機能」を包含するもの
つまり、以下の5つの機能を内包する「Applicationオブジェクト」。
・階層構造、
・プロパティ、
・メソッド、
・イベント、
・ユーザーの入力値
=この絵 ↓
=Applicationオブジェクトを表すオブジェクト式
(=「Application」、か、「Excel.Application」と書くだけ。)
=Setしたオブジェクト変数(「Applicationオブジェクト」をSetしたオブジェクト変数)
(例えば、
Dim ObjApp01 As Application
Set ObjApp01 = Excel.Application
というプログラムを書いた場合の
「ObjApp01 」が、「Setしたオブジェクト変数」です。
つまり、「ObjApp01 」=「Applicationオブジェクト」です。)
なお、
「Set ObjApp01 = Excel.Application」の部分は、
「Set ObjWbk = GetObject("既存Excelファイルのフルパス")」
(=既存ファイルを開く)と書いたり、
「Set ObjWbk = CreateObject("Excel.Application")」
(=新規空白ファイルを開く)と書く場合もあります。
=Applicationオブジェクト
======================================
★ (02)「Workbookオブジェクト(単一)」
「Workbookオブジェクト」は「Applicationオブジェクト」の1つ下の階層に位置するオブジェクトです。(すみません!先に階層構造の話をしてしまいます。)
本当は「Applicationオブジェクト」と「Workbookオブジェクト」の間に「Workbooksコレクションオブジェクト」があるっぽいのですが、「”オブジェクト式”や”部分オブジェクト式”を書くとき」は、基本、「コレクションオブジェクト専用の階層は用意されておらず」、たとえば、ドットからドットまでの単一オブジェクト毎の1つの階層内に、コレクションオブジェクトも単一オブジェクトも共存している感じです。(ただし、オブジェクトによってはコレクションオブジェクトが無いモノもあります。複数・新規作成ができない単一オブジェクトには、コレクションはありません。例えばFontオブジェクトとか。)
例えば「Application.Worksbooks.Workbook("ブック名")」なんて風にはなっていません。「.Worksbooks」だけを書いた時も「.Worksbooks("ブック名")」と書いたときも「ドットからドットまでの1つの階層内」にしか書きません。
逆に言ったら、もし「単一オブジェクトの直下の階層がコレクションで、さらにその下の階層にまた何らかの単一のオブジェクト・・・」という構造だとしたら、「・・・ドット・単一オブジェクト・ドット・コレクション名・ドット・単一オブジェクト名・ドット・・・」という感じで、コレクション名(かそれに相当する階層)が「ドットとドットに挟まれて1階層分を占有していないといけない」・・・ということになってしまいます。でも、実際にはそうなっていません。
(※2020/11/11追記 ↑これも「Item」のことを良く分かていなくて書いたので、間違いの記述です。すみません。何が間違っているか、ご自分でも考えてみてください。)
つまり、なので、「”オブジェクト式”の中では(多分便宜上ということだと思うんですけど)単一オブジェクトとコレクションオブジェクトは同じ階層とみなされて・その中で両者を書き分ける」ので、「ある単一オブジェクトの下の階層」は「コレクション」「だけ」じゃなくて、「別のコレクションと単一オブジェクト」としておおまかに捉えてしまってもよいと思います。
(※繰り返しますが、オブジェクトによってはコレクションオブジェクトが無いモノもあります。複数・新規作成ができない単一オブジェクトには、コレクションはありません。例えばFontオブジェクトとか。)
イメージ的には、「" 式 " としては」、以下のような階層構造なイメージですよね。
Workbookオブジェクトの上位のオブジェクトはApplicationであってWorkbooksオブジェクトではないっぽいですし、Worksheetオブジェクトの上位のオブジェクトはWorkbookオブジェクトであってWorksheetsオブジェクトではないっぽいです。
※2020/11/11追記
すみません!
上の図を描いたころは、「Item」という名前のプロパティやメソッドのことをよく知らなかったので、図が少し間違ってます。
「Item」という名前のプロパティやメソッドをきちんと使うことが、「正しい、省略の無い」オブジェクト式の書き方なので、それを考慮に入れますと、
「Workbooks」と「Workbook」のあいだ、と、
「Worksheets」ろ「Worksheet」のあいだ、にも、
「ドット(上図だとピンクの四角)」が、配置されることになります。
なお、「ドット」は「オブジェクトの切れ目」であって、「階層の切れ目」ではありません。
「単一オブジェクト」が「階層の切れ目」、という感じになります。
※2019/05/29追記
参考類似図:『DAOやADOのオブジェクトモデル一覧図(部分的なもの)』の、DAOやADOのオブジェクトモデルの階層一覧図。
(こんな図が見つかったので、あながち僕の考え方も、そうは間違ってはいなかったのかも・・・?と、少しホッとしています。^^ )
例えばイミディエイトウィンドウにて、
? Typename(Workbooks("Book1").Parent)
→出てくる「親オブジェクト」の名前はApplicationであって、Workbook「s」じゃない。
? Typename(Worksheets("Sheet1").Parent)
→出てくる「親オブジェクト」の名前はWorkbookであって、Worksheet「s」でもなければ、もちろんWorkbooksでもない。
もしかしたらそのような考え方は間違っているのかもしれませんが、でも、式としてはコレクションが1階層分を占有してしまうと、ヘルプやオブジェクトブラウザを見るときも、なんかおかしくなってきてしまう気がします。
なので僕は勝手に、「コレクションといったって、必ずしも上に居なければ単一オブジェクトたちを束ねられないわけじゃない。別に 横(隣り)に居ても束ねられるに違いない。」と、かってにこじつけて解釈しています。
※補足
実は、→こちらのWebで公開されているExcel2000のオブジェクトモデルの階層構造図の全体図によると、明確にコレクションのほうが階層が上に描いてあります。
実際にコレクションオブジェクトを操作するときは、多分こんなイメージで操作しています。
単一オブジェクトを(異種・同種)複数たばねたものがコレクションなので・・・。
本当は、こちらの図が「真実」かもしれません。
ただ、これについては、「なぜかマイクロソフトさんは、実際の操作のときの階層イメージと、リアルにオブジェクト式を書くときの階層構造(ドットからドットまで)を違うものにした」と割り切ってしまったほうがラクになるような気がします。なので、やはり、「ある単一オブジェクトの下の階層はコレクション」という風な考え方ではなくて、あえて「”オブジェクト式”を書く時だけは、ある単一オブジェクトの下の階層は、単一オブジェクトやコレクション」という風に覚えてしまっても良いと思います。
同じ階層に「Applicationの中のWindowオブジェクト」「Addinオブジェクト」、「Dialogオブジェクト」「CommandBarオブジェクト」などがあります。
「絵」としては、例えば2010以前の場合は、「ワークブック単位の子ウィンドウのこと」とイメージして良いと思います。あくまでもイメージ、なので・・・。(「子ウィンドウ」ということだと、「Windowオブジェクト」があるのですが、WondowオブジェクトはApplicationオブジェクトに属するものとWorkbookオブジェクトに属すると2種類あるので僕はまだどっちがどっちかとか、画面上でどうなっていたらどっちかなどがよく分かっていません。なのであいまいな説明になってしまいます。どうかお許しを。)
子ウィンドウについては、「シート単位で=シート毎に子ウィンドウとして開けもする」ので、その場合は「子ウィンドウ=Workbookオブジェクト」とはならないですが、そうじゃない場合=シート単位で子ウィンドウになってない場合は、「ワークブック=Workbookオブジェクト=たまたま子ウィンドウともいっしょ=たまたまWindowオブジェクトともいっしょ」ということでよいのだと思います。
例えば下図だと、左側のワークブックと、右側のワークブックが、それぞれ、「Workbookオブジェクト」です。
なのでこの絵は、「ガワ」となる「Applicationオブジェクト」の中に、「Workbookオブジェクトが2つある・・・」という絵になります。(Excel2013以降はこのようにはなりません。1つのガワにつき1つのWorkbookオブジェクトです。)
「Workbookオブジェクト(単一)」の階層構造を省略しない「オブジェクト式」は、
Application.Workbooks(インデックス番号)、
あるいはApplication.Workbooks.Item(インデックス番号)
Application.Workbooks("ワークブック名")
あるいはApplication.Workbooks.Item("ワークブック名")
といった形になります。
(下図の赤線矢印をご参照ください。)
単一のオブジェクトを取得する際は、多くの場合、「インデックス番号」や「"ワークブック名"」を書きます。Workbookオブジェクトに限らず、他のオブジェクトでも同様です。
ちなみにですが、次項の(03)のこととなりますが(先に少しご紹介で)、
「Workbooksコレクションオブジェクト」の省略しない「オブジェクト式」は、
Application.Workbooks
だけ、です。
コレクションオブジェクトを取得する際は、多くの場合、カッコも「インデックス番号」も「"ワークブック名"」を書かず、「単語だけ」となります。Workbooksコレクションに限らず、他のオブジェクトでも同様です。
多くのコレクションでそうですが、プロパティ名だけ(あるいはメソッド名やコレクション名だけ)が書かれていて、カッコもインデックス番号も名前も無い場合は、「コレクションを指定した」ということになります。
あと、「Application.Workbooks(×××)」のように、オブジェクト式の中で使われる「.(ドット)」ですが、多くの市販書籍で「の」と訳せばいい、と書いてあります。
でも僕は「~オブジェクトの中の~」とか、あるいは「~オブジェクトの下の~」と訳すほうがよいのではないかと考えています。
そのほうがオブジェクトたちが「階層構造の中にある」「階層構造を保持している」ということが、最初からより明確になると思うからです。
そして、自力でエラーを解決できるようになるには、自力でヘルプを読みこなせることが絶対条件だと思いますが、ヘルプを読みこなすには「オブジェクトモデルの階層構造の理解」が不可欠だからです。
逆に言うと、「オブジェクトモデルの階層構造の理解」がないと、ヘルプをなかなか理解できません。
そして、ヘルプを理解できるレベルにならないと、いつまでたっても、「意味もわからずコピペ」とか、「多少の意味は分かるけどエラーやトラブルにすごく弱い」というレベルの腕前から脱却できません・・・。
逆にヘルプが理解できるようになると、Web記事などもかなりスイスイ理解できるようになります。
ちょっと脱線しますが、Excelに限らず、VBAに挫折する一番の原因は「ヘルプが読めないこと」です。
挫折する人の100%が、例外なく、「ヘルプが読めません」。
なぜ読めないかというと、大変な無礼をはたらいて申し訳ないのですが、Excel講師の人たちがオブジェクトモデルの階層構造やここに書いてるような詳しい「絵との結びつきや”例外”」についてや、また、「プロパティ」「イベント」「メソッド」の詳細やオブジェクトブラウザとオブジェクトモデルの階層構造の関係について、明確に、最初に教えないからです。
「オブジェクト」についても「モノ」だとか「操作対象」だとかで、わかるようなわからないようなおざなりの説明でごまかしたり。
もちろん、最初から理解できるはずがないとしても、「こういうことを理解しないと挫折しますよ」「だからヘルプを読みこなすための物理的な時間と覚悟がないなら、VBAは時間のムダだからあえてでしないほうがいいです。学生に外注したほうが早くてコスパもいいかもですよ!」ということすらも教えないからです。
というか、講師の人たちが「その教える努力をしようとしない」感じです。その最たるものが「やってるうちにわかるよ」という言葉です。やってるうちにわかるのは確かですが、「やってるうち」、なんていう長い時間・テキトーな言葉じゃなくて、「短期間にわかるようにするにはどうしたらいいか」ということを「教える努力をしようとしない」気がします。短期間で上達できないならお金を払って習いに行く意味がありません。
よくない講師を見つけるのは簡単です。
「オブジェクト」について「モノ」だとか「操作対象」とかでごまかす講師は、最初から「ちゃんと教える気」がありません。また、「やってるうちにわかるよ」という講師もです。あと、オブジェクトモデルの階層構造とヘルプとオブジェクトブラウザやTypeName関数・Parentなどの密接な関係についてすぐに説明できない講師、もです。
Excel音痴でド素人の僕でさえ、このくらいの説明はできるのだから、プロの講師ならもっとわかりやすく的確に「オブジェクト」「コレクション」「オブジェクト変数」「プロパティ」「メソッド」「イベント」「列挙」「定数」「関数」などについて、説明できなければならないと思います。でなきゃお金を払う価値が無いし、短期間に一定以上の腕になることなんてできません。自力でエラー解決なんて夢のまた夢になってしまいます。
ごめんなさい、脱線しました。
というわけで・・・、
「Application.Workbooks(×××)」
なら、
「 ”Application” オブジェクトの中の ”Workbooks” オブジェクトの(×××)」
と訳します。
絵でいうと・・・
というオブジェクト(Applicationオブジェクト)=ガワ、の中に
というオブジェクト(Workbookオブジェクト)=個々のExcelブック、がある・・・
という感じです。
※注・・・今のこの絵だとタイトルバーに「Book1」と表示されていて拡張子が無いので、まだ保存されていない、と判断できます。そしていったん保存されると「Book1.xlsx」などとなって拡張子が付きます。なので、保存前は、「Workbooks(Book1)」と書き表し、保存されたあとは「Workbooks(Book1.xlsx)」と書き表します。ただ、いずれの場合も「Workbooks(1)」とインデックス番号でも書き表すことができ、インデックス番号は名前が変わっても変わりません。ただし、インデックス番号は、そのオブジェクトが画面上での「並び順」を基準としたオブジェクトの場合だと、その並び順を入れ替えるとインデックス番号も入れ替わることがあります。結果、『 同じインデックス番号であっても違うオブジェクトを指し表してしまうことになる 』ということが起こりますのでご注意ください(Workbookオブジェクトの場合はそういったことは無かったと思います)。
なお、詳しくはそういうオブジェクトの場合はヘルプに書いてあります。なので、知らないオブジェクトを初めて扱う時は、一回、ヘルプを読んでおくと良いです。
それくらいなら多くの方が「意味が分からない」ということは無いと思います。
数は少ないですけど、以上のようなことを知らないがために、また、Webや市販書籍にも載っておらず、延々と何日もエラーと戦う羽目になったりもしてしまいます。ヘルプを読めば10秒で片付くエラーが、ヘルプを読まないためにドツボにはまって何日もかけてしまう、典型的な例となってしまいます。ヘルプには「例外」についても多く書かれているので、トラブル時には必ずヘルプから読まなくてはなりません。最初のうちはわからないかもしれませんが、本記事を何度も読んでいただきながらプログラミングを重ねてくだされば、必ず少しずつ分かってきますのであきらめずに頑張ってください。
なお、「workbookオブジェクトでできること」は、「workbook メンバー excel」でGoogle検索すると一覧が出てきます。
※注意!!超重要!!!
「Application.Workbooks」の「Workbooks」は、コレクション名では「ありません」!! 実は、コレクション名と同名の「プロパティ名」です。(僕もこちらで知りました。)
ヘルプにも、『 Workbooksコレクションを取得する=式を書く、には、(同名の)Workbooksプロパティを使用します。単一のWorkbookオブジェクトを取得するには、Workbooks(Index)プロパティを使います』と書いてあります。
逆に、Workbookオブジェクトを取得するのに「コレクションを使え」とは一言も書いてありません。
実はExcelVBAでは、オブジェクトの取得=式を書く際には、その多くが、コレクション名と同名のプロパティを使って「取得=式を書く」ことをします。
ただし、「ユーザーフォーム」がらみの場合は、プロパティではなくコレクションを使ってオブジェクトの取得をする場合が多いです。ちなみにですが、Accessもプロパティではなくコレクションを使ってオブジェクトの取得をする場合が多いです。
ちなみにですが、上図のような「オブジェクトモデルの階層構造図」を見たり、練習ツールを使ったりしながら、階層構造を省略しないオブジェクト式が書けるようになると、多分ですけど、VBAのオブジェクト操作やエラー対策のスピードが上がると思います。
あと、「Workbookオブジェクト」の場合の、オブジェクト、オブジェクト式、オブジェクト変数等々の関係は、以下のようになると思います。
この絵(赤枠) ↓
=Workbookオブジェクト
=Workbookオブジェクトを表すオブジェクト式
(=「Application.Workbooks(×××)」と書きます。)
=Setしたオブジェクト変数
例えば、
Dim ObjWb01 As Workbook
Set ObjWb01 = Application.Workbooks(×××)
というプログラムを書いた場合の
「ObjWb01 」が、「Setしたオブジェクト変数」です。
=「5つの機能」を包含するもの
つまり、以下の5つの機能を内包する「Workbookオブジェクト」。
・階層構造、
・プロパティ、
・メソッド、
・イベント、
・ユーザーの入力値
順序を入れ替えても同じです。
「5つの機能」を包含するもの
つまり、以下の5つの機能を内包する「Workbookオブジェクト」。
・階層構造、
・プロパティ、
・メソッド、
・イベント、
・ユーザーの入力値
=この絵(赤枠) ↓
=Workbookオブジェクトを表すオブジェクト式
(=「Application.Workbooks(×××)」と書きます。)
=Setしたオブジェクト変数
例えば、
Dim ObjWb01 As Workbook
Set ObjWb01 = Application.Workbooks(×××)
というプログラムを書いた場合の
「ObjWb01 」が、「Setしたオブジェクト変数」です。
=Workbookオブジェクト
======================================
★ (03)「Workbooksコレクションオブジェクト(=Workbooksコレクション)」
「Workbooksコレクションオブジェクト」は、「ワークブックの名前がどんなのかよーわからんけど今開いているワークブック全部に一括でまとめて同じ処理をしたい!」という時に使います。
「今開いているワークブックたちを、コレクションして(集めて・束ねて)、いっしょくたに処理するための機能・ユニット」が、「Workbooksコレクションオブジェクト」です。
たとえば、以下のようなことができます。
・名前がわからなくても開いているすべてのブックを閉じる
・名前がわからなくても開いているすべてのブックの数を数える
などなど。
「Workbooksコレクションオブジェクト」の階層構造図の中での場所は以下の通りです。
本当は「Workbooksコレクションオブジェクト」の下に「Workbookオブジェクト」が位置するっぽいのですが、「”オブジェクト式”や”部分オブジェクト式”を書くとき」は、基本、「コレクションオブジェクト専用の階層は用意されていません」。
かつ、「”オブジェクト式”の中では(多分便宜上ということだと思うんですけど)単一オブジェクトとコレクションオブジェクトは同じ階層とみなされて・その中で両者を書き分ける」ので、「ある単一オブジェクトの下の階層は、「コレクションまたは単一オブジェクト」としておおまかに捉えてしまってもよいと思います。
例えば「Workbooksコレクション」と「Workbookオブジェクト(単一)」なら、オブジェクト式としては基本、両者は同じ階層として書きます。どちらかが上とか下とかはありません。
そして、その同じ階層の中で、式として「Workbooksコレクション」を表現したい場合は、
「・・・.Workbooks」
とだけ書いて(sをつけて書いて)、カッコも引数も何も書きません。
一方、「Workbookオブジェクト(単一)」を表現したい場合なら、
「・・・.Workbooksインデックス番号)」とか、
「・・・.Workbooks("ワークブック名")」といった形で書きます。
実際・リアルには階層構造が存在していたとしても、オブジェクト式の中に限ってだけは、上も下も無いので、このオブジェクトモデルの階層構造図のまんま、となります。
絵としては以下の絵 ↓ となり、この「Book1」~「Book3」のすべてを一括して全部(赤枠3つまとめて全部)となります。
「3つのBookあわせて」で、「1つのWorkbooksコレクションオブジェクト」となります。
※もし「Personal.xls」や「Psesonal.xlsb」を使っていたらそれも含まれます。
オブジェクト式は前項の(02)でもご紹介しましたが、以下のようになります。
Application.Workbooks
カッコや引数はありません。
「workbooksオブジェクトでできること」は、残念ながらGoogle検索してもすぐには一覧が出てきませんが、2007や2010のヘルプで「workbooksオブジェクト」で検索すると「Workbooks オブジェクト メンバー」で一覧が見れます。
2000のヘルプでは、残念ながら一覧が出てきません。
なので、オブジェクトブラウザで「workbooksオブジェクト」を検索し、右側に出てきたメンバを上から順番に、「選択してF1キーを押す」を繰り返します。
サマリーではないですが、次々と素早く、それぞれのメンバーのヘルプページを表示・切り替えができます。
なお、ヘルプではコレクション(=コレクションオブジェクト)は、単に「オブジェクト」と表現されます。もともとコレクションもオブジェクトだからです。
例えば、workbooksオブジェクトとworkbookオブジェクトの単語としての綴りの違いは、最後に「s」があるかないか、つまり複数形かどうかになります。
多くのコレクションと単一オブジェクトの違いはそういう風に見分けます。でも中には「s」があるか無いかでは区別できないコレクションもありますのでご注意ください。
iがeになったり(Axis、Axes)、tyがiesになったり(CustomProperty、CustomProperties)、単純に「Collection」が付加されたり(Series、SeriesCollection)、などがあります。
また、「同名」の「プロパティ」もあるので混同しないようにご注意ください。特にヘルプの中では混同しやすいのでご注意ください。
ヘルプの検索結果では、「××××××プロパティ」ではなく、「××××××オブジェクト」をクリックして読みます。
「Workbookオブジェクト(単体)」は「画面」「ウィンドウ」「絵」として目に見えますが、「Workbooksコレクションオブジェクト」は目に見えにくいです。
といいますか、そもそも多くの「コレクションオブジェクト(=コレクション)」は、「画面やメニュー・絵」としては目に見えない機能・ユニット・複合機能体、であることが多いです。
前項の図では1つひとつが「Workbookオブジェクト(単体)」でしたが、「Workbooksコレクションオブジェクト」はそれらをまとめて処理するための機能です。
一般的に、「コレクション」は、「For Each文」と一緒に使うと、複数のオブジェクトに一度に同じ処理ができます。
「Workbooksコレクションオブジェクト」の「オブジェクト式」は、前項の終わりのほうに書いたとおりです。オブジェクトモデルの階層構造図と合わせて見てみてください。
オブジェクト式において、単一オブジェクトではなくWorkbookコレクションオブジェクトとして書くと・・・
・名前がわからなくても開いているすべてのブックを閉じる
・名前がわからなくても開いているすべてのブックの数を数える
などなど。
といったことができるようになる・・・という感じです。
一方、「Workbookオブジェクト(単一)」をオブジェクト式で書くと、これらのことは簡単にはできなくなります。、また、やれることが、がらっと変わってきます。
あと、「Workbooksオブジェクト」の場合の、オブジェクト、オブジェクト式、オブジェクト変数等々の関係は、以下のようになると思います。
この絵 ↓ (赤枠3つまとめて全部)
=Workbooksオブジェクト=Workbooksコレクション
=Workbooksオブジェクト=Workbooksコレクションを表すオブジェクト式
(=「Application.Workbooks」と書きます。カッコや引数は無し。)
=Setしたオブジェクト変数
例えば、
Dim ObjWbS01 As Workbook
Set ObjWbS01 = Application.Workbooks
というプログラムを書いた場合の
「ObjWbS01 」が、「Setしたオブジェクト変数」です。
=「5つの機能」を包含するもの
つまり、以下の5つの機能を内包する「Workbookオブジェクト」。
(=Workbooksコレクション)
・階層構造、
・プロパティ、
・メソッド、
・イベント、
・ユーザーの入力値
順序を入れ替えても同じです。
「5つの機能」を包含するもの
つまり、以下の5つの機能を内包する「Workbooksオブジェクト」。
(=Workbooksコレクション)
・階層構造、
・プロパティ、
・メソッド、
・イベント、
・ユーザーの入力値
=この絵 ↓ (赤枠3つまとめて全部)
=Workbooksオブジェクト=Workbooksコレクションを表すオブジェクト式
(=「Application.Workbooks」と書きます。カッコや引数は無し。)
=Setしたオブジェクト変数
例えば、
Dim ObjWbS01 As Workbook
Set ObjWbS01 = Application.Workbooks
というプログラムを書いた場合の
「ObjWbS01 」が、「Setしたオブジェクト変数」です。
=Workbooksオブジェクト=Workbooksコレクション
この絵の「Workbooksオブジェクト(=Workbooksコレクション)」を、ローカルウィンドウで確認するとこんな感じです。
上図(ローカルウィンドウの図)を見ると、「ObjWbS01 」という「Workbooksコレクションを代入したオブジェクト変数」のツリーの1階層下に、「Item 1」~「Item 4」がぶらさがって位置していることが、見てとれます。
そこから、『「Workbooksオブジェクト(=Workbooksコレクション)」ってのは、例えば上図の「Item 1」~「Item 4」のような感じでぶら下がりさせて、そして、以下のような対応で「Workbookオブジェクト(単一)たち」を一括管理しているんだな~。たしかに「Workbookオブジェクト(単一)たち」がコレクションの中に束ねられてるわ。』という様子がなんとなく見て取れます。
Item 1 →Psesonal.xlsb または、Psesonal.xls
Item 2 →Book1
Item 3 →Book2
Item 4 →Book3
(※注・・・Psesonal.xlsbやPsesonal.xlsを使ってない人は Item 1 が Book1 になります。
Item 4 は出てきません。)
実際、例えば、「ObjWbS01.Close」と書くだけで、その命令でBook1 ~Book3を一括して閉じることができます。(「Book1」とかの名前をまったく知らなくても=考慮に入れなくても。※Psesonal.xlsbやPsesonal.xlsは処理から除外されるっぽいです。)
※同時に、「ローカルウィンドウを見ると、WorkbooksコレクションとWorkbookオブジェクト(単一)がツリー構造・階層構造になっているのに、オブジェクト式ではそうじゃないんだなー。でも、なんで?なんて考え出しても意味ないだろうし、実際にプログラムは書けるから、そうやるんだ、って割り切ろう! ドットじゃなくてカッコや引数を書くことで1階層分を表現した、とでも思えばいいや!」ということもなんとなくわかります。