Open21
GASいろいろ
リファレンス
- 左のサイドバーにそれぞれのサービス名がある
-
DocumentApp
、SpreadsheetApp
、DriveApp
みたいにサービスApp
が基本系 - 必要なメソッドは都度検索する
ファイルを読み込む
-
ID
もしくはURL
を指定してファイルを読み込む
const book = SpreadsheetApp.openById("スプレッドシートのID");
const docs = DocumentApp.openByUrl("ドキュメントのURL");
- スクリプトに紐づいたファイルを読み込む
const book = SpreadsheetApp.getActiveSpreadsheet();
const sheet = SpreadsheetApp.getActiveSheet();
新規作成する
const book = SpreadsheetApp.create("新しいスプレッドシート名");
// 新規に作成したURLとIDを確認
const bookUrl = book.getUrl();
const bookId = book.getId();
-
create
で新しいスプレッドシートを作成できる -
getUrl
、getId
で新しく発行された情報を取得できる
ログを出力する
-
Logger.log
とconsole.log
の2種類ある - ちょっと使うだけならどっちでもよさそう
Logger.log("ログです")
console.log("ログです")
-
Logger.log
の場合は「情報」(infoのこと?)と表示される -
console.log
の場合は「デバッグ」と表示される
スプレッドシート内のシートを取得する
- 全てのシートが欲しい時には
getSheets
が便利
const book = SpreadsheetApp.openById("ID");
// ブック内のシートを配列として取得
const sheets = book.getSheets();
// シート数を確認
Logger.log(`シート数 = ${sheets.length}`);
// シートごとの名前を確認
for (const sheet of sheets) {
Logger.log("シート名 = " + sheet.getName());
}
- シート名を指定する
const book = SpreadsheetApp.getActiveSpreadsheet();
const sheet = book.getSheetByName("シート名");
シートをコピーする
- 別のスプレッドシートにコピーする
// ブックを開く
const source = SpreadsheetApp.openById("コピー元のID");
const target = SpreadsheetApp.openById("コピー先のID");
// コピーしたいシートを取得
const sheet = source.getSheetByName("シート1");
// シートをコピー(してコピーしたシートを取得)
const copied = sheet.copyTo(target);
Logger.log(`シート名= ${copied.getName()}`);
// シート名 = シート1のコピー
- 別のスプレッドシートにコピーしても「シート1のコピー」というシート名になる
- 繰り返すと「シート1のコピー2」「シート1のコピー3」...となる
シートを削除する
- 上の続き
- リファレンスを確認すると
deleteSheet(sheet)
となっている- シート名ではなくて
sheet
オブジェクトを作る必要がある - スプレッドシート内のシートが0になる場合はエラーになる
- シート名ではなくて
const target = SpreadsheetApp.openById("コピー先のID");
target.deleteSheet(target.getSheetByName("シート1のコピー");
できるかなと思ったけどできなかったこともメモ
- またやりそうなのでメモ
target.getSheetByName("シート1のコピー").deleteSheet(); // このメソッドはない
target.deleteSheet("シート1のコピー"); // このメソッドもない
ブックを削除する
const file = DriveApp.getFileById("削除したいID");
file.setTrashed(true);
- スプレッドシート全体を削除する場合、
DriveApp
からファイルオブジェクトを取得する - ファイルオブジェクトをゴミ箱に移動する(30日後に自動削除)
フォームと自動通知
- 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();
}
autoForward.js
function onFormSubmit(e) {
const timestamp = e.response.getTimestamp();
const respondent = e.response.getRespondentEmail();
};
-
e
はトリガーした「イベント」のようなオブジェクトと考えてよさそう - メール通知に必要はデータは
e.response
の中にある - フォームの回答内容は
e.response.getItemResponses()
に入っている
autoForward.js
// フォームの回答を取得
const itemResponses = e.response.getItemResponses();
const values = itemResponses.map(function(itemResponse) {
return itemResponse.getResponse()
});
- 以前は
e.values
という値があったみたいだが、いまはundefined
と言われる - 自分でそれっぽい配列
values
を作成している -
GAS
(orJS
)の書き方が全然分かってないんだけど、Python
のリスト内包表記と同じ形式だと思っている
Pythonのリスト内包表記
values = [itemResponse.getResponse() for itemResponse in e.response.itemResponses()]
autoForward.js
....
const purpose = value[1];
....
const date_start = value[7];
const date_end = value[8];
....
- 回答データの配列
values
から、わかりやすい変数名に代入する - 自分の作ったフォームに合わせて、変数を用意する
autoForward.js
...
// メールの本文を作成する
const body = `
Googleフォームに申請がありました。
関係者への確認をお願いします。
# 申請日
${timestamp}
# 申請者
${name}
# 掲載期間
開始希望日 ${date_start}
終了希望日 ${date_end}
`
...
- メール本文を作成する
- 文字列テンプレートを使って、さきほど詰め直した変数を使う
- 実際の際のメールにインデントも反映されるので、左詰めにしておく
autoForward.js
// メールの件名を作成する
const subject = `フォームに申請(${name})`;
// メールを作成する
const to = "関係者1,関係者2,関係者3";
const draft = GmailApp.createDraft(to, subject, body);
draft.send();
- メールの下書きを作成してから送る
- 複数の宛先に送る場合はカンマで区切る
- 初めて実行する場合には、アプリ権限の許可が必要になる
- フォームの送信をトリガーとするのでデバッグがめんどくさかった
- すべてが空欄でも送信できるテスト用フォームを新規に作成し
e.response
のデータを確認しながらデバッグした -
e.values
という変数が残っていれば、もっと簡単だった
このアイテムは Google の利用規約に違反しているため、アクセスできません。
- 動作確認に使っていたフォームがアクセス禁止になってしまったっぽい
- 短い時間に何度もフォームに入力して、メールを送ったりしたからかな?
- 次にやるときは注意した方がよさそう
スプレッドシートの値をJSONに変換したい
とりあえずこのあたりの記事を読む
シートにあるデータを選択
const book = SpreadsheetApp.getActiveSpreadsheet();
const sheet = book.getActiveSheet();
const range = sheet.getDataRange();
const rows = range.getValues();
// 最初は見出し行(であることが多いはず)
const headers = rows[0];
const data = rows.slice(1);
- データの範囲を数値で指定
const nrows = sheet.getLastRow();
const ncols = sheet.getLastColumn();
const range = sheet.getRange(1, 1, nwors, ncols);
Slack連携
ファイル名を変更したい
/**
* @param {string} id - スプレッドシートID
*/
function renameBook(id) {
// IDを指定してスプレッドシートを取得
const book = SpreadsheetApp.openById(id);
// 現在のファイル名を取得
// 20241115_ファイル名 の形式
const currentName = book.getName();
// YYYYMMDD_ を削除 => 8桁の数字
const stem = currentName.replace(/^\d{8}_/, "");
// 現在時刻を取得
// 20241119
const now = new Date();
const jst = Utilities.formatDate(now, "JST", "yyyyMMdd");
// 新しいファイル名
// 20241119_ファイル名
const newName = `${jst}_{stem}`
// ファイル名を変更する
book.rename(newName)
return book;
}
- ファイル名の先頭に日付(
yyyyMMdd
)を付与しておくと、あとから探しやすい - 更新した場合は、ファイル名も現在時刻にしたい
- ただ閲覧したときに更新してほしくないので、
onEdit
などは不向き - 意図をもって更新した場合に、ファイル名を変更したいので、メニューにカスタムボタンを追加するのがいいのかもしれない