毎週のメール作成・送付作業を自動化したい
小売業で働くYasuと申します。スーパー銭湯♨大好きで、最近はボートレースにもはまりつつあります。
私が担当している業務に、「リベートの管理」というものがあります。「リベートとは何ぞや?
」と思われた方も多くいらっしゃることかと思います。
小売業でいうリベートとは、お取引先が取引高や目標達成度に応じて、われわれ小売業者に対して代金を払い戻す仕組みのことを指します。簡単に言えば、「おたくの商品たくさん売るんで、目標達成したらお金くださいね。お互い、WinWinでいきましょう!」みたいな感じです。
「リベート管理」業務の1つに、お取引先に請求書を送付するという業務があります。ただ、1か月に何百件もの請求書発行・郵送業務が発生するため、外部業者に委託しております。そこで1週間に1回、業者への依頼メールを作成しているのですが9部門分 × 3分(1通のメール作成時間)=27分かかっています。
1か月にすると27分 × 4週=月間108分 (約2時間) の作業時間です。![]()
【今までの作業手順】
Gmailを開き、メール作成
宛先に2名、ccで3名を入れる
件名と本文を入力
3つのファイルを添付
メール送信
上記手順を残り8部門分繰り返す
これをGASを使うことで月間108分→20分に短縮することができました![]()
完成したもの
作成手順
| 使用したもの | 用途 |
|---|---|
| GoogleDrive | 添付するファイルを格納 |
| Googleスプレッドシート | メールに入力する各項目を記入 |
| GoogleAppsScript | 自動化のためのコードを入力 |
| ChatGPT | GASのコードを作成 |
作り方(ステップ1)添付ファイル投函用フォルダの設定
マイドライブに、添付ファイル投函用のフォルダを作成します。今回は、1_農産から9_NFまで9つのフォルダを作成しました。
各フォルダにメールに添付したい3つのエクセルファイルを投函します。
①部門別請求書
②請求書の内訳表
③請求書送付先の住所一覧

作り方(ステップ2)Googleスプレッドシートの設定
メール作成時に必要な項目をGoogleスプレッドシートに記入します。今回は、宛先とccのメールアドレス、件名、本文、フォルダID、フォルダ名、担当者名を記入しています。

補足情報①(メール本文の記入)
作り方(ステップ3)GASのコード設定
ChatGPTに下記内容を記入し、コード作成を指示します。
指示:GASのコードを作成してください
内容:A列とB列に宛先のメールアドレス、C列・D列・E列にccのメールアドレス、F列にはメールのタイトル、
G2のセルにはメールの本文があります。メールの本文はすべてG2のセルの内容を貼り付けます。H列に記載さ
れているフォルダIDのフォルダに入っているExcelファイルをメールに添付します。
フォルダにファイルが無い場合は、メールを作成しないでください。 これらすべての情報を取得し、メール
の下書きに保存してください。
次のようなコードが作成されますので、Googleスプレッドシート→拡張機能→Apps Scriptに貼り付けます。
GASのコードはこちらをクリック
```javascript
/**
* スプレッドシートの内容から
* Gmailの下書きを作成する
*/
function createDraftEmails() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
// G2セルの本文を取得
const body = sheet.getRange("G2").getValue();
// A~H列のデータを取得
const data = sheet.getRange(2, 1, lastRow - 1, 8).getValues();
data.forEach((row, index) => {
const rowNumber = index + 2;
// A列・B列:宛先
const toList = [row[0], row[1]]
.filter(email => email && email.toString().trim() !== "")
.join(",");
if (!toList) {
Logger.log(`行${rowNumber}:宛先なしのためスキップ`);
return;
}
// C列・D列・E列:CC
const ccList = [row[2], row[3], row[4]]
.filter(email => email && email.toString().trim() !== "")
.join(",");
// F列:件名
const subject = row[5];
// H列:フォルダID
const folderId = row[7];
if (!folderId) {
Logger.log(`行${rowNumber}:フォルダIDなしのためスキップ`);
return;
}
const attachments = [];
try {
const folder = DriveApp.getFolderById(folderId);
const files = folder.getFiles();
while (files.hasNext()) {
const file = files.next();
const fileName = file.getName().toLowerCase();
// Excelファイルのみ添付
if (
fileName.endsWith(".xlsx") ||
fileName.endsWith(".xls")
) {
attachments.push(file.getBlob());
}
}
// 添付ファイルがない場合は下書きを作成しない
if (attachments.length === 0) {
Logger.log(`行${rowNumber}:Excelファイルなしのためスキップ`);
return;
}
// Gmail下書き作成
GmailApp.createDraft(
toList,
subject,
body,
{
cc: ccList,
attachments: attachments
}
);
Logger.log(`行${rowNumber}:下書き作成完了`);
} catch (e) {
Logger.log(`行${rowNumber}:エラー → ${e}`);
}
});
Logger.log("すべての処理が完了しました");
}
同僚に使い心地を聞いてみた
同僚Aさんのアドバイス(トリガー設定)
同僚Aさん:同じ部署でネットショップの運営を担当。自分よりもデジタルツールの知識が豊富
Aさん:「自分も同じようなGASを使った自動メール配信をやってますよ。今回作られたGASは毎週決まった曜日に実行する業務ですか?であれば、トリガー設定が便利ですよ。」
自分:「そんな機能があるんですね。毎週木曜日にやっている業務なので、その機能は使えそうですね!」
ということで、下記のようにトリガー設定を追加してみました。

同僚Bさんのアドバイス(フォルダからファイル削除)
Bさん:私が以前所属していた部署で、お肉のバイヤーを担当されています。
Bさん:「毎月、10社以上のお取引先に翌月の振分表をメールするという作業をしているので、この機能があれば、かなり時短になりますね!でも、翌月に新しい添付ファイルをフォルダに入れるときに、古いファイルが残っていると削除がめんどくさいですね
」
自分:「確かに!じゃあ、メール作成したあと、フォルダのファイルはゴミ箱に入るようにコードを修正してみるよ。」
ChatGPTに追加条件のコード作成を指示し、改良版を完成させることができました。
GASのコード(改良版)はこちらをクリック
```javascript
/**
* スプレッドシートの内容から
* Gmailの下書きを作成する
* 添付したExcelファイルは下書き作成後にゴミ箱へ移動する
*/
function createDraftEmails() {
// 現在開いているスプレッドシートのシートを取得
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// 最終行を取得
const lastRow = sheet.getLastRow();
// G2セルの本文を取得
const body = sheet.getRange("G2").getValue();
// 2行目から最終行まで、A~H列のデータを取得
const data = sheet.getRange(2, 1, lastRow - 1, 8).getValues();
data.forEach((row, index) => {
const rowNumber = index + 2;
// A列・B列:宛先
const toList = [row[0], row[1]]
.filter(email => email && email.toString().trim() !== "")
.join(",");
// 宛先がない場合はスキップ
if (!toList) {
Logger.log(`行${rowNumber}:宛先なしのためスキップ`);
return;
}
// C列・D列・E列:CC
const ccList = [row[2], row[3], row[4]]
.filter(email => email && email.toString().trim() !== "")
.join(",");
// F列:メールタイトル
const subject = row[5];
// H列:フォルダID
const folderId = row[7];
// フォルダIDがない場合はスキップ
if (!folderId) {
Logger.log(`行${rowNumber}:フォルダIDなしのためスキップ`);
return;
}
const attachments = [];
const filesToDelete = [];
try {
// H列のフォルダIDからフォルダを取得
const folder = DriveApp.getFolderById(folderId);
// フォルダ内のファイルを取得
const files = folder.getFiles();
while (files.hasNext()) {
const file = files.next();
const fileName = file.getName().toLowerCase();
// Excelファイルだけを添付対象にする
if (
fileName.endsWith(".xlsx") ||
fileName.endsWith(".xls")
) {
attachments.push(file.getBlob());
filesToDelete.push(file);
}
}
// Excelファイルがない場合はメールを作成しない
if (attachments.length === 0) {
Logger.log(`行${rowNumber}:Excelファイルなしのためスキップ`);
return;
}
// Gmailの下書きを作成
GmailApp.createDraft(
toList,
subject,
body,
{
cc: ccList,
attachments: attachments
}
);
// 下書き作成後、添付したExcelファイルをゴミ箱へ移動
filesToDelete.forEach(file => {
file.setTrashed(true);
});
Logger.log(`行${rowNumber}:下書き作成完了・Excelファイル削除完了`);
} catch (e) {
Logger.log(`行${rowNumber}:エラー → ${e}`);
}
});
Logger.log("すべての処理が完了しました");
}
おわりに
今回は、毎週実施している業務で大幅な効率化をすることができました。このツールは、自分だけでなく他部署でも大いに役立つということもわかりました。今後も自分の業務のみならず、周りの同僚も巻き込んだ業務改善ツールを作っていきたいと思います。


