0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ノンプロ研 GAS初級講座21期 補講 #4-5

Last updated at Posted at 2023-02-10

概要

ノンプログラマーのためのスキルアップ研究会 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回後の予定です。
引き続きよろしくお願いします!

参考書籍

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?