どうも。つじけ(tsujikenzo)です。このシリーズではVBAの「RangeオブジェクトのRangeプロパティ」がGASの「Rangeオブジェクト」とどう違うのかについて【前編・中編・後編】で書き留めています。今日は最終回の【後編】です。
前回のおさらい
前回は、GASのRangeクラスのメンバーはメソッドのみで、状態を表すプロパティや定数などは用意されていない。そしてGASはサーバーサイドのスクリプトの為、都度SpreadsheetApp APIを叩いてRangeオブジェクトを操作しているというお話をしました。
VBAとGASが出揃ったので最後におさらいしたいと思います。
VBAのRangeクラスとは
メンバー
ExcelライブラリのRangeクラスは、プロパティ(状態・属性)としてRangeプロパティやValueプロパティを、またメソッド(動作)としてActiveメソッドやSelectメソッドなどのメンバーを保有していました。
値の取得と設定
Rangeプロパティはアドレス(”A1”)を渡すことで、SheetオブジェクトからRangeオブジェクトを掴むことができます。
Debug.Print Sheet1.Range("A1").Value 'A1です
Sheet1.Range("A1").Value = “A1たい”
Debug.Print Sheet1.Range("A1").Value 'A1たい
さらに「オブジェクト変数」を使うことで、Rangeオブジェクトを変数に格納して、Valueプロパティを操作することもできます。
Dim A1 As Range
Set A1 = Sheet1.Range("A1")
Debug.Print A1.value 'A1たい
A1.value = "A1です"
Debug.Print A1.value 'A1です
VBAではRangeもValueもプロパティとして操作するのが特徴でした。
GASのRangeクラスとは
メンバー
GASのRangeクラスはGoogle Workspace Serviciesの[SpreadSheetサービス]に所属しており、使う時は[SpreadSheetApp]クラスから順番に[SpreadSheet]→[Sheet]→[Range]と、まるでマトリョーシカのように親から子へ続く階層構造で取り扱います。
Rangeオブジェクトを掴むためのgetRange()メソッドはSheetオブジェクトのメンバーです。
メンバーにはプロパティは無く、全てメソッドです。特に値を操作するget/set系のメソッドを良く使います。
値の取得と設定
Rangeクラスのメソッドであるget/set Value(s)メソッドを使用します。
rangeA1 = SpreadsheetApp.getActiveSheet().getRange('A1');
console.log(rangeA1.getValue()); //A1たい
rangeA1.setValue('A1です');
console.log(rangeA1.getValue()); //A1です
GASではRangeクラスのget/setメソッドとして操作するのが特徴でした。
比べよう
[VBA]
Dim A1 As Range
Set A1 = Sheet1.Range("A1")
Debug.Print A1.value 'A1たい
A1.value = "A1です"
Debug.Print A1.value 'A1です
- Sheetオブジェクトに対して
Rangeクラス(Worksheetクラス 20210103)のRangeプロパティをぶつける - 1で取得したRangeオブジェクトに対してValueプロパティをぶつける
- RangeやValueを取得・設定するメソッドはありません。
VBAはRange/Valueプロパティが用意されているので、ゲッター・セッターと呼ばれるオブジェクトのプロパティにアクセスする方法で値を操作します。(プロパティなのに(引数)を渡しているが気持ち悪いのはその為です)
Selectionプロパティ
さらにVBAではグローバルで使用できるSelectionプロパティ(選択されているセル範囲をRangeオブジェクトとして掴む)があるので、1.の「Sheetオブジェクトに対して~」という手順以外に、現在選択されてるセルからRangeプロパティを操作できるのも特徴的です。
「GAS]
rangeA1 = SpreadsheetApp.getActiveSheet().getRange('A1');
console.log(rangeA1.getValue()); //A1たい
rangeA1.setValue('A1です');
console.log(rangeA1.getValue()); //A1です
- Sheetオブジェクトに対してSheetクラスのgetRange()メソッドをぶつける
- 1で取得したRangeオブジェクトに対してget/set value(s)メソッドをぶつける
- RangeやValueの状態・属性を表すプロパティがありません。
GASは記述方法に関しても、上位オブジェクトを省略できないのも特徴的です。省略する場合は予め変数を用意してオブジェクト代入しておく必要があります。VBAと違って変数の型を宣言しなくていいのは楽ですね。
考察の結果
GASがサーバーサイドで動いていて、GASのサービスを操作する為にAPIを叩いているというのはローカルで動いているVBAと違う特徴的な点でした。
GAS(JavaScript)はクラス(プロトタイプ 20210103)ベースのオブジェクト指向で構成されている言語です。コンストラクタの目的はオブジェクトを生成することであり「これから生成するオブジェクトを初期化する」のが目的です。特にGoogle Workspace Servicesで用意されているクラス群にプロパティを書き換えて操作するメンバ-が(私の知る限り)無いのが、VBAとの最大の違いかも知れません。
神々にとってもVBAのExcelライブラリのRangeオブジェクトは難解なオブジェクトの一つだそうで、初学者の私にとって「VBAのRangeオブジェクトのRangeプロパティ」を理解するのはまだまだ厳しい道のりだなと痛感しました。まずは正しい書き方、使い方、読み方を徹底して学ぶのが先ですね💦
まとめ
以上で、VBAの「RangeクラスのRangeプロパティ」がGASの「Rangeクラス」とどう違うのかについて自分なりにまとめてみました。
この記事を書くにあたってノンプロ研のVBA板にて神・神・神・神様達に助言を頂きまして大変感謝申し上げます。
【追記20201229】
後々見つけたこちらのサイトが非常にわかりやすかったです。GASとVBAの最大の違いは「Rangeオブジェクトに、Rangeプロパティがある」です。
Rangeオブジェクトを参照するにはRangeオブジェクトを返すプロパティの戻り値を使わなければなりません。言い方を変えれば、Rangeオブジェクトを返すプロパティを経由してRangeオブジェクトを参照するという事です。下表は、Rangeオブジェクトを参照するためのプロパティです。
Rangeオブジェクトに、Rangeプロパティがあるあたりが、ちょっと理解しづらいかもしれません。まずは、上表の太字が使えるようになること目指してください。