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

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

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

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

Q&A

解決済

1回答

2338閲覧

GASでGmailの下書き一括メール作成(添付ファイル付き)を作成したい

macaulay

総合スコア2

Google Apps Script

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

0グッド

0クリップ

投稿2022/11/29 13:01

編集2022/12/01 02:20

前提

GASで下書きメール作成(添付ファイルつき)を作成したい

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • メールの下書きを一括作成したい
  • それぞれのメールにはGドライブに保存してある異なるファイルを添付したい
  • H列に記載した添付ファイル名を指定したドライブから検索して添付する

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

試しに2通分作成してみたところ、2通とも2行目に書いたファイルが添付されてしまう。 それぞれ異なるファイルを添付するようにしたい

該当のソースコード

GAS

1 function allsend() { 2 var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); 3 var values = sheet.getRange("A3:H" + sheet.getLastRow()).getValues(); 4 var lastRow = sheet.getLastRow(); 5 var folder = DriveApp.getFolderById("*****"); 6 7for(let i = 3; i<=lastRow; i++){ 8 var fileName = sheet.getRange(i,8).getValue(); 9 var tempu = DriveApp.getFilesByName(fileName).next(); 10} 11 values.forEach(([from, recipient, cc, bcc, subject, ...body]) => { 12 { 13 GmailApp.createDraft(recipient, subject, body.join("\n"), { from, cc, bcc, "htmlBody":body.join("\n"), attachments:[tempu]}); 14 } 15 }); 16} 17

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。
イメージ説明

イメージ説明

イメージ説明

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

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

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

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

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

YAmaGNZ

2022/11/29 13:15

tempuがどうなっているのかデバッグしてみましょう
guest

回答1

0

ベストアンサー

不具合の原因

  • このfor(let i = 3; i<=lastRow; i++)for文の処理ですが、変数tempuを書き換えているので、最後に書き換えた値(全部で2行なら、2行目のファイル名)に最終的になっています。

その他の気になる点

  • sheet.getRange(i,8).getValue()でファイル名を取得していますが、そもそも変数valuesの中にファイル名も含まれているので、二度手間ではないでしょうか。
    • valuesの中身を分割代入するときに、ファイル名も代入しましょう。
  • varは古い記法です。新しいconst / letを使うようにしましょう(機能的にvarには欠点があるので、新しいものが出てきているのです)。
  • 関数名のお作法にしたがってみるのはいかがでしょうか。
    • 「動詞」から始める
    • 最近はキャメルケースが主流
    • 🔺allsend() → ✅sendAll()
  • 変数のfromがどうやら予約語のようで、エディタで文字色が変わりました。使うのを避けた方が良いかもしれません。(確信はありません)

コード例

javascript

1function sendAll() { // 関数名は「動詞」から始めるのがお作法 2 const FOLDER = DriveApp.getFolderById('****フォルダーID****'); // 添付ファイルのあるフォルダを取得 3 4 const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); 5 const lastRow = sheet.getLastRow(); // 先に最終行を取得して 6 const values = sheet.getRange("A3:H" + lastRow).getValues(); // lastRowをここで使えばスマート 7 8 // 取得してきた値を1行ごとに繰り返し処理 9 for (const arr of values) { 10 const [sender, recipient, cc, bcc, subject, name, sentences, fileName] = arr; // fromは予約語っぽいので使わない方がいいかも…? 11 const body = name + '\n\n' + sentences; // 宛名 + 改行 改行 + 本文 12 const attachedFile = FOLDER.getFilesByName(fileName).next(); // 指定のフォルダの中から添付ファイルを取得 13 const options = { sender, cc, bcc, htmlBody: body, attachments: [attachedFile] }; 14 GmailApp.createDraft(recipient, subject, body, options); 15 } 16}

※ 実際に実行して試したわけではないので正常に動作するかわかりません。もしエラーがでましたら、エラーの内容を教えてください。修正いたします。

投稿2022/11/29 20:54

編集2022/12/01 09:25
Cocode

総合スコア2314

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

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

macaulay

2022/11/30 01:56

丁寧にご回答いただきありがとうございます!!! 当方、GASは初心者のため大変有り難いです。 早速実行したところ下記エラーが出てしまいました。 ーーーーー Exception: Cannot retrieve the next object: iterator has reached the end. sendAll @ コード.gs:10 ーーーー Gドライブにフォルダが複数あるので、フォルダIDの指定が必要かなと思ったのですが どうでしょうか・・?
Cocode

2022/11/30 07:53 編集

フォルダを指定しなくてもドライブ全体から探してきてくれます。 ただ、複数取得してくるので、おっしゃる通りフォルダを指定した方がベターです。 そのエラーは、どうやら指定のファイル名は存在しないようです。 スプレッドシートに記載のファイル名は間違っていませんか? const [sender, recipient, cc, bcc, subject, body, fileName] = arr; ↑この行のあとに、 Logger.log(fileName); ↑この行を追加して、(図形ボタンクリックではなく)エディタの画面の「実行▶︎」をクリックして確認してみてくださいm(_ _)m
macaulay

2022/11/30 14:04

ご回答ありがとうございます! 追記し実行してみましたが、同様のエラーが発生してしまいました。。。 すみません、事前にお伝えしておけばよかったのですが会社で使用しているドライブのため 大量のフォルダ、ファイルがあり、更に似たようなファイル名もたくさんある状況でございます。。。 差し支えなければフォルダ指定の追記をしたいのですが、 ご教授頂けますでしょうか?お手数ですがよろしくお願いします!
Cocode

2022/11/30 14:19 編集

エラーは発生されると思います!fileNameがちゃんとスプシから取得できているかの確認をしたかっただけなのです。 目的のファイル名は取得できていますか?(ログに表示されていますか?) (発生しているエラーは、ファイル名が重複しているからではなく、指定のファイル名が存在しないからっぽいのです。) 指定のフォルダの中には必ず目的のファイル名は1つしかないという前提でよいでしょうか?
Cocode

2022/11/30 14:17

または、もし指定フォルダ内に同じファイル名が複数ある場合は、どれを選択したらいいのでしょうか? よろしくお願いいたします。
macaulay

2022/12/01 02:22

ご回答ありがとうございます! 実行した際の画面を添付しました! >目的のファイル名は取得できていますか?(ログに表示されていますか?) 取得できていません。 >指定のフォルダの中には必ず目的のファイル名は1つしかないという前提でよいでしょうか? はい、1つしかありません。 今後も同じフォルダ内には複数作成することはないので、複数ある場合は考慮しなくても大丈夫です! お手数ですがどうぞよろしくお願いいたします!
Cocode

2022/12/01 03:01

画像ありがとうございます。みたいところのってなかったですけど…笑 でも原因わかりました! コード修正します。
Cocode

2022/12/01 03:05 編集

回答の「コード例」のコードを修正しました!お試しください。 ★★★追記★★★ すみませんフォルダ指定の件失念しておりました。もう少々お待ちを。
Cocode

2022/12/01 03:11

フォルダ指定版のコードに修正しました。お試しください。
macaulay

2022/12/01 05:00

すごいです!添付できました!! 本当にありがとうございます!!! あともう一点だけ、すみません・・・! 元々htmlメールで作成されるようになっていたのですが、テキストメールになってしまいました。 htmlメールにすることは可能でしょうか??
Cocode

2022/12/01 08:35

元々のhtmlメールが、中身htmlタグじゃなかったので、間違いかと思いその部分の記述を削除してしまいましたすみません! 修正します
Cocode

2022/12/01 09:25

修正しました。 const options = ... の1行を書き換えたのみです。 お試しください。
macaulay

2022/12/01 10:21

ありがとうございます! なぜかまたエラーが出てしまいました。。何度もすみません。。 Exception: Cannot retrieve the next object: iterator has reached the end. sendAll @ コード.gs:12 Exception: 次のオブジェクトを取得できません。イテレータが末尾に到達しました。
Cocode

2022/12/01 11:40

12行目ってどのコードですか?
macaulay

2022/12/01 13:17

こちらです! const attachedFile = FOLDER.getFilesByName(fileName).next(); // 指定のフォルダの中から添付ファイルを取得
macaulay

2022/12/01 13:54

すいません! 2通分記載していて、2通目に添付ファイル名を空欄にしていたせいでした! コード自体に問題はありませんでした! ただこのツールを添付ファイルがない場合にも同様に使いたいのですが、エラーが出ないようにすることは可能でしょうか・・?
macaulay

2022/12/02 05:26

tryとcatchを入れて改善できました! たくさんアドバイス頂きありがとうございます!!大感謝です!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問