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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Google Apps Script

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

Q&A

解決済

1回答

313閲覧

GASで下書きメールを作成したい

sasasasw

総合スコア2

Google Apps Script

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

0グッド

2クリップ

投稿2023/05/23 12:00

初めまして。
プログラミングの初心者で、何分お聞き苦しい部分もあるかもしれませんが、解決に向けてご教示いただければ幸いです。

実現したいこと

スプレットシートで「下書きメール」ボタンを押下すると、選択した行から必要情報を抽出し、Gmailに下書きメールを作成したい。

発生している問題・エラーメッセージ

ボタンを押下した後、選択した行(例えば10行目)にある情報(1・7・8列目)のみを抽出したいのに、全ての行を選択してしまい、1行につき1つのメールが無限ループで作成され、プログラムが止まらない。

該当のソースコード

function

1createDraft() { 2 const ui = SpreadsheetApp.getUi(); 3 const response = ui.alert('下書きメールを作成しますか?', ui.ButtonSet.OK_CANCEL); 4 let j = 0; //下書き作成の有無カウント用 5 if (response == ui.Button.OK) { 6 const sheet = SpreadsheetApp.getActiveSheet(); 7 const lastRow = sheet.getLastRow(); 8 9 for (let i = 8; i <= lastRow; i++) { 10 const values = sheet.getRange(i, 1, 1, 10).getValues(); 11 /* メールに差し込む各項目 */ 12 const applynumber = values[0][0]; //申請ナンバー 13 const date = values[0][6]; //申請日付 14 const name = values[0][7]; //申請者 15 16 17 18 let recipient = "送信メール先"; 19 const subject = (`ファイル名(${name})`); 20 21 const body = 22 (`ファイルを更新しました。 23 申請№:${applynumber} 24 申請日:${date} 25 26 対象のスプレットシートのURLを表示 27 28 let options ={cc: "共有先のメールアドレス", }; 29 30 GmailApp.createDraft(recipient,subject,body,options); 31 } 32 if (j > 0) { 33 ui.alert(`申請依頼の下書きメールを作成しました。Gmailの「下書き」トレイをご確認ください。)`); 34 } else { 35 ui.alert(`下書き作成をキャンセルしました。`); 36 } 37 } 38}

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

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

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

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

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

YAmaGNZ

2023/05/23 13:25 編集

jはいつ足されるのですか? あと、デバッガは使用しないのですか? ブレイクポイントで止めてステップ実行するなりして変数を確認できると思いますが・・・
guest

回答1

0

ベストアンサー

参考にしたと思われるサイトを確認したところ、
下書きを作成するかどうか、作成済みかどうかを特定の列(H列)の「下書きを作成する」「下書き作成済」という値で判断するようになっていますが、ご提示のスクリプトではその部分が削除されていたので、
スクリプトの実行時に特定の1行を指定して下書きを作成することがご希望の動作ではないかと推測しました。

ダイヤログの中で行番号を指定するとその行のデータに基づいてメールの下書きを作成する参考スクリプトは
以下のとおりとなりますので、これを参考にご自身のスクリプトを希望の動作になるように修正されてはどうでしょうか。

JavaScript

1//行番号を指定するバージョン 2function createMailDraft() { 3 const ui = SpreadsheetApp.getUi(); 4 let j = 0;//下書き作成の有無カウント用 5 //何行目からデータを取得するか確認 6 const response = ui.prompt('確認','下書きメールを作成する行番号を入力してください。', ui.ButtonSet.OK_CANCEL); 7 if (response.getSelectedButton() != ui.Button.CANCEL) { 8 const i = response.getResponseText();//下書きを作成するデータ行を取得 9 const sheet = SpreadsheetApp.getActiveSheet(); 10 const values = sheet.getRange(i, 1, 1, 10).getValues(); 11 /* メールに差し込む各項目 */ 12 const applynumber = values[0][0];//申請ナンバー 13 let date = values[0][6];//G列:申請日付 14 //G列が日付データのときは、文字列に整形 15 if (Object.prototype.toString.call(date) == "[object Date]") { 16 date = Utilities.formatDate(date, 'JST', 'yyyy/M/d'); 17 } 18 const name = values[0][7];//H列:申請者 19 const recipient = "送信メール先";//←★ここにメールアドレスを記入 20 const subject = (`ファイル名(${name})`); 21 const body = 22 (`ファイルを更新しました。 23 申請№:${applynumber} 24 申請日:${date} 25 `);//←★この行を追加 26 //対象のスプレットシートのURLを表示 ←★この行は何なのか不明でした。 27 const options = {cc: "共有先のメールアドレス", };//←★ここにメールアドレスを記入 28 console.log('to:' + recipient + '\nsubject:' + subject + '\nbody:' + body + '\nop:' + options.cc); 29 GmailApp.createDraft(recipient,subject,body,options); 30 j++;//←★この行を追加 31 } 32 if (j > 0) { 33 ui.alert(`申請依頼の下書きメールを作成しました。Gmailの「下書き」トレイをご確認ください。`); 34 } else { 35 ui.alert(`下書き作成をキャンセルしました。`); 36 } 37}

投稿2023/05/23 23:34

YellowGreen

総合スコア683

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

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

YellowGreen

2023/05/23 23:52

重複しないようにfunction名を変えてありますので、ボタンでの動作確認には ボタンへの再割り当てが必要になりますので念のため。
sasasasw

2023/05/24 03:01

早速のご回答、ありがとうございます。 意図としては6行目でポップアップが出現される際、確認で行番号を指定するのではなく、「OK」を押下するだけで現在選択している1行の情報が拾えるようにしたいと考えています(そのため、6行目は「ui.prompt」ではなく「ui.alert」に変えました)。 ただそのようにすると、8行目で「getResponseText」が反応せずにエラーとなります。 getResponseTextは、当初確認で行番号を指定した行の値を取得する変数というのは認識していますが、それに代替する変数が当てはまらず思案しております。 重ねてのお願いで恐縮ですが、解決先をご教示いただくことは可能でしょうか? 作成中のプログラムは下記になります。 --------------------------------------------------------------------------------------------- //行番号を指定するバージョン function createMailDraft() { const ui = SpreadsheetApp.getUi(); let j = 0;//下書き作成の有無カウント用 //何行目からデータを取得するか確認 const response = ui.alert('下書きメールを作成しますか?', ui.ButtonSet.OK_CANCEL); if (response !== ui.Button.CANCEL) { const i = response.getLastRow();//下書きを作成するデータ行を取得 const sheet = SpreadsheetApp.getActiveSheet(); const values = sheet.getRange(i, 1, 1, 10).getValues(); /* メールに差し込む各項目 */ const applynumber = values[0][0];//申請ナンバー let date = values[0][6];//G列:申請日付 //G列が日付データのときは、文字列に整形 if (Object.prototype.toString.call(date) == "[object Date]") { date = Utilities.formatDate(date, 'JST', 'yyyy/M/d'); } const name = values[0][7];//H列:申請者 const recipient = "******************";//←★ここにメールアドレスを記入 const subject = (`****************(${name})`); const body = (`****************を更新しました。 申請№:${applynumber} 申請日:${date} スプレットシートのURL `);//←★この行を追加 //対象のスプレットシートのURLを表示 ←★この行は何なのか不明でした。 const options = {cc: "**********", };//←★ここにメールアドレスを記入 console.log('to:' + recipient + '\nsubject:' + subject + '\nbody:' + body + '\nop:' + options.cc); GmailApp.createDraft(recipient,subject,body,options); j++;//←★この行を追加 } if (j > 0) { ui.alert(`申請依頼の下書きメールを作成しました。Gmailの「下書き」トレイをご確認ください。`); } else { ui.alert(`下書き作成をキャンセルしました。`); } }
YellowGreen

2023/05/24 04:24 編集

「選択した行から必要情報を抽出し」の部分を読みきれていませんでした。 セル範囲が選択状態にある行ということだったんですね。 それなら次のようになります。 if (response != ui.Button.CANCEL) { の次の2行を以下のとおりとしてください。 const sheet = SpreadsheetApp.getActiveSheet(); const i = sheet.getActiveRange().getRow();//選択されている行番号を取得 先にアクティブシートを取得します。 次にアクティブレンジからその行番号を取得できます。
YellowGreen

2023/05/24 04:20

行が選択状態になくても、その行にカーソルがあれば、その行番号を取得できます。
YellowGreen

2023/05/24 04:32

もしかして、複数の行を選択したときに、それぞれの行のデータに基づいてそれぞれにメールを送りたかったのでしょうか?
YellowGreen

2023/05/24 04:51 編集

複数のセル範囲が選択されているときのそれぞれの行データでメールの下書きを作成したい場合は、 if (response != ui.Button.CANCEL) { 以降の2行を次の4行に変更します。 const sheet = SpreadsheetApp.getActiveSheet(); const ranges = sheet.getActiveRangeList().getRanges(); ranges.forEach(v => { const i = v.getRow();//選択されている行番号を取得 そして、 const values = sheet.getRange(i, 1, 1, 10).getValues(); 以降で、最後の方の j++;//←★この行を追加 } の2行の間に }); の1行を挿入し j++;//←★この行を追加 }); } のようにします。(波括弧、丸括弧、セミコロンを追加です。) セル範囲が連続していなくても複数の行が選択されていれば それぞれの行の値に基づいてメールの下書きを作成します。
YellowGreen

2023/05/24 05:40 編集

上では、同じ行で複数のセル範囲が選択されているとその数分下書きができてしまいますので 同じ行ではひとつのセルだけを選択していただくようになります。 (追記) 同じ行で複数のセル範囲が選択されていても重複しないようにする方法として上の 書き換える4行を以下の4行にすることで重複を除外します。 const sheet = SpreadsheetApp.getActiveSheet(); const ranges = sheet.getActiveRangeList().getRanges();//選択範囲を全て取得 const rows = new Set(ranges.map(v => v.getRow()));//重複行を除外 rows.forEach(i => {
sasasasw

2023/05/24 05:05

解決できました! 確かにシート>行の順番でないと、正しく判別できないですものね… 運用としては、複数ではなく単一行でのメール送信になります。 ご丁寧にご教示いただき、ありがとうございました。
YellowGreen

2023/05/24 05:50

お役に立ったようで何よりです。 当方の読解力不足でお手数をおかけしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問