Open16

GASいろいろ

shotakahashotakaha

ファイルを読み込む

  • IDもしくはURLを指定してファイルを読み込む
const sheet = SpreadsheetApp.openById("スプレッドシートのID";
const doc = DocumentApp.openByUrl("ドキュメントのURL");
  • スクリプトに紐づいたファイルを読み込む
const sheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = SpreadsheetApp.getActiveSheet();
shotakahashotakaha

ログを出力する

  • Logger.logconsole.log の2種類ある
  • ちょっと使うだけならどっちでもよさそう
Logger.log("ログです")
console.log("ログです")
shotakahashotakaha
  • Logger.logの場合は「情報」(infoのこと?)と表示される
  • console.logの場合は「デバッグ」と表示される
shotakahashotakaha

スプレッドシート内のシートを取得する

  • 全てのシートが欲しい時には getSheets が便利
const ss = SpreadsheetApp.openById("ID");
const sheets = ss.getSheets();

Logger.log("シート数 = " + sheets.length);

for (const sheet of sheets) {
    Logger.log("シート名 = " + sheet.getName());
}
  • シート名を指定するともできる
const sheets = SpreadsheetApp
        .getActiveSpreadsheet()
        .getSheetByName("シート名");
shotakahashotakaha

シートをコピーする

  • 別のスプレッドシートにコピーする
const source = SpreadsheetApp.openById("コピー元のID");
const sheet = source.getSheetByName("シート1");
const target = SpreadsheetApp.openById("コピー先のID");

const copied = sheet.copyTo(target);
Logger.log("シート名 = " + copied.getName());
// シート名 = シート1のコピー
  • 別のスプレッドシートにコピーしても「シート1のコピー」というシート名になる
  • 繰り返すと「シート1のコピー2」「シート1のコピー3」...となる
shotakahashotakaha

シートを削除する

  • 上の続き
  • リファレンスを確認すると deleteSheet(sheet) となっている
    • シート名ではなくてsheetオブジェクトを作る必要がある
    • スプレッドシート内のシートが0になる場合はエラーになる
const target = SpreadsheetApp.openById("コピー先のID");
target.deleteSheet(target.getSheetByName("シート1のコピー");

できるかなと思ったけどできなかったこともメモ

  • またやりそうなのでメモ
target.getSheetByName("シート1のコピー").deleteSheet();  // このメソッドはない
target.deleteSheet("シート1のコピー"); // このメソッドもない
shotakahashotakaha

フォームと自動通知

  • Googleフォームに入力があったときに、任意の関係者に自動で通知をする
  • 自分のGmailから、関係者を指定してメールを送信する形式
autoForward.js
function onFormSubmit(e) {

    // フォームの入力情報を取得する
    const timestamp = e.response.getTimestamp();
    const respondent = e.response.getRespondentEmail();
    
    // フォームの回答を取得
    const itemResponses = e.response.getItemResponses();
    const values = itemResponses.map(function(itemResponse) {
        return itemRespons.getResponse()
    });

    const purpose = values[1];
    const date_start = values[7];
    const date_end = values[8];

    // メールの本文を作成する
    const body = `
Googleフォームに申請がありました。
関係者への確認をお願いします。

# 申請日
${timestamp}

# 申請者
${name}

# 掲載期間
開始希望日 ${date_start}
終了希望日 ${date_end}
`

    // メールの件名を作成する
    const subject = `フォームに申請(${name}`;

    // メールを作成する
    const to = "関係者1,関係者2,関係者3";
    const draft = GmailApp.createDraft(to, subject, body);
    draft.sent();    
}
shotakahashotakaha
autoForward.js
function onFormSubmit(e) {
    const timestamp = e.response.getTimestamp();
    const respondent = e.response.getRespondentEmail();
};
  • eはトリガーした「イベント」のようなオブジェクトと考えてよさそう
  • メール通知に必要はデータはe.responseの中にある
  • フォームの回答内容はe.response.getItemResponses()に入っている
shotakahashotakaha
autoForward.js
    // フォームの回答を取得
    const itemResponses = e.response.getItemResponses();
    const values = itemResponses.map(function(itemResponse) {
        return itemResponse.getResponse()
    });
  • 以前は e.valuesという値があったみたいだが、いまはundefinedと言われる
  • 自分でそれっぽい配列valuesを作成している
  • GAS(or JS)の書き方が全然分かってないんだけど、Pythonのリスト内包表記と同じ形式だと思っている
Pythonのリスト内包表記
values = [itemResponse.getResponse() for itemResponse in e.response.itemResponses()]
shotakahashotakaha
autoForward.js
    ....
    const purpose = value[1];
    ....
    const date_start = value[7];
    const date_end = value[8];
    ....
  • 回答データの配列valuesから、わかりやすい変数名に代入する
  • 自分の作ったフォームに合わせて、変数を用意する
shotakahashotakaha
autoForward.js
    ...
    // メールの本文を作成する
    const body = `
Googleフォームに申請がありました。
関係者への確認をお願いします。

# 申請日
${timestamp}

# 申請者
${name}

# 掲載期間
開始希望日 ${date_start}
終了希望日 ${date_end}
`
    ...
  • メール本文を作成する
  • 文字列テンプレートを使って、さきほど詰め直した変数を使う
  • 実際の際のメールにインデントも反映されるので、左詰めにしておく
shotakahashotakaha
autoForward.js
    // メールの件名を作成する
    const subject = `フォームに申請(${name}`;

    // メールを作成する
    const to = "関係者1,関係者2,関係者3";
    const draft = GmailApp.createDraft(to, subject, body);
    draft.send();  
  • メールの下書きを作成してから送る
  • 複数の宛先に送る場合はカンマで区切る
  • 初めて実行する場合には、アプリ権限の許可が必要になる
shotakahashotakaha
  • フォームの送信をトリガーとするのでデバッグがめんどくさかった
  • すべてが空欄でも送信できるテスト用フォームを新規に作成しe.response のデータを確認しながらデバッグした
  • e.valuesという変数が残っていれば、もっと簡単だった
shotakahashotakaha
このアイテムは Google の利用規約に違反しているため、アクセスできません。
  • 動作確認に使っていたフォームがアクセス禁止になってしまったっぽい
  • 短い時間に何度もフォームに入力して、メールを送ったりしたからかな?
  • 次にやるときは注意した方がよさそう