前提
スプレッドシート内に全部で3つのシートがあります。
シート1:情報のやりとりをするシート
シート2:メールアドレスのテーブル
シート3:自動送信させるメールの件名、本文等が記載されているシート
複数人で「シート1」を通じて、情報のやりとりをしています。
情報のやりとりは、以下の2種があります。
(往路) 新規投稿(B列~G列に追記)
(復路) 新規投稿へのコメントバック(K列~M列に追記)
実現したいこと
(往路)または(復路)のシート1の内容更新が行われたら、
GASで更新連絡メールを自動送信させたいです。
(往路)と(復路)で宛先、本文が異なるため、
処理をfunction1とfunction2の2つに分け、
それぞれに対しイベントトリガー設定をし、自動で処理が
走るようにしようと思っています。
<function1(往路)> I列がブランクの時のみ処理
- 1-1 スプレッドシートの情報をもとにメール作成、送信
- 1-2 シート1のI列に「済」フラグ追記
- 1-3 シート1のJ列にタイムスタンプ追記
<function2(復路)> I列に「済」があり、o列がブランクの時のみ処理
- 2-1 スプレッドシートの情報をもとにメール作成、送信
- 2-2 シート1のO列に「済」フラグ追記
- 2-3 シート1のP列にタイムスタンプ追記
<トリガー設定>
スプレッドシート_変更時
発生している問題・エラーメッセージ
function1の処理は問題なく走ります。
が、処理2-1のメール宛先の元データのN列を、下のスプレッド
シート上の関数※で補充させている関係で、function1が走った
直後にN列が補充されてしまい、そのタイミングでfunction2の処理が走り、
処理2-2、2-3が行われるため、処理2-1処理の判定で「作成対象外」と
判定されてしまうためか、メール送信ができません。
※(セルN5)の関数
=ArrayFormula(IFERROR(VLOOKUP(D5:D,'メアドシート'!$B$5:$H$8,7,0),""))
どのように回避するのがよいか、アドバイスをいただけないでしょうか?
また、どうしてアドバイスいただいた回避策がよいのかのメリ、
(第三案の場合は、以下a)、b)のデメ)についても教えてください。
<現時点で想像している回避策>
a) (セルN5)の関数を修正する
M列(返信コメント)に記載がない場合は、N列の補充処理がされないよう、
IFをさらに追加すればよいのでは? と、想像しているものの、どこに
どのようにIF追加すればよいか自力でたどりつけないので、
アドバイスが欲しいです。
b) function2にN列を追記する処理を追加する
E列の内容をキーに、シート2:メールアドレスのテーブルを参照し、
O列ブランクのN列のセルにメアド補充させたらよいのではないかと
推察していますが、どのようにコード記載すればよいかまでは
自力でたどりつけないので、アドバイス欲しいです。
該当のソースコード
以下に現コードを全文記載します。
8/12 下コードの冒頭にfunction1のコードを追記。
GAS
1 2function createMailData1() { 3 const ss = SpreadsheetApp.openById('~省略~'); 4 const mySheet1 = ss.getSheetByName('元シート'); 5 const mySheet2 = ss.getSheetByName('メアドシート'); 6 const mailSheet = ss.getSheetByName('メール文シート'); 7 const lastRow = mySheet1.getRange(mySheet1.getMaxRows(), 7).getNextDataCell(SpreadsheetApp.Direction.UP).getRow(); 8 console.log('lastRow ' + lastRow); //9が出たら正解 9 const targetRows = lastRow - 5 10 console.log('targetRows ' + targetRows); //4が出たら正解 11 12 //▼送信先のメアド 13 //「元シート(mySheet1)」のB列~I列までの値を 14 //getRange.getValuesで二次元配列(myRange)として取得 15 //起点は6行目、3列目(セルB6) 16 //getRange(行,列,●行分,▲列分) 17 const myRange = mySheet1.getRange(6, 2, targetRows, 8).getValues(); 18 console.log('myRange ' + myRange); 19 20 //for ループ 21 //行インデックス0スタートで+1ずつ、lastRowまで繰り返し 22 for (let i = 0; i < targetRows; i++) { 23 let no = myRange[i][0]; // 連番(B列) 24 let recipient = myRange[i][6]; // メアド(H列) 25 let myFlag1 = myRange[i][7]; // 投稿連絡フラグ(I列) 26 console.log('no ' + no); 27 console.log('recipient ' + recipient); 28 console.log('myFlag1 ' + myFlag1); 29 30 //投稿連絡フラグ欄(myFlag1)に「済」ありの時は処理スキップ 31 if (myFlag1 === "済") { 32 continue; 33 } 34 35 //▼メール件名 36 //「メール文シート(mySheet2)」のセルC3から取得 37 //getRange(行,列) 38 const subject1 = mailSheet.getRange(3, 3).getValue(); 39 console.log('subject1 ' + subject1); 40 41 //▼メール本文(body1) 42 //「メール文シート(mySheet2)」のセルC4から取得 43 const body1 = mailSheet.getRange(4, 3).getValue(); 44 console.log('body1 ' + body1); 45 46 const options = { 47 name: '自動送信メール', 48 noReply: true 49 //from:'~省略~' 50 }; 51 GmailApp.sendEmail(recipient,subject1,body1,options); 52 53 //▼元シート(mySheet1)の「投稿連絡メール」欄(I列)に"済"フラグを追記 54 //getRange(行,列,●行分,▲列分) 55 const addFlag = mySheet1.getRange(i +6, 9, 1, 1).setValue("済"); 56 57 //▼元シート(mySheet1)の「投稿連絡送信日」欄(J列)に"済"日時を追記 58 const timeStamp =new Date(); 59 console.log(timeStamp); 60 mySheet1.getRange(i +6, 10, 1, 1).setValue(timeStamp); 61 } 62} 63 64 65 66function createMailData2() { 67 const ss = SpreadsheetApp.openById('~省略~'); 68 const mySheet1 = ss.getSheetByName('元シート'); 69 const mySheet2 = ss.getSheetByName('メアドシート'); 70 const mailSheet = ss.getSheetByName('メール文シート'); 71 const lastRow = mySheet1.getRange(mySheet1.getMaxRows(), 7).getNextDataCell(SpreadsheetApp.Direction.UP).getRow(); 72 console.log('lastRow ' + lastRow); //9が出たら正解 73 const targetRows = lastRow - 5 74 console.log('targetRows ' + targetRows); //4が出たら正解 75 76 //▼送信先のメアド 77 //「元シート(mySheet1)」のB列~P列までの値を 78 //getRange.getValuesで二次元配列(myRange2)として取得 79 //getRange(行,列,●行分,▲列分) 80 const myRange2 = mySheet1.getRange(6, 2, targetRows, 16).getValues(); 81 console.log('myRange2 ' + myRange2); 82 83 //for ループ 84 //行インデックス0スタートで+1ずつ、lastRowまで繰り返し 85 for (let i = 0; i < targetRows; i++) { 86 87 //二次元配列名[行インデックス][列インデックス] 88 //起点[0][0]は6行目、3列目(セルB6) 89 let no = myRange2[i][0]; // 連番(B列) 90 let recipient = myRange2[i][12]; // 投稿者メアド(N列) 91 let myFlag1 = myRange2[i][7]; // 投稿連絡フラグ(I列) 92 let myFlag2 = myRange2[i][13]; // 返信連絡フラグ(O列) 93 console.log('no ' + no); 94 console.log('recipient ' + recipient); 95 console.log('myFlag1 ' + myFlag1); 96 console.log('myFlag2 ' + myFlag2); 97 98 //<条件1> 99 //返信連絡フラグ(myFlag2)がブランクの時は処理スキップ 100 if (myFlag2 === "済") { 101 continue; 102 103 //<条件2> 104 //投稿連絡フラグ((myFlag1)が「済」の時はfalse、それ以外はtrue 105 } else if (!(myFlag1 === "済")){ 106 continue; 107 } 108 109 //▼メール件名 110 //「メール文シート(mySheet2)」のセルC7から取得 111 //getRange(行,列) 112 const subject2 = mailSheet.getRange(7, 3).getValue(); 113 console.log('subject2 ' + subject2); 114 115 //▼メール本文(body2) 116 //「メール文シート(mySheet2)」のセルC8から取得 117 const body2 = mailSheet.getRange(8, 3).getValue(); 118 console.log('body2 ' + body2); 119 120 const options = { 121 name: '自動送信メール', 122 noReply: true 123 }; 124 125 GmailApp.createDraft(recipient, subject2, body2, options); 126 //★あとでsendEmailに修正★ 127 //GmailApp.sendEmail(recipient, subject2, body2, options); 128 129 //▼お褒めシート(mySheet1)の「返信連絡フラグ欄(O列)」に"済"フラグを追記 130 //getRange(行,列,●行分,▲列分) 131 const addFlag = mySheet1.getRange(i + 6, 15, 1, 1).setValue("済"); 132 133 //▼お褒めシート(mySheet1)の「返信連絡送信日」欄(P列)に"済"日時を追記 134 const timeStamp = new Date(); 135 console.log(timeStamp); 136 mySheet1.getRange(i + 6, 16, 1, 1).setValue(timeStamp); 137 } 138}
補足情報(FW/ツールのバージョンなど)
次回から、類似のケースは自力解決できるようになりたいので、
回答は遅くなってもかまいませんので、非エンジニア、ビギナーでも
わかるレベルでの回答、解説をいただけると助かります。
回答1件
あなたの回答
tips
プレビュー