Googleスプレッドシートに入力したデータをGoogle Apps Scriptと連携させることで、特定のタイミングで任意の内容のメールを送る(通知メールの送信)設定ができます。
今回は購入商品の仕入れ予定日通知メールのコードの組み方を例に出しつつ、コードの構成をご紹介致します。
※コピペで使用できるサンプルコード付き
※2022年11月4日修正
初期設定
スプレッドシートとGASの連携
以下の手順でスプレッドシートとGoogle Apps Scriptを連携させます。
- 設定したいスプレッドシートを開く
- スプレッドシート上メニュー「拡張機能」>「Apps Script」
- Google Apps Scriptのコード編集画面(プロジェクト編集画面)に遷移
- プロジェクト編集画面上部の「無題のプロジェクト」部分を編集して、適当なプロジェクトタイトルを設定
以上で設定したいスプレッドシートとGoogle Apps Scriptの連携設定は完了です。
続いて、スプレッドシートと今回作成したGASプロジェクトの「タイムゾーン」を設定していきます。
タイムゾーンの設定
スプレッドシートとGAS、それぞれのタイムゾーンが異なっている場合、コードを組んでいく上で時間の計算に狂いが生じる可能性があります。
先にタイムゾーンを統一しておきましょう。
スプレッドシートのタイムゾーンを設定する
- スプレッドシート上メニュー「ファイル」 > 「設定」
- 「このスプレッドシートの設定」画面が開いたら、「全般」タブ内のタイムゾーンを「(GMT+09:00) Tokyo」に設定します。(日本時間を使用する場合)
- 右下の「設定を保存」ボタンをクリックして設定を保存
Google Apps Script(GAS)のタイムゾーンを設定する
- GAS(https://script.google.com/home)を開く
- 「自分のプロジェクト」の中から設定したいプロジェクトを選択する(※プロジェクトを作成していない場合は上記「スプレッドシートとGASの連携」の手順で先にプロジェクトを作成してください)
- 左メニューの「歯車マーク」を選択
- 全般設定内のタイムゾーンを先程設定したスプレッドシートと同じタイムゾーンに設定する(日本時間にする場合は「(GMT+09:00) 日本標準時 - 東京」を選択)
GASコード編集方法
GASで使われているコードの言語は「JavaScript」に近いです。
コードの編集はGoogle Apps Scriptで直接組むことをオススメします。
デバッグ機能もありますので、操作性は高いです。
Apps Script – Google Apps Script
コードを組む - 自動メール送信設定
下記の「変数」の部分は任意に設定できます。
お好きな名前を設定してください。
- var 変数
- const 変数
ステップ1
function名の設定・シートの取得
function名を設定します。
function名は、組んだコード(作成したプロジェクト)を起動させるトリガーの設定時に必要になります。
トリガーの設定はGoogle Apps Script左メニュー「マイトリガー」から設定できます。
スプレッドシートの「どのシート」からデータを参照するのか指定します。
function mailSend() { var mySs = SpreadsheetApp.getActiveSpreadsheet(); // スプレッドシートを取得 var Sheet = mySs.getSheetByName('シート名を記入'); // シート名を取得 }
ステップ2
シートの列の名前を定義
参照する列の名前(const 変数)を設定します。
const 変数 = シード左からn列目
/* 繰り返し計算式の変数を定義 */ /* const 変数 = 数字(左から何列目なのかを記述 - C列なら「3」と記述); */ const ORDER_DATE = 1; // A列 「発注日」を取得 const ORDER_NUMBER = 2; // B列 「注文番号」を取得 const INVOICE_NUMBER = 3; // C列 「請求書番号」を取得 const SHIPPING_DATE = 4; // D列「仕入予定日」を取得 const STATUS = 5; // E列 「状態」を取得 const SHIPPING_NUMBER = 6; // F列「追跡番号」を取得 const SHIPPING_URL = 7; // G列「追跡番号URL」を取得 const ORDERER = 9; // I列「購入者」を取得 const MODEL_NUMBER = 11; // K列 「製品型番」を取得 const USE = 12; // L列 「用途」を取得 const CATEGORY = 15; // O列 「カテゴリ」を取得 const SHOP = 16; // P列 「発注先」を取得 const PIECE = 17; // Q列 「発注数」を取得 const PRICE = 19; // S列 「合計金額」を取得
ステップ3
日付を取得・日本時間に設定
取得した日付の表示形式と表示時間を設定します。
サンプルコードでは、日付の表示形式を「YYYY年MM月DD日(曜日)」、表示時間を「日本時間」に設定しています。
/* 今日の日付を取得し文字列を成形する */ new Date().toLocaleString({ timeZone: 'Asia/Tokyo' }); const tmp_today = new Date(); // 今日の日付を取得 const yy = tmp_today.getFullYear(); const mm = tmp_today.getMonth(); const dd = tmp_today.getDate(); const today = new Date(yy, mm, dd); const options = { weekday: 'short', year: 'numeric', month: 'long', day: 'numeric', timeZone: 'Asia/Tokyo' }; // 日付の表示形式を「YYYY年MM月DD日(曜日)」、表示時間を「日本時間」に設定
ステップ4
データの参照・処理範囲を指定
何行目から何行目までのデータを参照・処理するのかを指定します。
始まりの行を指定し、最終行を自動的に取得する設定にしたい場合(※推奨)
for(let i = n行目; i <= lastRow; i++)
/* 繰り返し計算 */ const lastRow = Sheet.getLastRow(); // データが含まれている最終行を自動取得 for(let i = 3; i <= lastRow; i++) { // 3行目からデータが含まれている最終行までを繰り返し処理 }
始まりの行と最後の行を数値で設定したい場合
for (var i = n行目; i <= m行目; i++)
/* 繰り返し計算 */ for (var i = 3; i <= 100; i++) { // 3行目-100行目までを繰り返し処理 - どこからどこまで処理するかは必ず記述すること }
メール本文で使用する値の定義を設定
メール本文で使用する値の定義を設定します。
var 値 = Sheet.getRange(i, ステップ2で設定した変数).getValue();
/* 仕入予定日 */ var sippingDate = Sheet.getRange(i, SHIPPING_DATE).getValue(); /* 注文内容 */ var orderDate = Sheet.getRange(i, ORDER_DATE).getValue(); // 発注日 var orderNumber = Sheet.getRange(i, ORDER_NUMBER).getValue(); // 注文番号 var invoiceNumber = Sheet.getRange(i, INVOICE_NUMBER).getValue(); // 請求書番号 var modelNumber = Sheet.getRange(i, MODEL_NUMBER).getValue(); // 製品型番 var use = Sheet.getRange(i, USE).getValue(); // 用途 var category = Sheet.getRange(i, CATEGORY).getValue(); // カテゴリ var piece = Sheet.getRange(i, PIECE).getValue(); // 発注数 var price = Sheet.getRange(i, PRICE).getValue(); // 合計金額 var shippingDate = Sheet.getRange(i, SHIPPING_DATE).getValue(); // 仕入予定日 var orderer = Sheet.getRange(i, ORDERER).getValue(); // 購入者 /* 状態 */ var status = Sheet.getRange(i, STATUS).getValue(); // 状態 var shippingNumber = Sheet.getRange(i, SHIPPING_NUMBER).getValue(); // 追跡番号 var shippingUrl = Sheet.getRange(i, SHIPPING_URL).getValue(); // 追跡番号URL /* 購入場所 */ var shop = Sheet.getRange(i, SHOP).getValue(); // 発注先
仕入予定日までの日数を計算し、日付を成形
floor関数で日数・日付を切り捨て計算(※切り捨て計算にしないと日数の計算に誤差が生じる可能性があるので注意)
/* 仕入予定日までの日数を計算し日付に変換 */ var date_shippingDate = Math.floor((new Date(sippingDate)).getTime() / 1000 / 60 / 60 / 24); // 「仕入予定日」のDateを作成, 日付に切り捨て var dt = Math.floor(today.getTime() / 1000 / 60 / 60 / 24); // 今日の日付 var day = date_shippingDate - dt; // 日付の差に変換
メール本文の日付の表示形式を設定
ステップ3で設定した const options の日付表示形式(YYYY年MM月DD日(曜日))を「orderDate」と「shippingDate」に適用します。
const options の日付表示形式を適用することで、メール本文の「発注日(orderDate)」と「仕入予定日(shippingDate)」が「YYYY年MM月DD日(曜日)」形式で表記されます。
/* 取得した日付を設定した表示内容・日本時間に成形する */ orderDate = orderDate.toLocaleString('ja-JP', options); // 発注日を日本時間表示 shippingDate = shippingDate.toLocaleString('ja-JP', options); // 仕入予定日を日本時間表示
ステップ5
メールを送る条件を指定 - 1
if (shippingDate == '' || status == '仕入済み' || status == 'キャンセル') { /* ステータスが「仕入済み」か「キャンセル」、もしくは仕入予定日が空白なら何もしない */ continue; }
共通するメール本文の内容を設定
今回は、仕入予定日の「7日前・1日前」「当日」「予定日を3日過ぎた時」の3タイプに分けて、メール本文を設定します。
メール3タイプの内、共通している本文内容の部分は、以下のようにあらかじめ設定しておきます。
var mailBody = '\n' /* 改行 */ + '発注日:' + orderDate + '\n' /* 改行 */ + '発注先:' + shop + '\n' /* 改行 */ + '仕入予定日:' + shippingDate + '\n' /* 改行 */ + 'ステータス:' + status + '\n' /* 改行 */ + '購入者:' + orderer + '\n' /* 改行 */ + '追跡番号:' + shippingNumber + '\n' /* 改行 */ + '追跡番号URL:' + shippingUrl + '\n' /* 改行 */ + '\n' /* 改行 */ + '\n' /* 改行 */ + '【注文内容】\n' /* 改行 */ + '注文番号:' + orderNumber + '\n' /* 改行 */ + '請求書番号:' + invoiceNumber + '\n' /* 改行 */ + '注文製品型番:' + modelNumber + '\n' /* 改行 */ + '注文製品カテゴリ:' + category + '\n' /* 改行 */ + '使用用途:' + use + '\n' /* 改行 */ + '\n' /* 改行 */ + '購入数:' + piece + '点\n' /* 改行 */ + '合計金額:' + price + '円(税込)\n';
メールを送る条件を指定 - 2
var strSubject = ''; // strSubjectの初期設定は「空白」とする var strBody = ''; // strBodyの初期設定は「空白」とする // メール本文 if (strSubject !== '') { // strSubjectが「空白でない」場合はメールを送信 /* メールを送信 */ GmailApp.sendEmail( strTo, strSubject, strBody, { from: strFrom, name: strSender } ); }
3タイプのメール本文を設定
if (day === 7 || day === 1) { // 仕入予定日の7日前 or 1日前 /* メール本文を準備 */ strSubject = '【仕入予定日のお知らせ】' + orderer + '様ご注文製品の仕入予定日まであと' + day + '日です'; strBody = '仕入予定日まであと' + day + '日です。\n' /* 改行 */ + modelNumber + 'の仕入予定日が近付いてきたのでお知らせします。\n' /* 改行 */ + mailBody; } else if (day === 0) { // 仕入予定日の当日 /* メール本文を準備 */ strSubject = '【仕入予定日のお知らせ】' + orderer + '様ご注文製品の仕入予定日当日です'; strBody = '仕入予定日当日になりました。\n' /* 改行 */ + modelNumber + 'が無事発送されたか確認してください。\n' /* 改行 */ + mailBody; } else if (day === -3) { // 仕入予定日を過ぎた後 /* メール本文を準備 */ strSubject = '【仕入予定日のお知らせ】' + orderer + '様ご注文製品の仕入予定日を過ぎました'; strBody = '仕入予定日を過ぎました。\n' /* 改行 */ + modelNumber + 'が無事発送されたか確認してください。\n' /* 改行 */ + '発送されていない場合は仕入予定日を確認し、必要があれば、仕入予定日を変更・更新してください。\n' /* 改行 */ + mailBody; }
サンプルコード全文
コピー・アンド・ペーストしてご使用いただけます。
function mailSend() { var mySs = SpreadsheetApp.getActiveSpreadsheet(); // スプレッドシートを取得 var Sheet = mySs.getSheetByName('シート名を記入'); // シート名を取得 /* 繰り返し計算式の変数を定義 */ /* const 変数 = 数字(左から何列目なのかを記述 - C列なら「3」と記述); */ const ORDER_DATE = 1; // A列 「発注日」を取得 const ORDER_NUMBER = 2; // B列 「注文番号」を取得 const INVOICE_NUMBER = 3; // C列 「請求書番号」を取得 const SHIPPING_DATE = 4; // D列「仕入予定日」を取得 const STATUS = 5; // E列 「状態」を取得 const SHIPPING_NUMBER = 6; // F列「追跡番号」を取得 const SHIPPING_URL = 7; // G列「追跡番号URL」を取得 const ORDERER = 9; // I列「購入者」を取得 const MODEL_NUMBER = 11; // K列 「製品型番」を取得 const USE = 12; // L列 「用途」を取得 const CATEGORY = 15; // O列 「カテゴリ」を取得 const SHOP = 16; // P列 「発注先」を取得 const PIECE = 17; // Q列 「発注数」を取得 const PRICE = 19; // S列 「合計金額」を取得 /* 今日の日付を取得し文字列を成形する */ new Date().toLocaleString({ timeZone: 'Asia/Tokyo' }); const tmp_today = new Date(); // 今日の日付を取得 const yy = tmp_today.getFullYear(); const mm = tmp_today.getMonth(); const dd = tmp_today.getDate(); const today = new Date(yy, mm, dd); const options = { weekday: 'short', year: 'numeric', month: 'long', day: 'numeric', timeZone: 'Asia/Tokyo' }; /* リマインダー送信アドレス設定 */ var strTo = ; strTo.push('送信先メールアドレス'); // To var strSender = '差出人名'; // 差出人名 var strFrom = 'Google App Script編集時にログインしているGmailアドレス'; // From 今ログインしているGmailアドレス /* 繰り返し計算 */ const lastRow = Sheet.getLastRow(); // データが含まれている最終行を自動取得 for(let i = 3; i <= lastRow; i++) { // 3行目からデータが含まれている最終行までを繰り返し処理 /* 仕入予定日 */ var sippingDate = Sheet.getRange(i, SHIPPING_DATE).getValue(); /* 注文内容 */ var orderDate = Sheet.getRange(i, ORDER_DATE).getValue(); // 発注日 var orderNumber = Sheet.getRange(i, ORDER_NUMBER).getValue(); // 注文番号 var invoiceNumber = Sheet.getRange(i, INVOICE_NUMBER).getValue(); // 請求書番号 var modelNumber = Sheet.getRange(i, MODEL_NUMBER).getValue(); // 製品型番 var use = Sheet.getRange(i, USE).getValue(); // 用途 var category = Sheet.getRange(i, CATEGORY).getValue(); // カテゴリ var piece = Sheet.getRange(i, PIECE).getValue(); // 発注数 var price = Sheet.getRange(i, PRICE).getValue(); // 合計金額 var shippingDate = Sheet.getRange(i, SHIPPING_DATE).getValue(); // 仕入予定日 var orderer = Sheet.getRange(i, ORDERER).getValue(); // 購入者 /* 状態 */ var status = Sheet.getRange(i, STATUS).getValue(); // 状態 var shippingNumber = Sheet.getRange(i, SHIPPING_NUMBER).getValue(); // 追跡番号 var shippingUrl = Sheet.getRange(i, SHIPPING_URL).getValue(); // 追跡番号URL /* 購入場所 */ var shop = Sheet.getRange(i, SHOP).getValue(); // 発注先 /* 仕入予定日までの日数を計算し日付に変換 */ var date_shippingDate = Math.floor((new Date(sippingDate)).getTime() / 1000 / 60 / 60 / 24); // 「仕入予定日」のDateを作成, 日付に切り捨て var dt = Math.floor(today.getTime() / 1000 / 60 / 60 / 24); // 今日の日付 var day = date_shippingDate - dt; // 日付の差に変換 /* 取得した日付を設定した表示内容・日本時間に成形する */ orderDate = orderDate.toLocaleString('ja-JP', options); // 発注日を日本時間表示 shippingDate = shippingDate.toLocaleString('ja-JP', options); // 仕入予定日を日本時間表示 if (shippingDate == '' || status == '仕入済み' || status == 'キャンセル') { /* ステータスが「仕入済み」か「キャンセル」、もしくは仕入予定日が空白なら何もしない */ continue; } var mailBody = '\n' /* 改行 */ + '発注日:' + orderDate + '\n' /* 改行 */ + '発注先:' + shop + '\n' /* 改行 */ + '仕入予定日:' + shippingDate + '\n' /* 改行 */ + 'ステータス:' + status + '\n' /* 改行 */ + '購入者:' + orderer + '\n' /* 改行 */ + '追跡番号:' + shippingNumber + '\n' /* 改行 */ + '追跡番号URL:' + shippingUrl + '\n' /* 改行 */ + '\n' /* 改行 */ + '\n' /* 改行 */ + '【注文内容】\n' /* 改行 */ + '注文番号:' + orderNumber + '\n' /* 改行 */ + '請求書番号:' + invoiceNumber + '\n' /* 改行 */ + '注文製品型番:' + modelNumber + '\n' /* 改行 */ + '注文製品カテゴリ:' + category + '\n' /* 改行 */ + '使用用途:' + use + '\n' /* 改行 */ + '\n' /* 改行 */ + '購入数:' + piece + '点\n' /* 改行 */ + '合計金額:' + price + '円(税込)\n' /* 改行 */ + '\n' /* 改行 */ + '\n' /* 改行 */ + 'Googleスプレッドシート「スプレッドシートA」を見る:\n' /* 改行 */ + '該当のGoogleスプレッドシートURL'; var strSubject = ''; // strSubjectの初期設定は「空白」とする var strBody = ''; // strBodyの初期設定は「空白」とする if (day === 7 || day === 1) { // 仕入予定日の7日前 or 1日前 /* メール本文を準備 */ strSubject = '【仕入予定日のお知らせ】' + orderer + '様ご注文製品の仕入予定日まであと' + day + '日です'; strBody = '仕入予定日まであと' + day + '日です。\n' /* 改行 */ + modelNumber + 'の仕入予定日が近付いてきたのでお知らせします。\n' /* 改行 */ + mailBody; } else if (day === 0) { // 仕入予定日の当日 /* メール本文を準備 */ strSubject = '【仕入予定日のお知らせ】' + orderer + '様ご注文製品の仕入予定日当日です'; strBody = '仕入予定日当日になりました。\n' /* 改行 */ + modelNumber + 'が無事発送されたか確認してください。\n' /* 改行 */ + mailBody; } else if (day === -3) { // 仕入予定日を過ぎた後 /* メール本文を準備 */ strSubject = '【仕入予定日のお知らせ】' + orderer + '様ご注文製品の仕入予定日を過ぎました'; strBody = '仕入予定日を過ぎました。\n' /* 改行 */ + modelNumber + 'が無事発送されたか確認してください。\n' /* 改行 */ + '発送されていない場合は仕入予定日を確認し、必要があれば、仕入予定日を変更・更新してください。\n' /* 改行 */ + mailBody; } if (strSubject !== '') { // strSubjectが「空白でない」場合はメールを送信 /* メールを送信 */ GmailApp.sendEmail( strTo, strSubject, strBody, { from: strFrom, name: strSender } ); } } }
杉岡システム株式会社
住所
〒573-0046
大阪府枚方市宮之下町8番2号(ABCセンター 西棟3階)
営業時間
平日10:00 - 17:30(土日祝休み)
連絡先
TEL
072-853-3553(平日10:00 - 17:30)
FAX
072-853-3577(平日10:00 - 17:30)
support@sugiokasystem.co.jp
WEBからのお問い合わせ
※営業時間外の場合、翌営業日以降に対応いたします。