実現したいこと
特定の時刻になったらgmailを送るものをつくろうとしています。
特定の時刻が複数あるので、GASのトリガーではなくGoogleスプレッドシートでnow関数を用いています。
now関数からhourとminuteで時と分を表示するセルをそれぞれ用意しています。その二つの値が表で用意している時刻表群と等しいものがあれば、それ以降の、gmailを送るプログラムが動くようにしています。
発生している問題・分からないこと
実現したいことで説明した、minute関数を用いて分を表示しているセルの値を変数hourに"const"を用いて格納した際に、実際にセルで表示されている分の値とhourが異なってしまいます。これは、下のソースコードの"console.log"で確認しています。
"const"を"var"に変えてもセルの値とhourが異なっています。
minute関数になっていない定数のセルから数値を正しく読み取ることは可能でした。
minute関数となっているセルの値を「=(セルの番号)」でそのまま置換するセルを用意して、それをhourとして読み取る形にしても、minuteのセルと「=(セルの番号)」の2つは同じ値が表示されますが、hourとは値が異なってしまいます。
now関数があるスプレッドシートは、更新時と分ごとに値が更新されるようになっています。
上記のような場合で、値が異なってしまう理由を教えてください。
該当のソースコード
1function sendConditionalEmails() { 2 const spreadsheet = SpreadsheetApp.openById("1ujn3YC5CG0T_p4LpkNPq50Sq9D7BOnP74odvJsXk-e4"); 3 4 // timeシートからデータを取得 5 const timeSheet = spreadsheet.getSheetByName("time"); 6 const month = timeSheet.getRange("B4").getValue(); 7 const day = timeSheet.getRange("C4").getValue(); 8 const hour = timeSheet.getRange("D4").getValue(); 9 const minute = timeSheet.getRange("E4").getValue(); 10 11 // 変数の値を確認 12 console.log(month) 13 console.log(day) 14 console.log(hour) 15 console.log(minute) 16 17 // class_timeシートのデータを取得 18 const classTimeSheet = spreadsheet.getSheetByName("class_time"); 19 const classTimeData = classTimeSheet.getDataRange().getValues(); 20 21 // hourと一致する行を検索 22 let i = -1; 23 for (let row = 1; row < classTimeData.length; row++) { 24 if (classTimeData[row][1] === hour) { // B列の値と一致 25 i = row + 1; // 行番号を取得 (1ベース) 26 break; 27 } 28 } 29 30 if (i === -1) { 31 Logger.log("hourと一致する値が見つかりません。プログラムを終了します。"); 32 return; 33 } 34 35 // minuteと一致するか確認 36 const classTimeMinute = classTimeSheet.getRange(i, 3).getValue(); // C列 37 if (classTimeMinute !== minute) { 38 Logger.log("minuteと一致しません。プログラムを終了します。"); 39 return; 40 } 41 42 // A列の値をperiodに代入 43 const period = classTimeSheet.getRange(i, 1).getValue(); 44 45 // 繰り返し処理の準備 46 const classPlanSheet = spreadsheet.getSheetByName("class_plan"); 47 const memberSheet = spreadsheet.getSheetByName("member"); 48 const mailSheet = spreadsheet.getSheetByName("mail"); 49 const classPlanData = classPlanSheet.getDataRange().getValues(); 50 const memberData = memberSheet.getDataRange().getValues(); 51 52 const noc = 5; 53 let rep = 1; 54 55 while (rep <= noc) { 56 const planMonth = classPlanData[rep - 1][0]; // A列 57 const planDay = classPlanData[rep - 1][1]; // B列 58 const planPeriod = classPlanData[rep - 1][2]; // C列 59 const planStatus = classPlanData[rep - 1][4]; // E列 60 61 // 条件を満たさなければ次のrepに進む 62 if (planMonth !== month || planDay !== day || planPeriod !== period || planStatus !== 0) { 63 rep++; 64 continue; 65 } 66 67 // 条件を満たした場合 68 const id = classPlanData[rep - 1][3]; // D列 69 i = -1; 70 71 // memberシートでidを検索 72 for (let row = 1; row < memberData.length; row++) { 73 if (memberData[row][0] === id) { // A列の値と一致 74 i = row + 1; // 行番号を取得 (1ベース) 75 break; 76 } 77 } 78 79 if (i === -1) { 80 Logger.log(`memberシートにID ${id} が見つかりません。(rep: ${rep})`); 81 rep++; 82 continue; 83 } 84 85 // メール情報をセット 86 const recipient = memberSheet.getRange(i, 4).getValue(); // D列 87 mailSheet.getRange("B1").setValue(recipient); 88 const subject = mailSheet.getRange("B2").getValue(); 89 let body = mailSheet.getRange("B3").getValue(); 90 91 // $1, $2, $4の置換 92 const memberB = memberSheet.getRange(i, 2).getValue(); // B列 93 const memberC = memberSheet.getRange(i, 3).getValue(); // C列 94 body = body.replace("$1", memberB).replace("$2", memberC).replace("$4", period); 95 96 // メール送信 97 if (recipient && subject && body) { 98 GmailApp.sendEmail(recipient, subject, body); 99 Logger.log(`メールを送信しました。(rep: ${rep})`); 100 } else { 101 Logger.log("メール送信に必要な情報が不足しています。"); 102 } 103 104 // mailシートのB1に"$4"をセット 105 mailSheet.getRange("B1").setValue("$4"); 106 107 // repを1増やす 108 rep++; 109 } 110} 111 112
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
「わからないことや発生している問題を教えてください」に書いた通りです。
また、検索してもminuteが原因で値が正しく」読み取れない理由はわかりませんでした。
補足
最後に、今回初めてGASに触れたため至らないところが多いとは思いますが、よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー