VBAを始めたての頃、Web上でサンプルを探しているとRangeオブジェクト とRangeプロパティ といった2種類の記述に違和感を感じ、ずっと頭の中にモヤがかかった感じですっきりしませんでした。今でもすっきりしている訳ではないのですが、自分なりに噛み砕いた解釈を紹介します。
結論から書くと、Web上で見かけるRangeプロパティ という記述は、Rangeオブジェクト が指し示しているものとほとんどの場合同じです。では何故、表現が時と場合によって変わるのかを説明します。
オブジェクトとは?
プログラムにおけるオブジェクト の定義はググると概ね以下のような表現がされています。
- プログラムが扱う操作や処理の対象
- (オブジェクト指向 の言語では)クラス のインスタンス
- クラス
オブジェクト を生成するための設計図
- インスタンス
クラス に基づいてプログラム実行時にコンピュータのメモリ上に展開されたオブジェクト
VBAに置き換えると、
- ワークブックやシート、セル、グラフ等そのもの
- オブジェクトブラウザ上のクラス(ちょっと乱暴ですが)
VBA上のオブジェクトとは「クラス をインスタンス化 したもの」といった説明をよくみかけます。言い換えて「設計図を実体化したもの」と解釈しています。ちなみに、他の言語ではクラス 由来ではないオブジェクト も存在するようですが、私は「VBAではインスタンス=オブジェクト」と捉えています。
- オブジェクトとは?
- プログラムが扱う操作や処理の対象=ワークブックやシート、セル、グラフなど
- クラス(設計図)をインスタンス化(実体化)したもの。VBAではインスタンス化が不要なクラスが多いので初心者には「?」となります。ここは理解できなければスルーで構いません。
オブジェクトの正体
サンプルをステップ実行して、ローカルウィンドウを覗いてみます。デモ1、デモ2ともにA1セルを参照していますが、中身がちょっと違います。デモ1はRangeオブジェクト そのものを参照しています。デモ2はRangeオブジェクト でValueプロパティ を指定しています。
- 変数 をオブジェクト型 で宣言すると、複数のプロパティ が表示されることからRangeオブジェクト そのものを参照していることが分かります。定義の「プログラムが扱う操作や処理の対象」です。
Sub デモ1() Dim 台詞 As Range Range("A1") = "よもやよもやだ" Set 台詞 = Range("A1") End Sub
- Rangeオブジェクト にValueプロパティ を指定すると、変数 に入っているのは特定の値 のみになりました。が、Range(“A1”).Valueが「プログラムが扱う操作や処理の対象」であることに変わりはありません。
Sub デモ2() Dim 台詞 Range("A1") = "よもやよもやだ" 台詞 = Range("A1").Value End Sub
どちらも、定義にあてはめるとオブジェクト になります。デモ1はすんなり理解できるのですが、デモ2はValueプロパティ で指定したのにオブジェクト ?と脳みそが破壊される訳です。
Rangeオブジェクト とかValueプロパティ は一度置いておいて、定義のオブジェクト を何となく理解して下さい。コードの記述によって参照されたもの(操作や処理の対象あるいはそのデータ)がオブジェクト です。Range(“A1”)、Range(“A1”).Value、どちらもオブジェクト です。
プロパティ はオブジェクト の属性(設定や情報)を取得/設定するものです。プロパティ の対象はそもそもオブジェクト です。
- Range(“A1”)…プロパティが指定されていないオブジェクト
- Range(“A1”).Value…プロパティが指定されているオブジェクト
オブジェクト式の階層構造
Application.ActiveWorkbook.ActiveSheet.Range("A1").Value
オブジェクトブラウザ を覗くと分かるのですが、Applicationオブジェクト は階層構造になっています(コードを記述するとき、Applicationは省略するケースが多いです)。
オブジェクト を返すのはプロパティ です。例えばRangeオブジェクト ですが、オブジェクトブラウザ でWorksheetオブジェクト を確認するとメンバー の中にRangeがありますが、アイコンをみるとプロパティ になっています。
上の階層に戻ってWorkbookオブジェクト を確認するとメンバー の中にWorksheetsがありますが、これもプロパティ です。
Applicationプロパティ を参照してApplicationオブジェクト を返し、そのメンバーであるWorkbooksコレクション を返すのにWorkbookプロパティ を参照、そのメンバーであるWorksheetsコレクション を返すのに…中略 Rangeオブジェクト を返すのにRangeプロパティ を参照、最後にValueプロパティ を参照して返されたものが前項の「オブジェクト の正体」です。
何が言いたいかというと、VBAの文法でよく「オブジェクト.プロパティ 」と表現されているのは階層構造上のオブジェクト を表現しているのであって、厳密には「プロパティ .プロパティ 」だということです。冒頭にも書きましたがオブジェクト を返すのはあくまでプロパティ です。
- Range(“A1”).Value…Rangeプロパティによって参照されたRangeオブジェクトのValueプロパティを取得している
「コードの書き出しはプロパティから」のような説明になっているかもしれませんが、そうではありません。Application.ActiveWorkbook.ActiveSheet.Range(“A1”).Valueの先頭は確かにApplicationプロパティ ですが、これも実は省略されています。省略せずに記述するとExcel.Application.ActiveWorkbook.ActiveSheet.Range(“A1”).Valueになります。(オブジェクト).プロパティ.プロパティ.プロパティ.プロパティ.プロパティということです。やはり脳味噌が破壊されますね…
RangeオブジェクトとRangeプロパティの違いはない
Web上で見かけるRangeプロパティ という記述は、Rangeオブジェクト が指し示しているものとほとんどの場合同じです。厳密に表現してプロパティ と記述してあるケース、初心者に分かりやすいようにオブジェクト と記述してあるケースなど、色々だと思います。
余談
オブジェクト の定義を自分なりに消化し、階層構造を理解した頃、今まで行き詰っていたことがすんなり頭の中に入ってくるようになりました。Rangeオブジェクト とRangeプロパティ の違いを理解しようとしたときの勉強が、思わぬ副作用として現れました。「点と点が線でつながる」とか「頭の中でバラバラだったパズルのピースが次々とはまっていく」といった感じです。
オブジェクト の正体がなんとなく分かるだけで、勉強の捗り方が大きく変わってきます。ここではさらっと流しましたが、クラス とメンバー の勉強を並行してすすめればさらに理解は深まります。