ZeroScript

ゼロからわかるスクリプト

【GAS】もう2度と存在しないシートに苦しまない

f:id:tabemi:20210526221034j:plain


どうも、たべみです。

GAS(Google Apps Script)を触っていると存在しないシートを取得しようとして失敗しますよね。

そんな時、シートを生成してくれる関数とクラスを書きました。


何回もエラーが出るから何とかしたい!シートがないときは作ってほしい
そんな方向けの記事です。

const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName/*存在しないシート*/);
const values = sheet.getDataRange().getValues(); // => エラー!!!

解決策その1

では、さっそく。

関数を用いる

function getSheet_(sheetName) {
  const sheet = SS.getSheetByName(sheetName);
  if (!sheet) {//ない場合は
    return SS.insertSheet().setName(sheetName);//シートを挿入する
  } else return sheet;//存在している場合はそのまま返す
}

使い方

function myfuntion() {
  const sheet = getSheet('シート10');
}

うーーん、いい感じです。

解説

const sheet = SS.getSheetByName(sheetName);

シートが存在しなかった場合、getSheetByName()は null を返します
null は false 判定となりますが、 ! (反転演算子) で true となりif文で括弧内の処理に移ります
insertSheet()は新しいシートを作成します。

重要な懸念点

使用すると入力補完が出ません
これがなかなか不便でして、@return を書く方法があるのかと思案しております。要調査です。

function myfuntion() {
  const sheet = getSheet('シート10');
  sheet.  //何も出てこない。 //getDataRange()とか補完してほしい
}

もっと短く書いて懸念点を解決する場合

const sheet = SS.getSheetByName(sheetName) || SS.insertSheet().setName(sheetName);

左辺が null なら右辺が返されるようになっていますが、見にくいですね、、
短く書くのもいいですが、ぱっと見よく分からないのはよくないかもしれないです。

解決策その2

入力補完がないのは不便ですので、ほかの方法をご紹介します!
なかなか使いやすいのではないかと!

クラスを用いる

class Sheet {
  constructor(sheetName) {
    const SS = SpreadsheetApp.getActiveSpreadsheet();
    let sheet = SS.getSheetByName(sheetName);
    if (!sheet) sheet = SS.insertSheet().setName()
    this.sheet = sheet;
  }
  /**
   *シートのすべての値を取得する
   * @return {Array[]}
   */
  getDataRangeValues() {
    return this.sheet.getDataRange().getValues();
  }
  /**
   * 2次元配列をシートに貼り付ける
   * @param {Array[]} values
   */
  setValues(values) {
    const row = 1;
    const column = 1;
    const rowNums = values.length;
    const numColumns = values[0].length;
    this.sheet.getRange(row, column, rowNums, numColumns).setValues(values);
  }
}

使い方

function myfuntion() {
  const sheetName = 'シート11';
  const sheet = new Sheet(sheetName);//インスタンス化
  const values = sheet.getDataRangeValues();
  values.forEach(x => {
    x.forEach(y => console.log(y)) //なんらかの処理
  })
  sheet.setValues(values);
}

クラスなので new を使ってインスタンス化、その後メソッドを呼び出すという形です。
入力補完もつくので良いです!

f:id:tabemi:20210526214109p:plain
インスタンス化してメソッドを呼び出す

解説

シートを扱う関数をすべて class 内のメソッドで行います
値の出し入れ以外に行う場合は、さらにメソッドを作りましょう!

もちろん入力補完が出ますよ。(それしか言わない。)

f:id:tabemi:20210526214105p:plain:w450
入力補完が出た

最後に

シートの取得だけでもの凄く勉強になりますね。ぜひ、こちらをコピペして活用してください!

今回は、シートがないときに作成しつつ取得する関数とクラスを作成してみました!


ではでは~