概要
ノンプログラマーのためのスキルアップ研究会 GoogleAppsScript初級講座
第4回「オブジェクト」
第5回「スプレッドシート・シート・セルの操作」
についての非公式の補講記事です。
21期講師のTaitoが執筆しています。
オブジェクト周りの話は用語の取り扱いが難しく、正確に書き切れる自信がありません。
用語について混乱があれば、都度ご質問くださいませ。
調べ方
講座内でちらっと触れましたが
この回以降は如何にオブジェクトのメソッドを効率よく探すか
が重要になってきます。
構文は理解した。あとは辞書を引くだけ。
という状態が理想的ですね。
辞書・リファレンスは以下の2サイトを参考にしましょう。
Google Apps Script REFERENCE: (Google公式)
https://developers.google.com/apps-script/reference
JavaScript | MDN: (Javascript準公式)
https://developer.mozilla.org/ja/docs/Learn/JavaScript
第4回 オブジェクト
ここだけおぼえるポイント
- { プロパティ: 値 }
- { key: value }
- 値はプロパティを指定して参照する(取り出す)
- ドット.記法はシンプル
- プラケット["記法"]は変数の使用ができる
- 値に関数が入る場合は
メソッド
と呼ぶ - 実は、GASで扱うすべてのデータはオブジェクトになっている
- "hoge" ← Stringオブジェクト
- 123 ← Numberオブジェクト
- [1, 2, 3] ← Arrayオブジェクト
- SpreadsheetApp ← トップレベルオブジェクト
- console ← Javascriptの組み込みオブジェクト
-
オブジェクトに対してメソッドを呼び出していく
のが、GAS操作の基本
基本構文
const obj1 = { name: "Bob", age: 25 };
// プロパティ名は自動で文字列になるので"クォーテーション"は不要
// プロパティの追加・更新
obj1.favorite = "apple";
obj1["name"] = "Tom";
// 改行したほうが見やすいですね ,を忘れずに
const obj2 = {
height: 10,
width: 20,
getArea() { // メソッド
return this.height * this.width; // ↑のプロパティを参照
},
setHeight(num) { // メソッドには引数も渡せる
this.height = num;
}
}
// メソッドの追加は関数リテラル
obj2.メソッド名 = function() {
// 処理
}
オブジェクトは
- 文字列や数値と同じ
データ型
である - かつ、
すべてのデータはオブジェクト
でもある - プログラミング用語では「オブジェクト」は更に広い意味を持つ
と、多義性に満ちた概念です。
ややこしくて、GAS初学者が最初につまずきやすいポイントです。
自分も最初は全然理解できませんでした。今も怪しいです。
第4回では
「データ型としてのオブジェクト」
「プロパティをキーとしたデータ集合としてのオブジェクト」
の話をしていました。
ひとつひとつ、ゆっくりモノにしていきましょう。
for..in文について
オブジェクトの要素を列挙する場合は、for..in文を使います。
const obj = {name: "Bob", age: 25};
for(const key in obj) {
console.log(key);
// name→age プロパティが順に出力
console.log(obj[key]); // ブラケット記法
// Bob→25 値が順に出力
}
for..文というのは、反復可能なデータの全要素をループする
制御構文です。
for..of文もそうでしたね。
実は、配列はオブジェクトでもあるのでfor..in文でも書けます。
const array = [1, 2, 3];
for (const index in array) {
console.log(index);
// 0→1→2 // インデックスが順に出力 (文字列として)
console.log(array[index]);
// 1→2→3 // 値が順に出力
}
配列ではfor..of文を使います。ただ、
- オブジェクトは
プロパティ
をキーとしたデータの集合 - 配列は
インデックス
をキーとしたデータの集合
この構造が似ていることを理解しておきましょう。
配列⇔オブジェクトを変換すること、よくあります。そういう時に役に立ちます。
メソッドについて
基本形はこちらのメソッド定義
です。
const obj = {
メソッド名() {
// 処理
}
}
obj.メソッド名(); // 実行
上記は簡略化された書き方(糖衣構文)で、実際には以下のように関数リテラルの代入
が行われています。
const obj = {
メソッド名: function() {
// 処理
}
}
ここで関数リテラルと聞いてアロー関数
を思い出すかもしれませんが、
アロー関数でメソッドを書いてはいけません。
理由は難解です!以下はいちおうの参考例ですが飛ばしてOKです。
const person = { name: 'Bob' }
// 通常の関数リテラルで定義
person.greet1 = function () {
console.log(`My name is ${this.name}`);
}
// 同じ処理をアロー関数で定義
person.greet2 = () => console.log(`My name is ${this.name}`);
function myFunction() {
this.name = 'Alice'; // myFunctionのプロパティ
person.greet1(); // My name is Bob
// 通常の関数リテラルでは、thisはメソッドを含むオブジェクトを参照します
person.greet2(); // My name is Alice
// アロー関数では、thisはオブジェクトの外側を参照する特性があります
}
このほか、オブジェクトについて学んでいくと
- 値渡しと参照渡し
- クラスとインスタンス
- プロトタイプ
- オブジェクト指向
などなど、一筋縄ではいかない概念がたくさん出てきます(GAS中級講座の対象です)。
理解しなければ実務で使えない…というわけではありませんが、
- なぜオブジェクトの中にメソッド(関数)を書く必要があるのか?
- なぜGASのすべてのデータはオブジェクトになっているのか?
深掘りしてみたい方は、学んでみるのも面白いかもしれません。
第5回 スプレッドシート・シート・セルの操作
いやいや、ややこしいオブジェクトの話なんてやめましょう!
よく分かんなくても使えるのがオブジェクトのいいところです!
スプレッドシートでオブジェクトをがんがん使い倒していきましょう。
ここだけおぼえるポイント
- スプレッドシートは操作したい対象毎にオブジェクトがある
- Spreadsheet スプレッドシートファイル
- Sheet スプレッドシート内の各シート
- Range シート内の範囲
- Value 範囲から取得した値
- 上から順番につかんで操作する
- メソッド1回呼び出し毎に変数に入れてもいいし、繋げて書いてもいい
// 1つずつ変数に入れる
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet(); // 後で使いたければ変数に入れておきましょう
const range = sheet.getDataRange();
const values = range.getValues();
// 繋げて書く(メソッドチェーン)
const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
アクティブとは
コンテナバインドスクリプトでは、紐づけられたスプレッドシートがアクティブ
になります。
const ss = SpreadsheetApp.getActive(); // getActiveSpreadsheet()と同じ
// 紐づいたスプレッドシートが取得できる
// スタンドアロンスクリプトで↑を書くとエラーになります IDかURLで取りましょう
スプレッドシートを取得した後のアクティブなシート
は文脈によって対象が変わってしまいます。
const sheet = ss.getActiveSheet();
// コンテナバインドなら、今開いているシート
// スタンドアロンなら、一番左側のシート
注意しましょう。
このように、シートの指定には苦労がつきものですが、
- シート名で指定
- インデックスで指定
- アクティブで指定
どれも一長一短で、完ぺきな方法はありません。運用でカバーしましょう!
Range
範囲指定はgetDataRange()だけ使えばOKとお伝えしましたが
- シートの1行目に空白がある
- セルが結合されている
- シートの中に複数のテーブルがある
などの場合、途端に役立たずになります。
(このようなシートを非構造化データと呼びます。第6回で取り扱います)
また特定のセルのみに値を書き込みたい場合は
アドレスでセル指定の方が効率的なので、状況に応じて使い分けましょう!
getRange()は、2パターンの引数を理解しておけばOKです。
sheet.getRange(アドレス文字列);
sheet.getRange(開始行, 開始列, 取得行数, 取得列数); // 行数列数は省略可
sheet.getRange('A1:C3'); // A1からC3セルまで
// 同じ
sheet.getRange(1, 1, 3, 3); // 1行1列目から3行3列分
getValuesとsetValuesについては次回に続く
次回更新は講座第7回後の予定です。
引き続きよろしくお願いします!
参考書籍