【GASで月次提出物を自動リマインド】#2
こんにちは!
エルフィールドでエンジニアとして働いている、S.Yと申します。
前回の#1では、Spreadsheetにデータを用意し、実行ボタンなどツールの外枠を作りました。
今回は後半編として、GASを使ったメール送信とファイル操作の自動化部分を紹介します。
社員名簿から情報を取得
まずは、Spreadsheetから社員情報を取得します。
GASでは以下のメソッドを使うことで、Spreadsheet内のデータを簡単に取得できます。
<主に使用するメソッド>
- getSheetByName() → シートオブジェクトを取得
- getRange() → セル範囲を指定
- getValues() → 範囲内の値を2次元配列として取得
- getValue() → 単一セルの値を取得)
- SpreadsheetApp.Direction.DOWN→ 指定セルから下方向のデータ範囲を取得する際に使用
提出物テンプレートをドライブから取得
提出物のテンプレートファイルは、Googleドライブ(マイドライブ)に保存しておきます。
<処理の流れ>
- フォルダIDを取得
- getFolderById()でフォルダオブジェクトを取得
- Spreadsheet、Gmail、Calendar、Googleドライブと簡単に連携可能
- makeCopy()で社員ごとにファイルをコピー)
- コピー後に社員番号・氏名・年月を付けてリネーム
これにより、誰の提出物か一目で分かるファイル名になります。
メール送信
GASではGmailAppを使うことで、簡単にメール送信ができます。
<使用するメソッド>
- GmailApp.sendEmail()
→ Gmailからメールを送信
→ 添付ファイルを送る場合は、attachmentsオプションを指定
- setTrashed(true)
→ コピーして作成した一時ファイルを処理後にゴミ箱へ移動
トリガー設定
ツールを自動実行するために、時間トリガーを設定します。
<設定方法>
1.GASエディタ左メニューの時計マーク「トリガー」をクリック
2.「トリガーを追加」を選択

3.実行関数・イベントソース(時間主導型)を設定
4.実行日時を指定
今回は例として、毎月25日の夕方に自動送信するよう設定しました。
これにより、提出期限前に自動でリマインドメールが送信されます。

実行結果
実際に実行してみると、以下の処理が正しく実行されることを確認できました。
- 社員名簿に登録された人数分のメールが送信
- 各社員ごとに提出物ファイルを生成
- メールに自動添付
添付ファイル名は以下の形式になります。
(ファイル名_社員番号_氏名_YYYYMM.拡張子)
注意点
今回の実装で気を付けたポイントをいくつか紹介します。
- Googleドライブはファイル・フォルダをIDで管理
→スクリプト内では、フォルダID・ファイルIDを指定して操作します。
- Spreadsheet操作の処理順
→処理が前後する場合があるため、SpreadsheetApp.flush() や Utilities.sleep() を使用して
処理完了を待つことがあります。
- エラー状態で保存すると変更が反映されない
→GASではコンパイルエラーがある状態で保存すると、スクリプトが正しく更新されない場合があります。
実装コード(抜粋)
今回作成したスクリプトの一部を紹介します。
function executeApplication() {
// Spreadsheet取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// 社員名簿シート
var sheetEmployeeList = spreadsheet.getSheetByName(“社員名簿”);
var lastRowEmp = sheetEmployeeList.getRange(“A2”)
.getNextDataCell(SpreadsheetApp.Direction.DOWN)
.getRow();
var employeeList = sheetEmployeeList.getRange(“A2:E” + lastRowEmp).getValues();
// ツールシート
var sheetTool = spreadsheet.getSheetByName(“ツール”);
var lastRowFil = sheetTool.getRange(“A18”)
.getNextDataCell(SpreadsheetApp.Direction.DOWN)
.getRow();
var fileListSpread = sheetTool.getRange(“A19:A” + lastRowFil).getValues();
// メールテンプレート
var sheetMailTemplate = spreadsheet.getSheetByName(“メールテンプレ”);
var subject = sheetMailTemplate.getRange(“A3”).getValue();
var text = sheetMailTemplate.getRange(“A5”).getValue();
// 本日日付(YYYYMM)
var date = new Date();
var yearMonth = Utilities.formatDate(date, ‘JST’, ‘YYYYMM’);
// フォルダID(仮の値)
const idDirFile = “FOLDER_ID_SAMPLE”;
const idDirTmp = “TMP_FOLDER_ID_SAMPLE”;
// 添付用ファイルリスト
var fileList = [];
// 申請書の取得
for (let i = 0; i < fileListSpread.length; i++) {
let files = DriveApp.getFolderById(idDirFile).getFilesByName(fileListSpread[i][0]);
if (files.hasNext()) {
fileList.push(files.next());
} else {
SpreadsheetApp.getUi().alert(“error”, “指定されたファイルがドライブに存在しません。”, SpreadsheetApp.getUi().ButtonSet.OK);
return false;
}
}
// 社員ごとにメール送信
for (let i = 0; i < employeeList.length; i++) {
let tmpSubject = subject + “_” + yearMonth;
// 仮の値に置き換え
let mailaddress = “sample@example.com”; // メールアドレス列
let employeeNumber = “12345”; // 社員番号列
let employeeName = “山田太郎”; // 氏名列
// tmpフォルダ内に社員用ディレクトリ作成
let dir = DriveApp.getFolderById(idDirTmp);
let tmpDirName = “tmp_” + employeeNumber + “_” + employeeName + “_” + yearMonth;
let tmpDir = dir.createFolder(tmpDirName);
// ファイルコピーと名前変更
let copyFileList = [];
for (let j = 0; j < fileList.length; j++) {
let tmpFileName = fileList[j].getName();
let fileCopyName = tmpFileName.substring(0, tmpFileName.lastIndexOf(‘.’))
+ “_” + employeeNumber + “_” + employeeName + “_” + yearMonth
+ tmpFileName.substring(tmpFileName.lastIndexOf(‘.’));
let copyFile = fileList[j].makeCopy(fileCopyName, tmpDir);
copyFileList.push(copyFile);
}
// メール送信
GmailApp.sendEmail(mailaddress, tmpSubject, text, {attachments: copyFileList});
// コピーした社員用ディレクトリ削除
tmpDir.setTrashed(true);
}
}
まとめ
今回の記事では、
- Spreadsheetからのデータ取得
- Googleドライブのファイルコピー
- Gmailによるメール送信
- トリガーによる自動実行
これらを組み合わせて、月次提出物のリマインドを自動化するツールを作成しました。
GASは環境構築が不要で、Googleサービスと簡単に連携できるのが大きな魅力です。
身近な業務のちょっとした手間を減らすツールとして、とても使いやすいプラットフォームだと感じました。
最後までお読みいただき、ありがとうございました!
今回のツール作成を通して、GASによる業務自動化の便利さを少しでも感じていただけたら嬉しいです。
それではまた別のテーマでお会いしましょう!👋