● Access2000VBA・Excel2000VBA独学~詳細版:VBAプログラムの書き方の基本の概要とVBAを早く独学・習得するためのポイントについて(Excelを例に)
※2018/09/24、ツリーの図が間違っていたので色々直しました。それ以前員読まれた方、ウソ情報を書いてしまい、ごめんなさい。
※2019/05/14 修正:この記事の「コレクション経由のオブジェクト取得ができる」という記述はすべて間違いでした。
大変申し訳ございませんでした。
本日別件でたまたまAccessのオブジェクトブラウザを見てみたら、すべて間違いとわかりました。
「大切な基礎の部分」で大ウソを流布してしまい、本当に申し訳ございませんでした。
穴があったり入りたいです。
「オブジェクト式」におけるAccessの「Forms」(つまり「Application.Forms」の「Forms」)は、「コレクション名」ではなくExcelの場合と同様、「プロパティ名」でした。
Accessのオブジェクトブラウザで確認できます。
Accessのオブジェクトブラウザで、Applicationを検索してオブジェクトのメンバを見ると、中に「Forms」というものがあり、すると、そのアイコンは「プロパティ」を表すアイコンです。
また、一番下の説明ペインにも「Property Forms As Forms」と書いてあります。
つまり、「プロパティのForms は、Forms というコレクションオブジェクトを返します。」という意味ですから、結果、「Application.Forms」の「Forms」は、コレクションではなくプロパティでした。
よってAccessでよく書く「Forms("フォーム1")」とか「Forms(1)」などの「Forms」は「コレクション名」ではなく「プロパティ名の「Forms」であった、ということです。
VBE上でFormsにカーソルを置いて、F1キーを押すとコレクションのことが出てきて、かつ、Excelのヘルプのように「 ××× オブジェクトを取得するには ××× プロパティを使います」と明示的に書いてないので誤解してしまいました。
今後は、オブジェクトブラウザから先に見るようにします。
ExcelやWordなどの「ユーザーフォーム」の各コントロール(テキストボックスやコマンドボタンなど)の場合も、これに同じです。
オブジェクトブラウザで調べると説明ペインに「Property ×××× As ×××× 」と書いてあります。
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
★ はじめに
ExcelのVBAを独学したり、できるだけ早く・安く習得したい、という場合、「ヘルプを自力で読めるようにする。ヘルプの内容を理解できるようにする」というのはすごく大切なことです。
なぜなら、「ヘルプが自力で読めれば、Web記事やマイクロソフト情報も自力で読めるようになり、トラブル解決も自力でどんどんできるようになる」からです。
Excelに限らず、「VBAの習熟度アップ=自力解決=時間・金額のコスパアップ」は、「ヘルプがどれだけ読めるか?理解できるか?」にかかっています。
「ヘルプなんて何が書いてあるかわからない!読みたくない!」と思ってしまいがちですが、また、Web情報に頼ることのほうが多いとは思いますが、でもたまにWeb情報が間違っていたりすることもありますので、そういう時は、ヘルプを見たほうがあっという間に解決できることもあります。(「できないこと」や「エラーになる場面」のことなども明確に書いてあったりもするので、無駄な調べ物をしなくて済むケースも多いです。)
ぜひ、本記事を「ヘルプを自力で読む」ということにご活用ください。
その一助になれれば、本当にうれしいです。
なお、ヘルプを自力で読めるようになるには、次のようなこともあわせてやっていくと、本当にVBAの理解が深まりますし、理解のスピードが速まります。(たぶん・・・)
以下のこともぜひ、ご活用ください。
▼「本記事や関連記事に書かれていることの理解」
▼特に、「Excelに限らずプロパティには、値を設定するだけのプロパティと”オブジェクトを連鎖取得できるプロパティ”の ”2つ” がある(こちらで知りました。)。ただ、ExcelではAccessとは段違いにそのようなプロパティを多く使う・・・ということの理解。(メソッドも同様で”オブジェクトを連鎖取得できるメソッド”がありますが。利用頻度はExcelでも少ないです。)」
▼オブジェクトを取得するには、あとひとつ、自然な流れの「コレクションから単一オブジェクトを選ぶ」というパターンもありますが、Excelではユーザーフォームのコントロールを操作するときにそれが多いです。Accessもこのパターンが多いです。WordはたぶんExcelと同じでプロパティ経由でオブジェクトを取得するパターンが多いと思います。
▼「値を返す自作関数と、オブジェクトを返す自作関数の理解(オブジェクトブラウザをより活用するために必須)」
▼「オブジェクトモデルの階層構造図をいつ何時も見る」
MSサイト→こちら /少し見やすく横につなげたもの→こちら /Excel2000の色付きの見やすいもの→こちら
▼「オブジェクトブラウザの操作方法の理解」
▼「オブジェクト」は「上位下位の階層構造」「プロパティ」「メソッド」「イベント」「ユーザーからの入力値」を保持・保存している。オブジェクトは基本、「複合機能体・複合機能ユニット」なので、これをすべて、「オブジェクトの持つ具体的かつ詳細な”機能”」ととらえても差し支えないと思います。
▼「オブジェクト」には、前項のうち、プロパティを保持していないものは存在しない。なのでプロパティを保持していれば必ず「オブジェクト」と思っていい。ただし、「メソッド」「イベント」などの他のものは「保持している・いないがそれぞれ違う」。メソッドやイベントを持っていないオブジェクトやコレクションもあるということです。
▼「オブジェクト変数の理解」
▼「オブジェクトをオブジェクト変数へ代入する・・・」とは・・・、オブジェクトが保持・保存している「上位下位の階層構造」「プロパティ」「メソッド」「イベント」「ユーザーからの入力値」のすべて・・・つまり、「ユーザーからの入力値やオブジェクト名だけでなく・オブジェクトの持つすべての機能」をオブジェクト変数の中に、丸っと入れ込んでしまうイメージです。なので、オブジェクトを代入されたオブジェクト変数はそのオブジェクトのすべての機能を使えるようになります。
▼「プログラミング」とは、「変数」をプログラム通りに自動的に動かす作業(と思っているほうが整理しやすい気がします。変数に代入したものしか動かせない、というイメージです。)。
▼VBAではその動かす対象の「変数」には、「一般的な変数(文字ベース)とオブジェクト変数の2つしかない」というイメージ。ただ、VBAではオブジェクトをオブジェクト変数に代入しなくてもいい。つまり「オブジェクト式(参照式)」のまんまでオブジェクトを表現しても動かせてしまう。なのでかえって分かりづらい。もしオブジェクトが「オブジェクト変数に代入できなければ動かせない」、という仕様になっていたなら、そのほうが分かりやすかったのではないか?と思う時があります。
▼「イミディエイトウィンドウでのTypeName関数とParentプロパティ」を利用してのオブジェクトの型や上位のオブジェクトの調査
▼「Stop命令とローカルウィンドウ」でのオブジェクトの型や現在のプロパティ値・上位下位・階層構造の調査
これらをある程度理解・利用できれば、VBAの習得はかなり早くなると思います。
中でも最も重要なのは、「オブジェクトモデルの階層構造図」です。
「オブジェクトモデルの階層構造図」はいわば地図、羅針盤、です。
「スタート地点」でもあるかもしれません。
なので、これが最初からあると無いとでは、VBAの学習・理解のスピードが10倍は違うと思います。
Excel2000のヘルプにはついているのですが、例えば2010のヘルプにはちょっとだけ残念ながら、ついていません。(ただ、前述のとおり、2000の階層構造図はWebにもあります。2010でもこれで十分使えます。→こちら /少し見やすく横につなげたもの→こちら /Excel2000の色付きの見やすいもの→こちら)
「オブジェクトモデルの階層構造図」が無いと、ヘルプやオブジェクトブラウザの内容からオブジェクトモデルの階層構造を想像するしかなくなってしまいますが、「オブジェクトモデルの階層構造図」があると、そもそも「ヘルプがすごく読みやすくなります」し、「オブジェクトブラウザ」も使いやすくなります。(この階層図が絶対に正しい、というわけでもないのかもしれません・・・というか、すべてのオブジェクトやコレクションが記載されているわけではないのですが、でも、オブジェクトの概要をつかむにはとても便利です。どっからどこまで、というのが明確になっている、というのは、とても安心感があります。五里霧中な感じというか、そういうのがだいぶ減るので、エラー対策などがとてもやりやすくなります。)
また、「オブジェクトモデルの階層構造図」は「全体図」なので、「この言葉とこの言葉がここにある、ってことは、このオブジェクトは実際のExcel画面では、このメニューや機能ではなかろうか?で、同じ単語だけど、こういう意味の違いがあるのでは?」ということが把握しやすいです。と同時に「これがこのオブジェクトなら、このプロパティやメソッドは実際の画面のこのリスト内のことやボタン、右クリックメニューのことだ」なんてことも想像がつきやすいです。
そしてそれら全ての相乗効果で、「さらにヘルプが読みやすくなります。」
でもって、ヘルプが読めるようになってくれば、勝手に、Web記事などもかなり理解できるようになっていると思います。そうなると、今まで一部しかわからなかったWeb記事が、あれもこれもわかる!という状況になってくると思います。
そうなれれば、さらに、理解が加速しますし、トラブル処理にかかる時間も短くなります。
冒頭でも書きましたが、「ヘルプが自力で読めるようになる」とか、「ヘルプが自力で読めれば、Web記事やマイクロソフト情報も自力で読めるようになり、トラブル解決も自力でどんどんできるようになる」ということとも大きく関係します。
階層構造図のことも本記事のあとのほうで書いていますので、ぜひ、お読みになってみてください。
※その意味で言うと、Excel2000のヘルプはめちゃくちゃ「優秀」です。
最初からオブジェクトモデルの階層構造図全図がついていますし、ヘルプの各オブジェクトのヘルプ内容に「上位のオブジェクト」への「逆階層」が記されいますし、かつ、それがその上位オブジェクトへのリンクになっています。なので、なんとなくでも、上位のオブジェクトへ上位のオブジェクトをへと、どんどんと上にたどっていくことができます。
ですので、例えば、もし「オブジェクトモデルの階層構造図」が手元に無い場合でも、オブジェクトの階層構造を理解しやすいです。
そのほか、ADO・DAOやSQLのヘルプもついています。
ADO・DAOについてもオブジェクトモデルの構造図がついていて、わかりやすいです。
AccessではADO・DAOをよく使うので、このヘルプがついているのはかなり重宝するのではないでしょうか?
あと、2010では出ないものが出る・・・というか、例えばオブジェクトブラウザから「グローバル」の「Rangeプロパティ」を選んでF1キーを押すと、RangeでもいろんなタイプのRangeを列挙してリンクしてくれます。
「Application、AutoFilter、Hyperlink、Range、Shapes、Worksheet」と、Rangeプロパティ保持しているオブジェクトの一覧が出ます。
つまり、Rangeプロパティはこれだけのオブジェクトに保持されている(含まれている)んだなあと(ヘルプだけでもオブジェクトブラウウザが無くても)一目でわかります。
この機能は2010のVBEヘルプにはついていないようです。
(2007にはついています。なので2007と2000のヘルプの組み合わせが一番かも・・・)
ただ、これはオブジェクトブラウザがあれば「検索結果」のペインを見れば同じことがすぐにわかるのでいいのですが、ヘルプとオブジェクトブラウザを行き来しないで済むという点で割と便利です。
なお、例えば2000のVBEヘルプでは、Rangeプロパティは「Application.Rangeプロパティ」、「Range.Rangeプロパティ」、「Worksheet.Rangeプロパティ」、の3つはまったく同じ内容ですが、2010は微妙に変えてあります。なので、2010はそのような細かい点で優れています。
というわけで、結局、Excel2007・2010のヘルプも大変優秀です。
プロパティや事例に対する記述が2000のヘルプよりもわかりやすくなっています。特にすべてのオブジェクトについて、そのメンバーの一覧が機能説明付きで表になっているので「これはどんなことができるオブジェクトなのか?」がすごくわかりやすいです。
もしかしたら、ADOやDAOのことを除く、Excelだけのことなら、2007のVBEヘルプが一番、優秀かもしれません。
だからほんとうに残念なのは、「オブジェクトモデルの階層構造図」や上位オブジェクトへの逆階層図が無く、ヘルプ内で自由に階層を下位から上位へたどる、ということがヘルプだけだとやりにくいということです。
でも、それは2000の「オブジェクトモデルの階層構造図」全図があればそれが結構使えるので、Webにもありますからそれでも十分です。
すこしまとめてしまうと、結局、2010と2000のヘルプ(2003も2002もかもですが)の両方があれば、「一番ExcelVBAがよくわかるし実際に一番便利」です。
なので、もし、ExcelVBAを本当にマスターしたい、ひいては、それで小遣い稼ぎやお仕事をしたい、という方は、Excel2000を必ず買って、VMWareやVirtualBOXなどの仮想マシンに入れて、ヘルプを是非、見てみてください。必ず、エラー対策などに役立ちます。
なお、後述しますが、「Parent プロパティ」と「TypeName関数」を組み合わせると、イミディエイトウィンドウで階層構造を調べることはできます。「Stop命令やブレークポイントと、ローカルウィンドウ」を使うことでも、上下の階層構造をすごく詳しく調べられます。またそちらではプロパティの「現在値」まで調べられます。
これらは「オブジェクトやプロパティの理解」にすごく役立ちます。
(※参考記事→『イミディエイトウィンドウで使う自作関数 』 『「選択したオブジェクトの調査シート白地.xls」(当方自作の参考ツール)~3つの自作関数とともに。』
また、Excel2000のヘルプだと、例えばイミディエイトに「Worksheets("Sheet1")」とタイプした際に、「Worksheets」の上に点滅カーソルを置いて「F1」キーを押すと、「Worksheetsプロパティ」のヘルプページが開くので、すぐに、「あ、この”Worksheets”はオブジェクトを連鎖取得できるタイプのプロパティのプロパティ名だ!オブジェクト名やコレクション名じゃない!」とすぐに分かります。2010のヘルプはなぜかその動きをしてくれません。壊れてるだけかな?WordやOutlookはちゃんとF1押下でそのプロパティやオブジェクトなどのヘルプページにジャンプしてくれるんですが・・・。)
もしタダで、Excel2000が手に入ったら、VMWareなどの無料の仮想マシン管理ソフトでXPやWin2000などの仮想マシンを作り、そこにExcel2000を入れて、2000のヘルプとオブジェクトブラウザを動かしてみることをおすすめします。
★ 「習うより慣れろ」では、結局大したものは作れません。ヘルプが読めないと・・・。
「習うより慣れろ」とよく言われますが、それでは、結局は大したものは作れません。また、中級以上のことを覚えるのにアホみたいに長い時間がかかってしまいます。
VBAはExcelに限らず「中級以上のこと」を覚えないと、「ぶっちゃけコスパが良くなりません」。
逆に言うと、中級以上のことを覚える気が無いなら、最初からVBAの学習なんて無駄なことは止めて、「マクロの記録」機能だけで、「部分対処」し、難しいものは安い業者や学生に発注するほうが、コスパが「はるかに」いいです。いやほんとう、真面目な話・・・。だって、社内のプログラムだって、大したもの作れないのに書いてる人の人件費が高かったら無駄じゃない?と思います。だったらマクロの記録以上のことは外注したほうが安いです。(「マクロの記録」機能をバカにする人がいますが、プログラムが書けない人のためのコスパ考えてないと思います。そういう人のことはあまり聞かないほうがいいです。)
特に「独学」の場合はそうです。その傾向が強いです。
「習うより慣れろ」では、大抵の独学者はすぐに行き詰まります。
そして、ほぼ100%、挫折します。
正直、「中級以上」のものをつくるには、「習うより慣れろ」などという学習レベルではとても太刀打ちできません。
なんで「習うより慣れろ」などという無責任、かつ、安直なことを多くの人が言うのか僕には理解できません。
いずれにしましても、そうならないためには、最低限・・・・、「ヘルプが自力で読める」ようにならないと無理です。でないと、「わからないところすらわかれない。」という状況から脱することができません。
逆に言いますと、ヘルプを読む気が無いなら、コスパは見込めないので、学生さんか、やすい業者に外注に出すほうがいいです。VBAなんて覚えなくてもいいです。というか、時間をドブに捨てるのが目に見えているので、やってはいけない、とすら言ってもいいかもしれません。
「時間」というコストが無限にあって、「のんびりやればいいやぁァ~」ということなら話は別ですが、そうではないのでしたら、「習うより慣れろ」などという無責任、かつ、安直な考えは捨てて、できれば本記事・関連記事・「オブジェクトモデルの階層構造図」のことを学んでほしいと思います。
そして、良い師匠にお金を払って、短時間で中級以上をマスターしてしまったほうが絶対にコスパがいいです。そしてあなた自身、お小遣い稼ぎもできます。投資分を取り戻せます。
「習うより慣れろ」とよく言われますが、最初のうちや「マクロの記録で作れるもの”以下”のレベルの簡単なものを作るだけ」の話です。
以上のようなことは、どのプログラミングでもたぶん同じなのではないかと思います。
「オブジェクトモデルの階層構造図」と、本記事、関連記事程度のことは、いつかは習得しなければいつまでたっても効率化が進まないような気がします。
というか、それ以前に、中級クラスのプログラム自体が作れませんので、「必ず挫折」します。
(ある一定のラインからは急に難しく感じるのがパソコン、プログラミング、ですので・・・)
その意味でも、最初に本記事と関連記事のことくらいは、常に念頭に置いて学習することをお勧めします。
最初は意味がわからなくても、常に念頭に置いていれば、プログラムを書いてその実際の動きを何度も見ているうちに、いつかは理解ができ、それにともなって、他の多くのことの理解も早まると思います。
僕自身、頭が悪くて効率の良い美しいコードってやつが書けないもんですから、何か言う資格なんてほんとうは無いんですけど、でもそんな僕でもなんとかかじりつけているので、みなさんなら、今は初心者のかたでも、将来は必ず、僕のレベルなんて軽く超えて、よいプログラムが書けると思います。
★ VBAとは?VBAでは何を動かすの?VBAで動かすモノの対象は大きくは2つ。
VBAで動かす対象物は大きくは2つです。
(01)「オブジェクト」
と、
(02)「文字列・数値・日付等々のデータ」
の2つです。
※このとき「オブジェクト」とは、例えばExcelの場合なら「セル、シート、グラフ、ピボットテーブル、各種の集計機能、ダイアログボックスの機能、エラー管理機能、リボン・メニュー・ツールバー管理機能、その他目に見えない裏方のたくさんの機能」など、『複数の機能を持ったユニット』のことをさします。Word、Access、Outlook、PowerPointにも独自のオブジェクトがたくさんあります。
(01)の「オブジェクト」を動かす場合は主に、オブジェクトの持つ「プロパティ」の設定値を設定し、「メソッド」という命令語句と「ステートメント」という命令語句で動かします。
例えばExcelの場合なら、オブジェクトに対して、『開く、閉じる、コピペ、移動、削除、最大化・最小化、色設定、フォント設定、音設定、印刷、PDF化、図やシェイプの動かし、メッセージ操作、罫線設定、リストアップ、(Excelであれば)集計、グラフ操作、・・・』、といった操作をします。
(02)の「文字列・数値・日付等々のデータ」を動かす場合は主に、「関数」という命令語句と「ステートメント」という命令語句で動かします。
この場合は「文字列・数値・日付等々のデータ」に対して、例えば、『加工・計算・結合・分解・データ型変換・等々』、といった操作をします。これはExcelもAccess・Wordもその他のソフトも同様です。
また、実際には(01)と(02)の「両方のミックス」が多いです。
理由は、「オブジェクト」の中に保持・保存されている「ユーザーからの入力値」や「各種の設定値(プロパティ値)」は、「文字列や数値」であることが多いからです。(例えば「セル」というオブジェクトの中には、ユーザーが入力した各種の値や、セルの色の値、セルの罫線の値、などいろんな設定値がいっしょくたになって詰まっています。保存されています。)
なので(01)と(02)の両方がミックスされた場合は次のような感じになります。
『
オブジェクトの持つ「ユーザーからの入力値」や「各種の設定値(プロパティ値)」を、「関数」や「ステートメント」で自由に操作をしながら、同時に、そのオブジェクトや他の多くのオブジェクトたちを、「メソッド」や「ステートメント」で自由に動かして行く。
』
そしてそのプログラムを自動実行・連鎖実行させるタイミングとしては、「イベント」と呼ばれる「自動実行ポイント(自動実行タイミング)」を利用します。
「ミックス」の具体例としては、例えば次のような動きをプログラミングすることになります。
『
例えば「A1セル」と「B1セル」で考えてみます。
「A1セル」というオブジェクトに入力・保存されている、例えば数値に対して、100をかけます(乗算する)。
その答えが1000以上になったら、例えば次のように「A1セル」オブジェクトのプロパティの設定値を書き換えます。
・セルの色をピンクにする。
(色変更に「RGB」という関数を使うことがあります。)
・文字を赤の太文字にする。大きさも13ポイントに変更。
・罫線も赤い太い罫線に変更。
で、この変更された「A1セル」オブジェクトを、「Copy」というメソッドでコピーします。
コピー出来たら、それを今度は「B1セル」というオブジェクトに「Paste」というメソッドで貼り付けします。
答えが1000未満なら、すべての変更をもとに戻します。
』
★ 「文字列・数値・日付等々のデータ」を動かす場合の注意
ExcelVBAに限らず、WordでもAccessでも「文字列・数値・日付等々のデータ」を動かす際には「関数」を使います。
が、Excelは少し特殊で、Excelの「関数」には、大きく分けて2種類あります。
「ワークシート関数」と「VBA関数」の2つです。
(WordやAccessはVBA関数1種類だけです。)
VBAプログラムの中では、基本的には「ワークシート関数」は「まんま」では使えません。
もともと「ワークシート関数」は「ワークシート」の「数式」の中でしか使えない関数ですので・・・。
VBAでは基本、「VBA関数」を使います。
「VBA関数」なら、VBAプログラムの中で、「まんま」で使えます。
注意したいのは、ヘルプを読んだときにそれが「ワークシート関数」のヘルプなのか、「VBA関数のヘルプなのか」をちゃんと意識して分けて閲覧しないといけないということです。
間違えてしまいます。
※VBAプログラムの中で、「ワークシート関数」を使うには「WorksheetFunctionプロパティ」を使います。ただし、すべてのワークシート関数を「WorksheetFunctionプロパティ」で使えるわけではありません。IF関数などはそれを使ってもVBAコード内では使えないので、変わりのVBA関数の「IIF」関数を使います。
多分ですが、そのほかの「WorksheetFunctionプロパティでさえも使えないワークシート関数」にも、「変わりとなるVBA関数」が用意されていると思います。
★ VBAを書く前に・ヘルプを読む前に知っておくと良いこと。
(a)「オブジェクト」を動かすには、何はともあれ「オブジェクトの取得」が必要です。
(b)「オブジェクトの取得」には「単一のオブジェクトの取得」と「コレクションと呼ばれるオブジェクトの取得」の2種類があります。
(c)「オブジェクトの取得」とは、「操作したい目的のオブジェクトを1つだけ選択する」、という意味です。
派生して、「取得(=選択)できれば、その取得したオブジェクトをオブジェクト変数に代入できる」「代入後は、操作をラクにできる・共用部品が作りやすくなる・インテリセンス機能(入力補完機能)が使えるようになる」などのメリットがあります。
※代入後にインテリセンス機能を使えるようにするには、取得したオブジェクトの種類を完全把握しておく必要があります。それには、「TypeName関数」を使うと便利です。「TypeName関数」で取得したオブジェクトの種類を明確に調べることができます。
(d)オブジェクトが保持する「プロパティ」には、
「(ア)単に設定値を取得したり変更したりするだけのプロパティ」と、
「(イ)設定値を変更・指定するとともに、同時に、オブジェクトを連鎖的に共同取得までもができてしまうプロパティ」
の2種類があります。
使いたいプロパティがどちらになるのかは、確認したい場合は、オブジェクトブラウザでチェックするか、ヘルプを読めば明記してあります。
ちなみにですが、Excelのオブジェクトの取得は多くが(イ)のパターンです。
Wordもたぶん(イ)が多いです。(未検証です。すみません。
それに対してAccessでは、(イ)のケースはかなり少なく、「コレクション」というものからオブジェクトを取得するケースが多いです。
(e)同様に、オブジェクトが保持する「メソッド」にも、
「(ウ)開く・閉じる・移動・コピペ・印刷・等々、単にオブジェクトを動かすだけのメソッド」と、
「(エ)それらの動作をするとともに、同時に、オブジェクトを連鎖的に共同取得までもができてしまうプロパティ」
の2種類があります。
これも、使いたいメソッドがどちらになるのかは、確認したい場合は、オブジェクトブラウザでチェックするか、ヘルプを読めば明記してあります。
ただ、ExcelとAccessでは(ウ)も(エ)も、使う場面は少ないと思います。Wordは未確認です。
(Accessではビジネス定型処理ではまず使いません。)
(f)「オブジェクトの取得」にはExcel、Access、Word、すべて、最低限3つの入り口があります。
「コレクション経由」
「プロパティ経由」
「メソッド経由」の3つです。
特に、注意すべきは「プロパティ経由」です。
特にExcelで多いので。
Wordもおそらく多いと思います。(未検証です。)
「プロパティ経由」の場合は、(d)の(イ)のタイプのプロパティが使われます。
「メソッド経由」の場合は、(e)の(エ)のタイプのメソッドが使われます。
「コレクション経由」「プロパティ経由」「メソッド経由」、どれで取得したらいいのか?
は、ヘルプに書いてあります。
例えば「Range オブジェクト」の場合は、ヘルプに以下のように書いてあります。
「単体の Worksheet オブジェクトを取得するには、Worksheets(index) プロパティを使用します・・・云々・・・。」
「Worksheets(index) プロパティを使用します」と書いてありますが「(index)」の部分をカットすると「Worksheetsプロパティ」となります。
なので、『Worksheet オブジェクトを取得するには、Worksheetsプロパティを使用します』ということになります。
これで、「 ”プロパティ経由” のオブジェクトの取得でいいんだな」と分かります。
同時に、「Worksheetsプロパティ」を使えばいいんだなと分かります。
このあとさらに読み進めていくと『 引数 index には、ワークシートのインデックス番号または名前を指定します。』と書いてあるので、ワークシートの番号か、シート名を明確に指定します。
「Worksheet(1)」(左から順番に1、2、3、・・・となります)とか、「Worksheet("Sheet1”)」といった指定の方法になります。
もしオブジェクト側のヘルプだけで判明しない場合や、もっと何かが知りたいときは、例えば「Worksheetsプロパティ」(つまりプロパティ側)のヘルプページを見て、さらに取得の方法を調べます。
※補足
「オブジェクト」や「コレクション」は、「オブジェクトモデル」としては階層構造になっていて、上から・・・
「コレクション=コレクションオブジェクト=単一オブジェクトが複数に束ねられたもの」
「単一オブジェクト」
となっているイメージだと思います。(あくまでイメージ。コレクションと単一オブジェクトは同じ階層化かもしれません。)
そしてそれぞれにプロパティやメソッドがあります。
一応簡易的なイメージ図にしてみると・・・・(あくまでもイメージ図です。)、
上位の階層の:単一のオブジェクト(A) ---- プロパティやメソッド(B)
|
|
現階層の:コレクション(C) ---- プロパティやメソッド(D)
|
|
現階層の:単一のオブジェクト(E) ---- プロパティやメソッド(F)
|
|
下位の階層の:コレクションor単一オブジェクト(G)--プロパティやメソッド(H)
・・・といった感じのイメージでオブジェクトモデルの構造になっていると思うんですが、今、取得したいのは(E)だとします。
実際、「オブジェクトを取得したい」という場合は、ほとんどの場合が、(C)ではなく(E)が多いと思うんですが、
まず、「コレクション経由」で(E)を取得したい場合は、(C)→(E)という上から(縦方向だけ)のある意味「正の流れ」
となる感じだと思います。
一方、そうではなく、「プロパティ経由」で(E)を取得したい場合は、(B)→(E)という「斜め上?」「横方向からの動きを含んだ?」からの「イレギュラーな流れ」
で取得する・・・。
といった感じでしょうか?
ただ、ここで一つ注意点があるのですが、(B)からの取得の場合は、大雑把に言うと・・・、「上の階層のプロパティやメソッドから取得する・・・」ということなんですが、ただそれは現:単一オブジェクトの上に在るコレクションのプロパティやメソッドからではなく、そのまた「1つ上位の」「単一オブジェクト」の「プロパティやメソッド」からの取得となります。これを覚えておくと、オブジェクトブラウザが見やすくなりますし、ヘルプとの連携・活用・コスパアップもしやすくなります。(例えば「Worksheetオブジェクト(単一)」の取得の場合は、「Worksheetsコレクション」が保持するプロパティやメソッドからではなく、上位の単一オブジェクトの「Workbookオブジェクト」が保持するプロパティやメソッドから(その場合は「Worksheetsプロパティ」から)オブジェクトを取得する、という動きになります。)
なお、(B)からの取得の流れが、(B)→(E)っていう風に、(E)へ「直」で行くものなのか、それとも、(B)→(C)→(E)っていう感じで(C)の「コレクション」をワンクッション挟んで行くものなのかは、僕にはまだわかりません。
その辺はプロの先生にお金をお支払いして聞いてください。
でも、Excelの場合は、むしろその(B)→(C)→(E)のルートのほうが多いのかしらん??
もちろん、(C)もオブジェクトの一種ですので、(C)を取得したい場合は、(B)→(C)もあります。
(B→Eも、B→Cも、同じプロパティを使って取得し分けます。「カッコと引数」をつけて書くか/書かないかの違いだけです。B→Eと取得したいならカッコと引数を書きます。B→Cと取得したい場合は書かずにプロパティ名だけで終わります。)
「プロパティ経由」でのオブジェクトの取得についてはひとまず以上です。
あと、「メソッド経由」でオブジェクトを取得する場合も、「プロパティ経由」の場合と同様に、(B)→(E)(もしくは(B)→(C)→(E)?)という、「ある意味イレギュラーな流れ」です。
ちなみにですが、Excelの場合で、(C)→(E)という「正の流れ」でのオブジェクト取得が多いのは「ユーザーフォーム」がらみの場合です。
「ユーザーフォーム」を作ったときに、コマンドボタンやリストボックスなどを「オブジェクトとして取得したい場合」に、(C)→(E)という「コレクション経由」の流れが多いです。(=「コントロール」と呼ばれるオブジェクトの一種の取得をする場合に多い・・・、ということでもあります。)
Accessもこの(C)→(E)という「正の流れ」・「コレクション経由」でのオブジェクト取得が多いです。
(B)→(E)(もしくは(B)→(C)→(E)?)という「イレギュラーな流れ」が多いのが、ExcelやWord、
ということになるかと思います。(PowerPointなどは調べてませんのでご自分でも調べてみてください。ヘルプに
なんで、そんな風に異なるの?ということなんですが、あえて「マイクロソフトが勝手にそう決めた」ということにしておき、あえて、あまり深く考えないほうがいいと思います。
特にVBAを学習しはじめのときは。
大切なのは、Excelでも、Wordでも、Accessでも、
・「単一のオブジェクト」を取得するには、(C)→(E)というある意味「正の流れ」と
(B)→(E)・(B)→(C)→(E)・(B)→(C)というある意味「イレギュラーな流れ」のなかで、
・3系統(2系統)のやり方があって(=コレ・プロ・メソ経由の3つ(2つ)の入り口があって)、
・ソフトによってそれぞれのウェイトが違う、
ということを理解することと、
・プロパティ経由だろうが、コレクション経由だろうが、メソッド経由だろうが、取得しているのは「オブジェクト」であり、
・「そうやってオブジェクトを取得できる」
という事実です。
逆に言うと、「そうやってでしか、オブジェクトを取得でき”ない”(特にプロパティ経由やメソッド経由)」「もとからそういう掟・仕様になってしまっている」「だからあれこれ考えても仕方がない」という事実です。
もっと言うと、本当に大切なのは、「最終的には、今現在・どんなオブジェクト(単一 or コレクション)を取得できているのか?が明確にわかりされすればいい。」ということです。
『 単一オブジェクトの取得は、コレクション起点の ”正の流れ” 以外に、プロパティやメソッド起点での ”イレギュラーな流れ” でもできる 』、という事実をあらかじめ知っていれば、ヘルプも、VBAのWeb記事も、書籍も、全部理解度が上がるからです。
ヘルプやWeb情報が自力で読めるようになれば、当然、記述ミスやトラブル解決の腕も上がると思います。
(g)オブジェクトを動かすための書き方の基本(基本構文)
【プロパティの値を設定したいとき】
これは、オブジェクトに対する各種設定値の書き換えです。
例えばExcelの場合なら「セルに対する書式設定やその他の各種設定、入力値の単純書き換え・・・」といったような作業ですが、基本になる書き方は以下のような感じです。
オブジェクト.プロパティ=値
オブジェクト.オブジェクト.・・・.プロパティ=値
・・・など。
ほかにも色々あると思いますが、基本形はこれです。
なお、「オブジェクト.」は、「オブジェクト参照式.」と言われたりもします。
「オブジェクト.」、あるいは、「オブジェクト参照式.」は前述もしましたが、Excelの場合は(d)の(イ)が使われることが多いです。
【メソッドで動かしたいとき】
これは、オブジェクトに対する、開く、閉じる、印刷、等々、の操作ですが、基本になる書き方は以下のような感じです。
オブジェクト.メソッド
オブジェクト.オブジェクト.・・・.メソッド
・・・など。
ほかにも色々あるのかどうか分かりませんが、基本形はこれです。
まれに、「オブジェクト.」、あるいは、「オブジェクト参照式.」にて、前述の(e)の(エ)が使われます。
※補足
追加の説明ですが、「オブジェクト.」の部分は「オブジェクト参照式.」と呼ばれるほかにも・・・、
「オブジェクト式.」
「オブジェクトへの参照.」
「オブジェクトの参照式.」
・・・と言われたりもします。
これは、説明する人の都合で色々です。
また「オブジェクト.プロパティ=設定値」の部分は・・・、
オブジェクト.オブジェクト.プロパティ=設定値
だったり、
オブジェクト.オブジェクト.オブジェクト.プロパティ=設定値
だったり、
オブジェクト.オブジェクト.オブジェクト.オブジェクト.プロパティ=設定値
だったり、
つまり、「オブジェクト.」の部分が幾つにも現れることがあります。
これは「オブジェクト全体が階層構造になっているから」です。(次項でももう少し詳しくお話しています。)
そのため、「深い階層に位置するオブジェクトのプロパティ」の場合は、「オブジェクト.オブジェクト.オブジェクト.・・・」といった感じで異なるオブジェクトが多数、段階的に書かれることになります。
ただ、特にExcelの場合は深い階層になりがちなせいか、オブジェクト参照式を書くだけでも長ったらしくなってしまうのでかどうかは分かりませんが、プロパティから左側のオブジェクトの階層構造の記述を省略できることが多いです。(全部が全部ではありませんが。)
(h)「コレクション」には、少なくとも2つの視点で2種類があります。
「コレクション」は、「複数のオブジェクトを束ねたもの」で、これまた「オブジェクト」です。
ただ、これには2種類あります。
(イ)異なる種類のオブジェクトを束ねたコレクション
と
(ロ)同じ種類のオブジェクトのみを束ねたコレクション
の2つです。
前者は例えば「Sheets」コレクションです。
ワークシート、グラフシート、マクロシートなど、複数の異なる種類のシートを、「シート」というくくりの基準で束ねています。
なので「Sheetコレクション」は、言わば「全種類シート管理機能」です。
後者は例えば「Worksheets」コレクションです。
これは複数の「ワークシート」「のみ」を、「ワークシート」というくくりの基準で束ねています。グラフシートやマクロシートなどは、この”束ね”の中には入っていません。
なので「Worksheetsコレクション」は、言わば「ワークシートOnly管理機能」です。
「Worksheet」オブジェクトは、「Sheets」コレクションに属する場合と、「Worksheetsコレクション」に属する場合があります。いずれの場合も、「Worksheet」オブジェクト関連の命令は全部使えますので、見分けがつきにくいです。
でも、その際には「ヘルプ」や「TypeName関数」と「Parentプロパティ」が力強い味方となってくれます。
ちなみにですが、上位のオブジェクトが何なのかを調べるのはエラー回避の面からみても、割と大切だったりしますが、その上位のオブジェクトが何なのかを調べるにも、「TypeName関数」と「Parentプロパティ」が力強い味方となってくれます。
あと、別の視点でもう2種類あります。
(ハ)「オブジェクトモデルの階層構造図」に載っているもの
と
(二)そうでないもの
の2種類があります。
(ハ)の載っているものは「一般機能」的な感じです。
次のようなイメージでもあります。
「1st」なコレクション
「OnMap」なコレクション
「一般的」なコレクション
(二)の載っていないものは「例外機能」的というか、「特別機能」・「アドバンス機能」的な感じです。次のようなイメージ?なのかな?。ちょっとよくわかりません・・・。
「2nd」なコレクション
「OffMap」なコレクション
「例外的」なコレクション・・・になるんでしょうか?ちょっとよくわかりません・・・。
という感じ。
例えば、これまた
「worksheetsコレクション」と
「sheetsコレクション」。
「worksheetsコレクション」は(ハ)の「オブジェクトモデルの階層構造図」に載っているもの、です。
「sheetsコレクション」は(二)のそうでないもの・載っていないもの、です。
なお、Sheetsコレクションのほうがworksheetsコレクションよりも上位に見えますが、そうじゃないかもしれません。そうかもしれないけど、調べてもよくわかりませんでした。
でも、特に問題なく使えるので悩まないことにします・・・。
(i)「コレクション名」と「プロパティ名」が同じ場合のコレクションとプロパティの見分け方
例えば「Worksheets」ですが、これは「コレクション名」と「プロパティ名」の両方に存在します。やれることが全く違うのに、名前が同じなので混乱するのですが、VBAプログラムコードで、どちがらがどちらかを見分けるには次のように見ます。
後ろにカッコも何も付いてなかったら「コレクション(=コレクションオブジェクト)」で、
後ろにカッコが付いていたら「プロパティ(=オブジェクト取得ができるプロパティのことが多い)」
という風に見れば大抵はOKだと思います。
オブジェクト名が何かや上位オブジェクト名が何かを見たりしてもなんとなくわかります。
たとえばイミディエイトウィンドウで以下のようにタイプしてEnterしてみます。
? Typename(Worksheets)
→「Sheets」と返ってきます。つまりこの「Worksheets」は、Sheetsコレクションです。
Typename関数の引数にも返り値にも両方の末尾に「s」がついているので、「Worksheets」は「コレクション=コレクションオブジェクト」と判断して間違いないと思います。
? Typename(Worksheets.Parent)
→「Workbook」と返ってきます。つまりこの「Worksheets」の1つ上の階層のオブジェクト(=Parent)は、「Workbookオブジェクト」です。また、それのメンバでもある、ということになります。
? Typename(Worksheets("Sheet1"))
→「Worksheet」と返ってきます。つまりこの「Worksheets」は、「Worksheets("Sheet1")」全体で「オブジェクトだ」といえます。「Worksheet」と返ってきて「Worksheets」ではないので、「s」が無いので、ひいては「たぶん単一オブジェクトだ」、ということもわかります。
(ただ、ここでは「Worksheets」がプロパティだと明確にはすぐには判断できませんが・・・。Excel2000のヘルプだと「Worksheets("Sheet1")」の「Worksheets」の上に点滅カーソルを置いてF1キーを押すと、「Worksheetsプロパティ」のヘルプページが開くので、すぐに、「あ、これはオブジェクトを連鎖取得できるタイプのプロパティだ!」と分かります。)
? Typename(Worksheets("Sheet1").Parent)
→こちらも「Workbook」と返ってきます。つまりこちらの「Worksheets("Sheet1")」の1つ上の階層のオブジェクト(=Parent)は、「Workbookオブジェクト」です。また、それのメンバでもある、ということになります。
以上から分かるのは、以下のようなことです。
(a)「Worksheets」は、「Sheets」という「コレクション」
(b)「Worksheets("Sheet1")」全体としては、「Worksheet」という「単一オブジェクト」で、かつ、ここでの「Worksheets」1語だけを見ると、「Worksheetsプロパティ」というプロパティ名。
(c)(a)も(b)も、「Worksheets」1語だけを見ると、「Worksheetsプロパティ」というプロパティ名なんだけど、カッコがついている・いないで、返ってくるオブジェクトが異なる。
プログラムによっては(c)が理由でエラーになる可能性があるので、注意が必要です。
★ 「オブジェクト.オブジェクト.・・・.プロパティ」とオブジェクトを階層構造で書きたい場合の基本書式
オブジェクトは階層構造になっています。
例えばExcelの場合、「セル」「セル範囲」を意味する「Range」というオブジェクトは、以下のようなオブジェクトの階層をたどります。
「Aplicationオブジェクト」
(Excel2010までの場合、Excelの親ウィンドウ・アプリケーションウィンドウのこと。)
↓
「Workbookオブジェクト」
(Excel2010までの場合、Excelの子ウィンドウのこと。)
↓
「Worksheetオブジェクト」
(「Sheet1」「Sheet2」などのワークシートのこと)
↓
「Rangeオブジェクト」
(「A1」セル、「A1~F10まで」、などの。セルやセル範囲のこと)
プログラムとして書いた場合は、例えば以下のような記述例となります。
Application.ActiveWorkbook.ActiveSheet.Range("A1")
Application.Workbooks(1).Worksheets(1).Range("A1")
Application.Workbooks("Book1”).Worksheets("Sheet1").Range("A1")
どれも「A1」セルを「オブジェクト」として書き表したものです。
Application.ActiveWorkbook.ActiveSheet.Range("A1") は、
「Excelアプリケーションの、作業中のBookの、作業中のワークシートの、A1セル。」
という意味です。
Application.Workbooks(1).Worksheets(1).Range("A1") は、
「Excelアプリの、1つ目のBookの、1つめ(一番左)のワークシートの、A1セル。」
という意味です。
Application.Workbooks("Book1”).Worksheets("Sheet1").Range("A1")
「Excelアプリの、「Book1」というBookの、「Sheet1」というワークシートの、A1セル。」
という意味です。
このように、何かのオブジェクトを書き表したいときには、「オブジェクトの階層構造」を把握していないと書けません。
でもこれは私らド素人や初心者の方々には難しいです。
仕方がないので、「オブジェクトモデルの階層構造図」のようなものを利用して、それを見ながらヘルプを見たりWEb検索したりして階層構造を正しく書いていきます。
例えばExcelの階層構造図は以下のようなものです。
Excel2000オブジェクトモデルの階層
https://msdn.microsoft.com/ja-jp/library/cc326844.aspx?f=255&MSPPError=-2147217396
上記の図を横につなげたもの
https://euc-access-excel-db.com/00000WPhtml/Excel2000-obj-model01.html
Excel2000ヘルプよりの図(こちらのほうが見やすいかも?」
https://euc-access-excel-db.com/00000WPhtml/Excel2000-obj-model01.png
これらの図を見るとかなり一目瞭然で、トップレベルの「Applocationオブジェクトから」、目的のオブジェクトまでの階層構造がすぐにわかります。
VBAで記述するときも、このとおりに書けばいい、ということになります。
ExcelはAccessと比べると、すごくオブジェクトの取得方法の理解がむずかしいので、このようなオブジェクトモデルの階層図があると、とても便利です。
この階層図は古くて、Excel2000のもの(もしかしたら今は無いオブジェクトもあるのかもしれません)ですが、よく使う機能であればこの階層図でも十分ですので、ぜひ、「オブジェクトやプロパティの理解」に活用してほしいと思います。
また、この、
・「オブジェクトモデルの階層図」
・「ヘルプ」
・「オブジェクトブラウザ」
・「オブジェクト変数の理解」
・「Excelに限らずプロパティには、オブジェクトを取得できるプロパティやメソッドがある。ただ、ExcelではAccessとは段違いにそのようなプロパティを多く使う・・・ということ」
・「本記事や関連記事に書かれていること」
を読んである程度理解できれば、VBAの習得はかなり早くなると思います。
なぜなら、「ヘルプが自力で読めるようになる」からです。
「ヘルプが自力で読めれば、Web記事やマイクロソフト情報も自力で読めるようになり、トラブル解決も自力でどんどんできるようになる」からです。
中でも最も重要なのは、「オブジェクトモデルの階層図」です。
これが最初からあると無いでは、VBAの学習の理解のスピードが10倍は違うと思います。
どのオブジェクトをどう取得すればいいかは、ヘルプに書いてあるのでそれを読んでオブジェクト参照式を記述します。
ただし、たとえば前述の
Application.ActiveWorkbook.ActiveSheet.Range("A1")
Application.Workbooks(1).Worksheets(1).Range("A1")
Application.Workbooks("Book1”).Worksheets("Sheet1").Range("A1")
は、
全部、Range("A1")と書いて、ほとんどの階層を省略できます。
どこをどう省略してもよいか?や、省略するとどんな意味に変化するか?などは、これもヘルプに書いてあります。
「省略する箇所によっては、意味が思いもよらぬ形に異なってくる場合があります」ので、必ず、ヘルプを確認し、何をどう省略するとどう変わるか?などをよく読んで、また、実際にプログラムを動かしながら意味を把握しておいてください。
例えば、Rangeオブジェクトなら、「オブジェクト修飾子 (ピリオドの左側に記述するオブジェクト) を指定せずに使用した場合、Range プロパティは作業中のワークシートのセル範囲を返します。」と書いてあります。
これは「.Range("A1") のピリオドの左側全部を省略すると、作業中のワークシートのA1セルを選択したことになります。」という意味です。
そのとき、後述の「Parent プロパティ」と「TypeName関数」で省略前と省略後の目的のオブジェクトの種類を調べ、変化しないならよし、変化してしまうならどんなオブジェクトに変化するのかを実際にチェックしておくと良いと思います。
なお、「Parent プロパティ」と「TypeName関数」でオブジェクトの階層構造を調べることができます。が、それでも、「オブジェクトモデルの階層構造図」は重要だと思います。
あったほうがいいです。
「Parent プロパティ」と「TypeName関数」で調べる階層構造は、目的の操作に関連する狭い部分だけしか調べられませんが、「オブジェクトモデルの階層構造図」は「全体図」なので、調べたものがどのあたりに位置するかまでがわかるからです。
また、調べたものと関連するほかの何かを調べた時も、それらの関係性もわかりやすくなります。
そういった、「いろんなものの位置関係」も「わかるとわからない」ではVBAの理解のスピードが相当「速くなる・遅くなる」といった違いが出るような気がします。
★ 今現在操作中のオブジェクトまでの、トップからの階層構造の調べ方
エラーが出た時などに、「オブジェクトの階層構造を把握したい・把握し直したい」という場合があります。
そのようなとき、トップレベルのオブジェクトから、現在操作中のオブジェクトまでの階層構造を調べるには、イミディエイトウィンドウで「Parent プロパティ」と「TypeName関数」を使って調べる方法が、たぶん、手っ取り早いのではないかと思います。
(もしかしたら、別のもっと簡単な方法があるかもしれません。もしそうでしたらごめんなさい。)
例えば、トップレベルのオブジェクトから、「A1セル」というオブジェクトまでの階層構造を調べたいとします。
その場合はイミディエイトウィンドウで次のように操作します。
まず、次のようにタイプしてEnterします。
? TypeName(Range("A1"))
「Range」と表示されます。
これは、「Range("A1")」は「Rangeオブジェクトですよ」、という意味です。
では次に、以下のようにタイプしてEnterします。
? TypeName(Range("A1").Parent)
「Worksheet」と表示されます。
これは、「Range("A1")」の1つ上の(親の)オブジェクトは「Worksheetオブジェクトですよ」、という意味です。
次は、以下のようにタイプしてEnterします。
(つまり、「.Parent」を一つずつ増やしてEnterしていくことになります。)
? TypeName(Range("A1").Parent.Parent)
「Workbook」と表示されます。
これは、「Range("A1")」の2つ上の(親の)オブジェクトは「Workbookオブジェクトですよ」、という意味です。
次は、以下のようにタイプしてEnterします。
? TypeName(Range("A1").Parent.Parent.Parent)
「Application」と表示されます。
これは、「Range("A1")」の3つ上の(親の)オブジェクトは「Applicationオブジェクトですよ」、という意味です。
で、この「Application」が出たら、調査は終わりです。
「Application」が最上位・トップレベルのオブジェクトですので。
さらに「.Parent」を何個も増やして調べても「Application」が出るだけみたいです。
で、結局イミディエイトには、以下のように各オブジェクト名が表示されていると思います。
? TypeName(Range("A1").Parent.Parent.Parent)
Application
Workbook
Worksheet
Range
これがトップレベルのオブジェクトから、「A1セル」=「Range("A1")」までのオブジェクトの階層構造です。
Application
|_
Workbook
|_
Worksheet
|_
Range
という階層構造になってますよ~!という意味です。
なので、本当は、前項でもご紹介しましたが・・・、
Application.ActiveWorkbook.ActiveSheet.Range("A1")
Application.Workbooks(1).Worksheets(1).Range("A1")
Application.Workbooks("Book1”).Worksheets("Sheet1").Range("A1")
・・・というような書き方がどうやら「正式」なようです。
でも、面倒くさいので、「Range("A1")」とか、「Worksheets(1).Range("A1")」とか、「一部を省略してもいいよ~!」ということらしいです。
ただし、注意が必要なのは、Rangeの場合はどこで何を省略しても「Rengeオブジェクト」のままですし、「作業中のワークシートのセル範囲を返す」ということらしいので良いのですが、ほかのオブジェクトには、もしかしたらそうじゃないものもあるかもしれません。
(ないかもしれませんけど。それならいいんですが・・・(^^))
なので、省略する場合も、各オブジェクトのヘルプに一応目を通してから、省略するほうがいいと思います。
なお、Worksheetsコレクションのように、「Worksheets コレクションを取得するには、Worksheets プロパティを使用します。」とヘルプには書いてあるものの、実際にイミディエイトウィンドウにて「? Typename(Worksheets)」とタイプしてEnterすると、「Sheets」と返ってきてしまう、つまり、WorksheetsコレクションではなくSheetsコレクションが返ってきてしまう・・・そういったオブジェクトもあるようです。
つまり、「ヘルプの記述と実際の動作がちがうっぽくない?」というケースです。
そういうケースも注意が必要です。
もしかしたら、そういう動きが正常なのかもしれませんが、いずれにしても、自分の思い込みと違う場合があるかもしれませんので、もしオブジェクトがらみで何らかのエラーが出た場合で、どうしてもエラーが解決しないときは 「? Typename(オブジェクト)」 にて、一応、操作対象のすべてのオブジェクトの種類の実態調査をしてから、解決にあたるほうが良いかもしれません。
★ VBAプログラムの「=」は「代入しろ」という命令語句です。
VBAプログラムでの「=」は場面場面で意味が異なります。
大きく分けて2つの意味があります。
まずメインの意味としては、「=」は「代入しろ」という命令語句です。
「等しい」という意味で使うことはないわけではありませんが、少ないです。
多くは「変数=×××」「変数に、右辺の”値や式の結果”を代入しろ」という具合で、「代入する」という意味で使います。
なので、
「変数A=変数A+1」というプログラムも成り立ちます。
この場合も、「=」を「等しい」という意味では使ってませんので。
逆に「等しい」という意味でこのプログラムを見てしまうと、「変数Aに1足したものが変数Aとイコール?なんで?」となってしまいます。
でもここでも「=」は「代入しろ」という命令語句ですので、意味は次のようになります。
「新しい変数A=直前までの変数A+1」
「新しい変数Aに、直前までの変数Aの値に1を足して、代入しろ」
「新しい変数Aに、直前までの変数Aの値に1を足して、代入しなおせ」
「新しい変数Aに、直前までの変数Aの値に1を足して、上書きしろ」
※「直前までの変数Aの値」とは、「変数A=変数A+1」というプログラム(プログラムの行)が実行されるまでの「変数Aの値」のことです。
実行されてしまうと1足された数字になってしまうので、そうなるまえの、1足されてない変数Aが保持している値のことです。
・・・と、こんなような意味になります。
これが一つ目の意味です。
もう一つの意味は文字通り「=(イコール=等しい)」の意味です。
これは、「=」が「条件式」に使われる時です。
そのとくは「=」は「等しい」という意味で使います。
「条件式」、とは、
「If文(条件分岐処理)」、
「Select Case文(条件分岐処理)」
「For ~ Next文」(繰り返し処理処理)」
「DoUntil ~ Loop文」(繰り返し処理処理)」
「SQL文(データ管理専用の命令語句)」
などで使う、「条件式」のことです。
例えば「If文」だと「もし××だったら▼□しろ」という命令を書くわけですが、この場合の「××」のところに書く条件式です。
「もし変数Aの値が100だったら、”100点です!”というメッセージを出せ」
というようなプログラムを書きたいと思ったとき、を考えてみます。
その場合、そのプログラムは
「If 変数A=100 Then Msgbox(”100点です!”)」
という格好になります。
で、このときにの「変数A=100」という部分の「=」は「イコール=等しい」という意味で使われます。「If」の意味も追加されれば
「もし 変数Aが100 と等しかったら」
「もし 変数A=100 という状況だったら」
「もし 変数A=100 という条件に当てはまったら」
「もし 変数A=100 という条件にビンゴ!だったら」
というような意味になります。
これは
「Select Case文」
「For ~ Next文」」
「DoUntil ~ Loop文」」
「SQL文」
でも同じです。
以上のように・・・、
VBAプログラムでは、「=(イコール)」には、2つの意味があり、それは「代入する」という意味と、「等しい」という意味。
ただし、「代入する」という意味合いのほうがメインで使われ、「等しい」という意味合いはサブで「条件式」で使われる・・・、
・・・ということを覚えておいてください。
★ ひとつだけ覚えなければならないステートメント(文)があるとしたら?(If文)
まず「ステートメント = 文・制御文」と思ってください。
で、いきなりですが、乱暴な言い方かもしれませんが、基本、最低限のステートメントとしては、「If文」と「For Next文」「For Each Next文」「DoUntil Loop文」さえ覚えておけば、なんとかなります。
ほかのステートメントは知らなくても・・・。
特に、『ひとつだけ覚えなければならないステートメント(文)は何?』と聞かれたら、「If文」だと思います。
「If文」さえ知っていれば、ビジネス定型処理のプログラムのような厳格性・緻密性を求められないプログラムでは、8割がた、なんとかなってしまいます。(今はマシンパワーがあるため)
あとは「Exit文」を覚えれば、以上の文だけでも相当なことができます。
それぞれのExit文の意味は次の通りです。
「Exit Do」→「Do Loop」を抜けます。
「Exit For」→「For Next」や「For Each Next」を抜けます。
「Exit Function」→「Functionプロシージャ」を終わる。
「Exit Property」→「Propertyプロシージャ」を終わる。
「Exit Sub」→「Subプロシージャ」を終わる。
★ 変数とは?オブジェクト変数とは?変数の宣言とは?
★ エラー処理とは?(On Error Goto ×× 文、など)
小さな会社のプログラムでは、あまり使いすぎるとエラーの出る箇所がわかりづらく勉強のさまたげにもなりますので、もし、「作る人」が「毎日つきっきりで職場に居れて、公休日もまず問題ない」なら、これは書かなくても大丈夫です。
あるいは一応書くだけ書いておいて、エラーが無くなるまで「コメントアウト:無効化」しておきます。
VBAではエラーが出てもメッセージの「終了」ボタンをユーザーさんに押してもらえばなんとかなるので。
「他人のプログラムを作ってあげるとき」は、ちゃんと書いて有効化しておいたほうがいいかもしれません。