[Excel VBA]RangeオブジェクトとRangeプロパティの違い

VBA始めたての頃、Web上でサンプルを探していると「Rangeオブジェクト」と「Rangeプロパティ」といった2種類の記述に違和感を感じ、ずっと頭の中にモヤがかかった感じですっきりしませんでした。今でもすっきりしている訳ではないのですが、自分なりに噛み砕いた解釈を紹介します。

紹介したいのはこの解釈ではなく(おい)、解釈に至るまでの道のりで得た知識です。

目次

オブジェクトとは?

プログラムにおけるオブジェクトの定義はググると概ね以下のような表現がされています。

  1. プログラムが扱う操作や処理の対象
  2. オブジェクト指向の言語では)クラスのインスタンス
クラス

オブジェクトを生成するための設計図

インスタンス

クラスに基づいてプログラム実行時にコンピュータのメモリ上に展開されたオブジェクト

VBAに置き換えると、

  1. ワークブックやシート、セル、グラフ等そのもの
  2. オブジェクトブラウザ上の「クラス」(ちょっと乱暴ですが)

VBA上のオブジェクトとは「クラスをインスタンス化したもの」といった説明をよくみかけます。言い換えて「設計図を実体化したもの」と解釈しています。ちなみに、他の言語ではクラス由来ではないオブジェクトも存在するようですが、私は「VBAではインスタンス=オブジェクト」と捉えています。

オブジェクトの正体

サンプルをステップ実行して、ローカルウィンドウを覗いてみます。demo1demo2ともにA1セルを参照していますが、中身がちょっと違います。demo1Rangeオブジェクトそのものを参照しています。demo2RangeオブジェクトでValueプロパティを指定しています。

変数をオブジェクト型で宣言すると、複数のプロパティが表示されることからRangeオブジェクトそのものを参照していることが分かります。定義の「プログラムが扱う操作や処理の対象」です。
Sub demo1()
    Dim myVar As Range
    Range("A1") = "よもやよもやだ"
    Set myVar = Range("A1")
End Sub
RangeオブジェクトにValueプロパティを指定すると、変数に入っているのは特定の値のみになりました。が、Range(“A1”).Valueが「プログラムが扱う操作や処理の対象」であることに変わりはありません。
Sub demo2()
    Dim myVar
    Range("A1") = "よもやよもやだ"
    myVar = Range("A1").Value
End Sub

どちらも、定義にあてはめるとオブジェクトになります。demo1はすんなり理解できるのですが、demo2はプロパティで指定したのにオブジェクト?と脳みそが破壊される訳です。

Rangeオブジェクト」とかValueプロパティ」は一度置いておいて、定義のオブジェクトを何となく理解して下さい。コードの記述によって参照されたもの(操作や処理の対象あるいはそのデータ)がオブジェクトです。Range(“A1”)Range(“A1”).Value、どちらもオブジェクトです。

オブジェクト式の階層構造

Application.ActiveWorkbook.ActiveSheet.Range("A1").Value

オブジェクトブラウザを覗くと分かるのですが、Applicationオブジェクトは階層構造になっています(コードを記述するとき、Applicationは省略するケースが多いです)。

Application(オブジェクト
Workbooks(コレクション)→Workbook(オブジェクト
             Worksheets(コレクション)→Worksheet(オブジェクト
                            Range(オブジェクト

                           ┗Value(プロパティ

これらのオブジェクトを返すのはプロパティです。例えばRangeオブジェクトですが、オブジェクトブラウザでWorksheetオブジェクトを確認するとメンバーの中に「Range」がありますが、アイコンをみるとプロパティになっています。

上の階層に戻ってWorkbookオブジェクトを確認するとメンバーの中に「Worksheets」がありますが、これもプロパティです。

Applicationプロパティを参照してApplicationオブジェクトを返し、そのメンバーであるWorkbooksコレクションを返すのにWorkbookプロパティを参照、そのメンバーであるWorksheetsコレクションを返すのに…中略 Rangeオブジェクトを返すのにRangeプロパティを参照、最後にValueプロパティを参照して返されたものが前項の「オブジェクトの正体」です。

最後がプロパティではなくメソッドだとしても、返されたそれはオブジェクトです。

何が言いたいかというと、VBAの文法でよく「オブジェクト.プロパティ(orメソッド)」と表現されているのは階層構造上のオブジェクトを表現しているのであって、厳密には「プロパティ .プロパティ(orメソッド)」だということです。冒頭にも書きましたがオブジェクトを返すのはあくまで「プロパティ(メソッド)」です

「コードの書き出しはプロパティから」のような説明になっているかもしれませんが、それも違います。Application.ActiveWorkbook.ActiveSheet.Range(“A1”).Valueの先頭は確かにApplicationプロパティですが、これも実は省略されています。省略せずに記述するとExcel.Application.ActiveWorkbook.ActiveSheet.Range(“A1”).Valueになります。「(オブジェクト).プロパティ.プロパティ.プロパティ.プロパティ.プロパティ」ということです。やはり脳味噌が破壊されますね…

RangeオブジェクトとRangeプロパティの違い

結論、Web上で見かけるRangeプロパティ」という記述は、「Rangeオブジェクト」が指し示しているものとほとんどの場合同じです。文法を「オブジェクト.プロパティ」と表現しているのは大半の人が理解しやすいようにそうしているのだと思います。ただ、VBAをもうちょっと突き詰めたいと考えている人にとってはこの「オブジェクト.プロパティ」といった表現が弊害になることを憂慮して、「Rangeプロパティ」と表現しているのだと解釈しました。

オブジェクトの定義を自分なりに消化し、階層構造を理解した頃、オブジェクトプロパティといった用語がすんなり頭の中に入ってくるようになりました。Rangeの違いを理解しようとしたときの知識が、思わぬ副作用として現れました。

読んでくださった方、説明下手で申し訳ありませんが雰囲気だけでも読み取ってください。オブジェクトの正体がなんとなく分かるだけで、その後のVBA習得の捗り方が大きく変わってきます。ここではさらっと流しましたが、クラスとメンバーの勉強を並行してすすめればさらに理解は深まります。

それでは、最後までご高覧いただきありがとうございました。

目次
閉じる