いつものGoogleで、 仕事が自動で動き出す。
難しいシステムの導入は不要です。 スプレッドシート・Googleフォーム・Gmailなど、すでに使っているGoogleツールに コードを貼り付けるだけで、面倒な作業が自動化されます。 工務店・建設業に特化した実務直結の自動化コード10種を無料公開します。 低コストで始めやすく、アフターや顧客対応の抜け漏れ防止にもつながります。
Google Apps Scriptとは?
一言で言うと: Googleスプレッドシートに「自動で動く指示」を書き込めるツールです。 費用は完全無料。必要なものはGoogleアカウントだけ。コードはコピペするだけでOKです。
費用
完全無料
設定時間
約10〜30分
必要なもの
Googleアカウントのみ
例えるなら、毎朝手動でやっている作業をGoogleが代わりにやってくれる仕組みです。 「お問い合わせが来たら自動でメールを送る」「1年後になったら担当者に通知する」といった 繰り返し作業をすべて自動化できます。 AIで文章を整え、GASで動かす組み合わせも相性抜群です。
基本的な使い方(3ステップ)
- 1 Googleスプレッドシートを開き、メニューから「拡張機能」→「Apps Script」をクリック
- 2 下記のコードをコピーして、エディタ画面に貼り付けて保存(💾アイコン)
- 3 「トリガー」を設定して自動実行のタイミングを決める(時間・フォーム送信時など)
こんなこと、ありませんか?
お問い合わせへの返信が翌日になってしまう
引き渡しから1年後の点検連絡を忘れてしまう
職人の日報をExcelに手打ちで集計している
見積書をPDFにしてメール送信する作業が手間
現場ごとの写真がドライブでバラバラになっている
月末の経費・領収書整理に半日かかっている
これらはすべて、GASで自動化できます
GAS-001. お問い合わせ自動お礼メール
なぜ必要か 問い合わせへの返信が翌日になるだけで、お客様は別の会社に問い合わせます。このスクリプトを設定すれば、フォーム送信と同時に自動でお礼メールが届き、「すぐに反応してくれる会社」という第一印象を与えられます。
カスタマイズ箇所(★マークの部分を変更)
- ・COMPANY_NAME:自社の会社名
- ・SENDER_NAME:担当者名
- ・REPLY_EMAIL:返信先のメールアドレス
// ★ここを自社情報に変更してください
const COMPANY_NAME = '株式会社〇〇工務店';
const SENDER_NAME = '担当者名';
const REPLY_EMAIL = 'buildmate88@gmail.com';
function sendThankYouMail() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
// 最新の問い合わせを取得(A列:タイムスタンプ、B列:名前、C列:メール)
const name = sheet.getRange(lastRow, 2).getValue();
const email = sheet.getRange(lastRow, 3).getValue();
if (!email) return; // メールアドレスがなければ終了
const subject = `【${COMPANY_NAME}】お問い合わせありがとうございます`;
const body = `${name} 様
この度は${COMPANY_NAME}へのお問い合わせありがとうございます。
担当の${SENDER_NAME}より、2営業日以内にご連絡差し上げます。
しばらくお待ちくださいますようお願いいたします。
━━━━━━━━━━━━━━━━━━━━━━
${COMPANY_NAME}
担当:${SENDER_NAME}
メール:${REPLY_EMAIL}
━━━━━━━━━━━━━━━━━━━━━━`;
GmailApp.sendEmail(email, subject, body, {
replyTo: REPLY_EMAIL,
name: COMPANY_NAME
});
// 送信済みフラグをD列に記録
sheet.getRange(lastRow, 4).setValue('送信済み');
}
// トリガー設定:フォーム送信時にこの関数を実行してください
GAS-002. OB顧客1年点検リマインダー
なぜ必要か 引き渡しから1年後・3年後・5年後の点検連絡を忘れることは「売りっぱなし」の典型例です。スプレッドシートに引き渡し日を入力しておくだけで、担当者のGmailに自動通知が届きます。紹介受注の基盤を自動でつくります。
スプレッドシートの列構成
- ・A列:顧客名 B列:引き渡し日(例:2024/04/01) C列:担当者メール
// ★ここを自社情報に変更してください
const COMPANY_NAME_002 = '株式会社〇〇工務店';
// 通知するタイミング(引き渡しから何年後か)
const REMIND_YEARS = [1, 3, 5];
// 何日前から通知するか
const DAYS_BEFORE = 7;
function checkObReminders() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const today = new Date();
for (let i = 2; i <= lastRow; i++) {
const customerName = sheet.getRange(i, 1).getValue();
const deliveryDate = new Date(sheet.getRange(i, 2).getValue());
const staffEmail = sheet.getRange(i, 3).getValue();
if (!customerName || !deliveryDate || !staffEmail) continue;
for (const year of REMIND_YEARS) {
const targetDate = new Date(deliveryDate);
targetDate.setFullYear(targetDate.getFullYear() + year);
// 対象日の7日前〜当日に通知
const diffDays = Math.floor((targetDate - today) / (1000 * 60 * 60 * 24));
if (diffDays >= 0 && diffDays <= DAYS_BEFORE) {
const subject = `【${COMPANY_NAME_002}】${customerName}様 引き渡し${year}年点検のご連絡時期です`;
const body = `${customerName}様の引き渡しから${year}年が経過します(${targetDate.toLocaleDateString('ja-JP')})。
点検・フォローのご連絡をお忘れなく。
顧客情報をスプレッドシートで確認してください。`;
GmailApp.sendEmail(staffEmail, subject, body);
}
}
}
}
// トリガー設定:毎日午前8時に実行するよう設定してください
GAS-003. 職人日報フォーム→自動集計・週次レポート
なぜ必要か 職人がGoogleフォームで日報を入力するだけで、スプレッドシートに自動集計され、毎週月曜の朝に週次レポートが届きます。夜中に日報を手打ちする作業がなくなり、現場監督の残業時間が削減されます。
// ★ここを自社情報に変更してください
const MANAGER_EMAIL = 'buildmate88@gmail.com';
const COMPANY_NAME_003 = '株式会社〇〇工務店';
function sendWeeklyReport() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
// 今週の月曜日を取得
const today = new Date();
const monday = new Date(today);
monday.setDate(today.getDate() - today.getDay() + 1);
monday.setHours(0, 0, 0, 0);
let reportBody = `${COMPANY_NAME_003} 週次作業レポート\n`;
reportBody += `対象期間:${monday.toLocaleDateString('ja-JP')} 〜 ${today.toLocaleDateString('ja-JP')}\n`;
reportBody += `━━━━━━━━━━━━━━━━━━━━━━\n\n`;
let count = 0;
for (let i = 2; i <= lastRow; i++) {
const timestamp = new Date(sheet.getRange(i, 1).getValue());
if (timestamp >= monday) {
const worker = sheet.getRange(i, 2).getValue(); // 職人名
const site = sheet.getRange(i, 3).getValue(); // 現場名
const work = sheet.getRange(i, 4).getValue(); // 作業内容
const progress = sheet.getRange(i, 5).getValue(); // 進捗状況
reportBody += `【${timestamp.toLocaleDateString('ja-JP')}】\n`;
reportBody += `担当:${worker} / 現場:${site}\n`;
reportBody += `作業内容:${work}\n`;
reportBody += `進捗:${progress}\n\n`;
count++;
}
}
reportBody += `━━━━━━━━━━━━━━━━━━━━━━\n`;
reportBody += `今週の日報件数:${count}件`;
GmailApp.sendEmail(
MANAGER_EMAIL,
`【${COMPANY_NAME_003}】週次作業レポート`,
reportBody
);
}
// トリガー設定:毎週月曜日の午前8時に実行してください
GAS-004. 見積書PDF自動生成・メール送信
なぜ必要か スプレッドシートで作った見積書をボタン1つでPDF化してお客様にメール送信します。製本・郵送の手間と印刷コストをゼロにできます。
// ★ここを自社情報に変更してください
const COMPANY_NAME_004 = '株式会社〇〇工務店';
const SENDER_EMAIL_004 = 'buildmate88@gmail.com';
const SENDER_NAME_004 = '担当者名';
function sendEstimatePdf() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
// ★スプレッドシートのセル位置に合わせて変更してください
const customerName = sheet.getRange('B2').getValue(); // 顧客名
const customerEmail = sheet.getRange('B3').getValue(); // 顧客メール
const estimateNo = sheet.getRange('B4').getValue(); // 見積番号
const totalAmount = sheet.getRange('B20').getValue(); // 合計金額
if (!customerEmail) {
SpreadsheetApp.getUi().alert('顧客のメールアドレスを入力してください。');
return;
}
// スプレッドシート全体をPDF化
const url = `https://docs.google.com/spreadsheets/d/${ss.getId()}/export?format=pdf&size=A4&portrait=true&fitw=true`;
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(url, {
headers: { Authorization: `Bearer ${token}` }
});
const pdfBlob = response.getBlob().setName(`見積書_${estimateNo}.pdf`);
const subject = `【${COMPANY_NAME_004}】見積書のご送付(見積番号:${estimateNo})`;
const body = `${customerName} 様
お世話になっております。
${COMPANY_NAME_004}の${SENDER_NAME_004}です。
ご依頼いただきました件について、見積書をお送りいたします。
添付PDFをご確認ください。
ご不明な点がございましたら、お気軽にご連絡ください。
━━━━━━━━━━━━━━━━━━━━━━
${COMPANY_NAME_004}
担当:${SENDER_NAME_004}
メール:${SENDER_EMAIL_004}
━━━━━━━━━━━━━━━━━━━━━━`;
GmailApp.sendEmail(customerEmail, subject, body, {
attachments: [pdfBlob],
name: COMPANY_NAME_004,
replyTo: SENDER_EMAIL_004
});
SpreadsheetApp.getUi().alert(`${customerName}様にPDFを送信しました。`);
}
// スプレッドシートにボタンを作り、このスクリプトを割り当ててください
GAS-005. 現場写真の自動フォルダ振り分け
なぜ必要か Googleドライブの指定フォルダに写真をアップするだけで、現場名・日付ごとのフォルダに自動整理されます。「あの写真どこだっけ?」という時間の無駄をなくします。
// ★ここを変更してください
// 写真をアップするメインフォルダのID(DriveのURLの/folders/の後の部分)
const SOURCE_FOLDER_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// 整理済みフォルダのID
const ARCHIVE_FOLDER_ID = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';
function organizePhotos() {
const sourceFolder = DriveApp.getFolderById(SOURCE_FOLDER_ID);
const archiveFolder = DriveApp.getFolderById(ARCHIVE_FOLDER_ID);
const files = sourceFolder.getFiles();
while (files.hasNext()) {
const file = files.next();
const fileName = file.getName();
const createdDate = file.getDateCreated();
// 日付フォルダ名を作成(例:2026-04-07)
const dateStr = Utilities.formatDate(createdDate, 'Asia/Tokyo', 'yyyy-MM-dd');
// ファイル名から現場名を取得(ファイル名の先頭に「現場名_」を付けるルール)
// 例:「〇〇邸_外壁.jpg」→「〇〇邸」フォルダに振り分け
const siteName = fileName.includes('_') ? fileName.split('_')[0] : '未分類';
// 現場名フォルダを作成または取得
let siteFolder;
const siteFolders = archiveFolder.getFoldersByName(siteName);
if (siteFolders.hasNext()) {
siteFolder = siteFolders.next();
} else {
siteFolder = archiveFolder.createFolder(siteName);
}
// 日付フォルダを作成または取得
let dateFolder;
const dateFolders = siteFolder.getFoldersByName(dateStr);
if (dateFolders.hasNext()) {
dateFolder = dateFolders.next();
} else {
dateFolder = siteFolder.createFolder(dateStr);
}
// ファイルを移動
file.moveTo(dateFolder);
}
Logger.log('写真の整理が完了しました');
}
// トリガー設定:毎日深夜に実行するよう設定してください
GAS-006. 協力業者への発注連絡自動化
なぜ必要か スプレッドシートに発注内容を入力してボタンを押すだけで、協力業者に自動でメール送信されます。FAXとの決別、「言った言わない」の解消につながります。
// ★ここを自社情報に変更してください
const COMPANY_NAME_006 = '株式会社〇〇工務店';
const SENDER_EMAIL_006 = 'buildmate88@gmail.com';
function sendOrderEmail() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// ★スプレッドシートのセル位置に合わせて変更してください
const vendorName = sheet.getRange('B2').getValue(); // 業者名
const vendorEmail = sheet.getRange('B3').getValue(); // 業者メール
const siteName = sheet.getRange('B4').getValue(); // 現場名
const workDate = sheet.getRange('B5').getValue(); // 作業日
const workContent = sheet.getRange('B6').getValue(); // 作業内容
const workers = sheet.getRange('B7').getValue(); // 人数
const notes = sheet.getRange('B8').getValue(); // 備考
if (!vendorEmail) {
SpreadsheetApp.getUi().alert('業者のメールアドレスを入力してください。');
return;
}
const dateStr = workDate instanceof Date
? Utilities.formatDate(workDate, 'Asia/Tokyo', 'yyyy年MM月dd日')
: workDate;
const subject = `【${COMPANY_NAME_006}】作業依頼:${siteName}`;
const body = `${vendorName} 御中
お世話になっております。
${COMPANY_NAME_006}です。
下記の通り作業をご依頼申し上げます。
【現場名】${siteName}
【作業日】${dateStr}
【作業内容】${workContent}
【人数】${workers}名
【備考】${notes || 'なし'}
ご確認の上、ご返信をお願いいたします。
━━━━━━━━━━━━━━━━━━━━━━
${COMPANY_NAME_006}
メール:${SENDER_EMAIL_006}
━━━━━━━━━━━━━━━━━━━━━━`;
GmailApp.sendEmail(vendorEmail, subject, body, {
name: COMPANY_NAME_006,
replyTo: SENDER_EMAIL_006
});
// 送信履歴を記録
sheet.getRange('B9').setValue(`送信済み:${new Date().toLocaleString('ja-JP')}`);
SpreadsheetApp.getUi().alert(`${vendorName}様に発注メールを送信しました。`);
}
// スプレッドシートにボタンを作り、このスクリプトを割り当ててください
GAS-007. 工事完了アンケート自動送付
なぜ必要か 引き渡しから3日後に満足度アンケートを自動送付します。口コミ・紹介の仕組み化と、改善点の早期発見につながります。
// ★ここを自社情報に変更してください
const COMPANY_NAME_007 = '株式会社〇〇工務店';
const SENDER_EMAIL_007 = 'buildmate88@gmail.com';
// ★GoogleフォームのURL(アンケートフォームを作成して貼り付けてください)
const SURVEY_URL = 'https://forms.gle/xxxxxxxxxxxx';
// 引き渡し後何日後に送付するか
const DAYS_AFTER_DELIVERY = 3;
function sendSurveyEmail() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const today = new Date();
today.setHours(0, 0, 0, 0);
for (let i = 2; i <= lastRow; i++) {
const customerName = sheet.getRange(i, 1).getValue();
const customerEmail = sheet.getRange(i, 2).getValue();
const deliveryDate = new Date(sheet.getRange(i, 3).getValue());
const surveySent = sheet.getRange(i, 4).getValue();
if (!customerName || !customerEmail || surveySent === '送信済み') continue;
deliveryDate.setHours(0, 0, 0, 0);
const diffDays = Math.floor((today - deliveryDate) / (1000 * 60 * 60 * 24));
if (diffDays === DAYS_AFTER_DELIVERY) {
const subject = `【${COMPANY_NAME_007}】新居のご感想をお聞かせください`;
const body = `${customerName} 様
先日はご引き渡しおめでとうございます。
${COMPANY_NAME_007}でございます。
新居での生活はいかがでしょうか?
よりよいサービスのため、ご感想をお聞かせいただけますと幸いです。
▼アンケートはこちら(所要時間:約3分)
${SURVEY_URL}
今後ともどうぞよろしくお願いいたします。
━━━━━━━━━━━━━━━━━━━━━━
${COMPANY_NAME_007}
メール:${SENDER_EMAIL_007}
━━━━━━━━━━━━━━━━━━━━━━`;
GmailApp.sendEmail(customerEmail, subject, body);
sheet.getRange(i, 4).setValue('送信済み');
}
}
}
// トリガー設定:毎日午前9時に実行してください
GAS-008. 補助金申請期限アラート
なぜ必要か 補助金の締め切りを見逃すと、数百万円の機会損失になります。スプレッドシートに補助金情報を登録しておくと、1ヶ月前・1週間前に自動アラートが届きます。
// ★ここを変更してください
const ALERT_EMAIL = 'buildmate88@gmail.com';
const COMPANY_NAME_008 = '株式会社〇〇工務店';
// 何日前にアラートを送るか(複数設定可能)
const ALERT_DAYS = [30, 14, 7, 3, 1];
function checkSubsidyDeadlines() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const today = new Date();
today.setHours(0, 0, 0, 0);
for (let i = 2; i <= lastRow; i++) {
const subsidyName = sheet.getRange(i, 1).getValue(); // 補助金名
const deadline = new Date(sheet.getRange(i, 2).getValue()); // 締め切り日
const maxAmount = sheet.getRange(i, 3).getValue(); // 最大補助額
const status = sheet.getRange(i, 4).getValue(); // ステータス
if (!subsidyName || status === '申請済み' || status === '終了') continue;
deadline.setHours(0, 0, 0, 0);
const diffDays = Math.floor((deadline - today) / (1000 * 60 * 60 * 24));
if (ALERT_DAYS.includes(diffDays)) {
const subject = `【重要】${subsidyName} 締め切りまであと${diffDays}日`;
const body = `${COMPANY_NAME_008} 御中
補助金の申請期限が迫っています。
【補助金名】${subsidyName}
【締め切り日】${Utilities.formatDate(deadline, 'Asia/Tokyo', 'yyyy年MM月dd日')}
【残り日数】あと${diffDays}日
【最大補助額】${maxAmount}
早めの対応をお願いします。
スプレッドシートで詳細を確認してください。`;
GmailApp.sendEmail(ALERT_EMAIL, subject, body);
}
}
}
// スプレッドシートのA列:補助金名、B列:締め切り日、C列:最大補助額、D列:ステータス
// トリガー設定:毎日午前8時に実行してください
GAS-009. 月次売上レポート自動生成
なぜ必要か 受注データを入力するだけで、月末に売上・粗利・件数をまとめたレポートをGmailで受信します。経営判断に必要な数字を自動で可視化します。
// ★ここを変更してください
const REPORT_EMAIL = 'buildmate88@gmail.com';
const COMPANY_NAME_009 = '株式会社〇〇工務店';
function sendMonthlyReport() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const today = new Date();
const thisMonth = today.getMonth();
const thisYear = today.getFullYear();
let totalSales = 0; // 売上合計
let totalCost = 0; // 原価合計
let orderCount = 0; // 件数
let orderDetails = ''; // 明細
for (let i = 2; i <= lastRow; i++) {
const orderDate = new Date(sheet.getRange(i, 1).getValue());
if (orderDate.getMonth() !== thisMonth || orderDate.getFullYear() !== thisYear) continue;
const projectName = sheet.getRange(i, 2).getValue(); // 工事名
const sales = Number(sheet.getRange(i, 3).getValue()); // 売上
const cost = Number(sheet.getRange(i, 4).getValue()); // 原価
totalSales += sales;
totalCost += cost;
orderCount++;
const grossProfit = sales - cost;
const margin = sales > 0 ? Math.round((grossProfit / sales) * 100) : 0;
orderDetails += `・${projectName}:¥${sales.toLocaleString()} (粗利率${margin}%)\n`;
}
const grossProfit = totalSales - totalCost;
const grossMargin = totalSales > 0 ? Math.round((grossProfit / totalSales) * 100) : 0;
const monthStr = `${thisYear}年${thisMonth + 1}月`;
const subject = `【${COMPANY_NAME_009}】${monthStr}度 月次売上レポート`;
const body = `${monthStr}度 月次レポート
━━━━━━━━━━━━━━━━━━━━━━
■ サマリー
受注件数:${orderCount}件
売上合計:¥${totalSales.toLocaleString()}
原価合計:¥${totalCost.toLocaleString()}
粗利合計:¥${grossProfit.toLocaleString()}
粗利率 :${grossMargin}%
━━━━━━━━━━━━━━━━━━━━━━
■ 受注明細
${orderDetails || 'データなし'}
━━━━━━━━━━━━━━━━━━━━━━
${COMPANY_NAME_009} 自動レポート`;
GmailApp.sendEmail(REPORT_EMAIL, subject, body);
}
// トリガー設定:毎月1日の午前8時に実行してください(前月分が集計されます)
GAS-010. ヒヤリハット自動集計・安全週報
なぜ必要か Googleフォームで報告されたヒヤリハットをGASが自動集計し、毎週安全管理担当者に週報を送信します。報告のしやすい仕組みが事故ゼロへの第一歩です。
// ★ここを変更してください
const SAFETY_EMAIL = 'buildmate88@gmail.com';
const COMPANY_NAME_010 = '株式会社〇〇工務店';
function sendSafetyWeeklyReport() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const today = new Date();
const monday = new Date(today);
monday.setDate(today.getDate() - today.getDay() + 1);
monday.setHours(0, 0, 0, 0);
// カテゴリ別集計
const categories = {};
let totalCount = 0;
let reportDetails = '';
for (let i = 2; i <= lastRow; i++) {
const reportDate = new Date(sheet.getRange(i, 1).getValue());
if (reportDate < monday) continue;
const site = sheet.getRange(i, 2).getValue(); // 現場名
const category = sheet.getRange(i, 3).getValue(); // カテゴリ(転倒・落下など)
const description = sheet.getRange(i, 4).getValue(); // 状況
const action = sheet.getRange(i, 5).getValue(); // 対処内容
categories[category] = (categories[category] || 0) + 1;
totalCount++;
reportDetails += `【${site}】${category}\n`;
reportDetails += `状況:${description}\n`;
reportDetails += `対処:${action}\n\n`;
}
// カテゴリ別集計テキスト
let categoryText = '';
for (const [cat, count] of Object.entries(categories)) {
categoryText += `・${cat}:${count}件\n`;
}
const subject = `【${COMPANY_NAME_010}】今週のヒヤリハット週報(${totalCount}件)`;
const body = `${COMPANY_NAME_010} 安全管理担当者 様
今週のヒヤリハット週報をお送りします。
━━━━━━━━━━━━━━━━━━━━━━
■ 今週の集計
報告件数:${totalCount}件
■ カテゴリ別
${categoryText || '報告なし'}
━━━━━━━━━━━━━━━━━━━━━━
■ 詳細レポート
${reportDetails || '今週の報告はありませんでした。'}
━━━━━━━━━━━━━━━━━━━━━━
${COMPANY_NAME_010} 自動安全週報`;
GmailApp.sendEmail(SAFETY_EMAIL, subject, body);
}
// トリガー設定:毎週金曜日の午後5時に実行してください
「自社に合わせてカスタマイズしたい」 そんな時はご相談ください。
コードのカスタマイズ・トリガーの設定・スプレッドシートの構築まで、 元・施工管理の代表が工務店の現場に合わせてサポートします。
無料相談する