質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

2回答

614閲覧

シートの更新に沿ってメール自動送信

shiyuh

総合スコア21

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2022/10/06 20:00

スプレッドシートのシートの内容が更新されたら
その内容を指定のメールアドレスにそれぞれ送るというシステムを作りたいです。

以下のサイトを参考にし、とりあえずやりたいことは実現したのですが、
シートが更新されたら上から順に全ての行に対して都度実行されてしまうので、
新しく更新された行にだけメールの送信がかかるように変えたいです。

ご教示くださいませ。

参考サイト↓
https://tonari-it.com/gas-mail-magazine/

使用中のコード↓

function sendMail(){ const sheet = SpreadsheetApp.getActiveSheet(); const lastRow = sheet.getLastRow();; const DOC_URL = '*****ドキュメントのURL*****'; const doc = DocumentApp.openByUrl(DOC_URL); const docText = doc.getBody().getText(); const subject = 'メルマガ送信テスト'; const options = {name: 'いつも隣にITのお仕事'}; for(let i = 2; i <= lastRow; i++){ const company = sheet.getRange(i, 1).getValue(); const lastName = sheet.getRange(i, 2).getValue(); //姓 const firstName = sheet.getRange(i, 3).getValue(); //名 const recipient = sheet.getRange(i, 4).getValue(); const body = docText .replace('{社名}',company) .replace('{姓}',lastName) .replace('{名}',firstName); GmailApp.sendEmail(recipient, subject, body, options); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

「新しく追加した行のみ」ではなく、 「チェックボックスで選択した行のみ」 にメール送信するようにしてみました。

というのも今後の実務を考えた時に、例えば、

  • 一人のお客様からメールを再送してと頼まれた時、「新しく追加した行に送信」だと、同じ宛先を最終行にかかなければならないのか?
  • 宛先を追加したもののその時は送信せず、別の機会にさらに追加して、前回追加した分と一緒に送りたいときはどうするのか?

など疑問点がでてきたからです。

画面の様子

  • 「全て選択」ボタンで、全ての宛先に一括でチェックをいれられるようにしました。
    • もちろん1つずつチェックいれはずしもできます!
  • 「選択をリセット」ボタンで、全ての宛先のチェックを外すようにしました。
  • 「メールを送信する」ボタンで、
    • メールを送信しますか?の確認画面で「OK」を押したら、
    • メールが送信されるようにしました。

↓表の1行目を固定化しているので、スクロールしても各項目名とボタンはずっと1行目に見えています。
イメージ説明
イメージ説明 イメージ説明

コード例

javascript

1/* 2 * メールを送信する関数 3 */ 4function sendMail() { 5 // メール送信確認のメッセージボックスを画面に表示 6 const response = Browser.msgBox( 7 '送信確認', 8 '選択した宛先にメールを送信しますか?', 9 Browser.Buttons.OK_CANCEL 10 ); 11 12 // 「キャンセル」なら、ここで処理を終了 13 if (response === 'cancel') return; 14 15 // ドキュメントの文章を取得 16 const DOC_URL = 'ドキュメントのURL'; 17 const doc = DocumentApp.openByUrl(DOC_URL); 18 const docText = doc.getBody().getText(); 19 20 // スプレッドシートを取得 21 const ss = SpreadsheetApp.getActiveSpreadsheet(); 22 const sheet = ss.getSheetByName('宛先リスト'); // シート名でシートを取得 23 const lastRow = sheet.getLastRow(); 24 const range = sheet.getRange(2, 1, lastRow, 5); 25 26 // チェックボックスに✅がはいっているレコードのみに絞る 27 const checkedRecords = range.getValues().filter(row => row[0] === true); 28 29 const subject = 'メルマガ送信テスト'; 30 const options = { name: 'いつも隣にITのお仕事' }; 31 32 // メールを送信 33 for (let data of checkedRecords) { 34 const company = data[1]; 35 const lastName = data[2]; 36 const firstName = data[3]; 37 const recipient = data[4]; 38 39 const body = docText 40 .replace('{社名}', company) 41 .replace('{姓}', lastName) 42 .replace('{名}', firstName); 43 44 GmailApp.sendEmail(recipient, subject, body, options); 45 } 46 47 // 送信完了のメッセージボックスを画面に表示 48 Browser.msgBox('メールの送信が完了しました。'); 49} 50 51/* 52 * 全てを選択する関数(全てに✅をいれる) 53 */ 54function checkAll() { 55 const ss = SpreadsheetApp.getActiveSpreadsheet(); 56 const sheet = ss.getSheetByName('宛先リスト'); // シート名でシートを取得 57 const lastRow = sheet.getLastRow(); 58 const range = sheet.getRange(2, 1, lastRow); 59 range.check(); // チェックをいれる 60} 61 62/* 63 * 選択をリセット選択する関数(全ての✅をはずす) 64 */ 65function uncheckAll() { 66 const ss = SpreadsheetApp.getActiveSpreadsheet(); 67 const sheet = ss.getSheetByName('宛先リスト'); // シート名でシートを取得 68 const lastRow = sheet.getLastRow(); 69 const range = sheet.getRange(2, 1, lastRow); 70 range.uncheck(); // チェックをはずす 71}

投稿2022/10/07 02:22

編集2022/10/07 03:23
Cocode

総合スコア2314

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiyuh

2022/10/07 08:58

チェックボックス選択式は送信を手作業で行う手間はありますが、 一件一件メールを作成するよりは遥かに楽&自動すぎないことで誤作動による送り間違えもおさえられる という点からベスト回答にさせていただきました。 お力添えいただきありがとうございます!!
guest

0

新しく更新された行にだけ

これを判別するものを作成する必要があります。
onEdit()を使用すると、シートの変更を検知することができます。

gs

1function onEdit(e) { 2 3 // 編集された行数 4 let editRow = e.range.getRow() 5 let editCol = e.range.getColumn() 6 7 // ヘッダ行を除いた、2行目から下のセル 8 if (editRow >= 2) { 9 // さらに特定の列だけ、D列(4列目)までのセルが変更された 10 if (editCol <= 4) { 11 let sheet = e.source.getActiveSheet() 12 // 行の内容が更新されたので、「更新」をセット 13 sheet.getRange(editRow, 5).setValue("更新") 14 } 15 } 16}

さらにE列に「行が更新されたか?」の状態を保持しておく必要があります。
イメージ説明

メール送信処理のforループ内で、E列セルを取得し「更新」されている場合に
メール送信を行うようにすれば問題は解消できるのではないかと思います。

gs

1 for (let i = 2; i <= lastRow; i++) { 2 3 const company = sheet.getRange(i, 1).getValue(); 4 const lastName = sheet.getRange(i, 2).getValue(); //姓 5 const firstName = sheet.getRange(i, 3).getValue(); //名 6 const recipient = sheet.getRange(i, 4).getValue(); 7 8 // 更新されたかフラグ 9 let updateRange = sheet.getRange(i, 5) 10 11 // 行の更新があった場合のみ、メールを送信 12 if (updateRange.getValue() === "更新") { 13 const body = docText 14 .replace('{社名}', company) 15 .replace('{姓}', lastName) 16 .replace('{名}', firstName); 17 18 console.log(`${i}行目 更新されているのでメール送信`) 19 GmailApp.sendEmail(recipient, subject, body, options); 20 21 // 更新されるまでの再送信を防ぐため、空文字をセット 22 updateRange.setValue("") 23 } 24 }
実施前処理実施後再実施前再実施後
イメージ説明イメージ説明イメージ説明イメージ説明

投稿2022/10/07 02:21

k.a_teratail

総合スコア845

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiyuh

2022/10/07 08:55

ご回答いただきありがとうございます。 今回製作しているシステムが、一度に3行のデータが追加されて、そのうち2つの列は前行と同じデータだけど1列のみデータが変わっていて・・・みたいな複雑な構成だったので、適用したところ少し用途と当てはまらない点が出てきてしまいました。しかし、今後十分に使用できるコードですので、ぜひ活用させていただきます。 お力添えいただきありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問