3
4

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 3 years have passed since last update.

[GAS]スプレッドシートのシートから取るところをルール化したらよくなった

Last updated at Posted at 2022-03-13

はじめに

GASの大部分の処理はスプレッドシート関連、すなわち

  • スプレッドシートにある以下のような情報を取得する
    • 従業員情報
    • グーグルフォームの情報
    • 売上情報
  • スプレッドシートにある情報を編集する
    • 従業員情報を修正したり
    • 従業員情報にグーグルフォームの情報を追加したり

だと思います。スプレッドシートをデータベースとして使うイメージですね。

高頻度で触る処理になるので、以下のようなルールを設けてみたらうまくいきました。

  1. シートの情報は連想配列でまとめる
  2. シートの情報をとるときは基本共通処理を使う
  3. シートの情報をとったときはクラスに格納する

です。

ルール1 シートの情報は連想配列でまとめる

sheet.gs
const SHEET = {
  member : {
    name : '従業員情報',
    row : {
      // 実際にデータが何行目からあるかを定義しています。共通処理の中でここの情報を取得しています。
      data : 2,
    },
    column : {
      // 何列目になんの情報があるかを定義してます。後ほどクラスに設定するときに使います。
      id : 1,
      name : 2,
      status : 3,
    },
  },
  form : {
    name : 'フォーム',
    row : {
      data : 2,
    },
    column : {
      time : 1,
      id : 2,
      text : 3,
    },
  },
};

ルール2 シートの情報をとるときは基本共通処理を使う

sheet.gs

// シートからの情報を取得する処理(見出しを省く)
function getSheetData(sheetConfig, spreadSheetId){
  let data = getSheetDataFull(sheetConfig, spreadSheetId);
  [...Array(sheetConfig.row.data - 1)].forEach(_ => data.shift());
  return data;
}

// シートからの情報を取得する処理(見出しを省かず、シートの情報全体をとる)
function getSheetDataFull(sheetConfig, spreadSheetId){
  const ss = (spreadSheetId !== undefined)
    ? SpreadsheetApp.openById(spreadSheetId)
    : SpreadsheetApp.getActive();

  const sheet = ss.getSheetByName(sheetConfig.name);
  return ss.getSheetByName(sheetConfig.name).getDataRange().getValues();
}

// 1つのセルに対して情報を設定
function setText(sheetConfig, row, column, text){
  setList(sheetConfig, row, column, [[text]]);
}

// 複数のセルに対して情報を設定
function setList(sheetConfig, row, column, list){
  if(!list.length) return;
  const sheet = SpreadsheetApp.getActive().getSheetByName(sheetConfig.name);
  sheet.getRange(row, column, list.length, list[0].length).setValues(list);
}

// シート全体を更新
function refreshSheet(sheetName, list, startColumn, startRow){

  if(!list[0].length) return;
  const sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);

  startRow = startRow ? startRow : 2;
  startColumn = startColumn ? startColumn : 1;
  sheet.getRange(startRow, startColumn, sheet.getLastRow(), list[0].length).clear();
  sheet.getRange(startRow, startColumn, list.length, list[0].length).setValues(list);
}

// シートに情報を追加(見出しの下の行から足す)
function addSheet(sheetConfig, column, list){
  if(!list.length) return;
  const sheet = SpreadsheetApp.getActive().getSheetByName(sheetConfig.name);
  sheet.insertRows(sheetConfig.row.data, list.length);
  sheet.getRange(sheetConfig.row.data, column, list.length, list[0].length).setValues(list);
}

// シートに情報を追加(シートの最後の行から足す)
function addSheetLastRow(sheetConfig, list, column){
  if(!list.length) return;
  const sheet = SpreadsheetApp.getActive().getSheetByName(sheetConfig.name);

  sheet.getRange(
    sheet.getLastRow() + 1,
    column !== undefined ? column : 1,
    list.length,
    list[0].length
  ).setValues(list);
}

ルール3 シートの情報をとったときはクラスに格納する

取得するところ

sheet.gs
function getMemberList(){
  return getSheetData(SHEET.member).map(row => new Member(row));
}

クラスを定義しているところ

class/Member.gs
class Member{
  constructor(row){
    this.id = row[SHEET.member.column.id - 1];
    this.name = row[SHEET.member.column.name - 1];
    this.status = row[SHEET.member.column.status - 1];
  }

  isValid(){
    return this.id !== ''
      && this.name !== ''
      && this.status !== '';
  }

  getHonorificName(){
    return `${this.name} 様`;
  }
}

効果

上のようなルールを設けることで

  • 列が変わったときにも対応が容易になった
  • PGやコードレビューがしやすくなった

などの恩恵がありました。
フレームワーク化もしてみたいなぁと思いつつ一旦こんな運用をしています。

3
4
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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?