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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

948閲覧

spreadsheet上の行で期限が来たらMailSendを行いたいがformatDate(string,string,string)となってしまう

tanukichan

総合スコア4

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/11/04 02:40

編集2019/11/04 09:29

初めまして初心者です。
どなたか教えていただけないでしょうか。

前提・実現したいこと

GoogleActionScriptを使用し、Google spreadsheet上の各行の中で期限の3日前、7日前に自動的に指定のメールアドレスにMailSendでリマインドを行いたい

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

実行すると以下エラーとなります。
Cannot find method formatDate(string,string,string). (line 25, file "Code")


25行目のコード抜粋
var strLimit_format = Utilities.formatDate(strLimit, "JST", "yyyy/MM/dd");

ネットで調べて解決しようと行ったこと


25行目のコード抜粋にnewdateを追加
var strLimit_format = Utilities.formatDate(new Date(strLimit), "JST", "yyyy/MM/dd");

25行目に追記した結果のエラーメッセージ

TypeError: Cannot find function getYear in object 期限. (line 36, file "Code")

spread sheetの内容

イメージ説明

コード全文

function mailSend() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = spreadsheet.getSheets()[0];
var today = new Date();
var today_format = Utilities.formatDate(today, "JST", "yyyy/MM/dd");

var strFrom = "hoge@gmail.com"; var strCc = ""; for (var i = 2; i <= 300; i++) { var strName = sheet1.getRange(i, 3).getValue(); if ( strName == "" ) { continue; } var strTo = sheet1.getRange(i, 4).getValue(); var strQualNo = sheet1.getRange(i, 1).getValue(); var strQualName = sheet1.getRange(i, 2).getValue(); var strLimit = sheet1.getRange(i, 6).getValue(); var strLimit_format = Utilities.formatDate(new Date(strLimit), "JST", "yyyy/MM/dd"); var strSub = "[お知らせ]" + strQualName + "期限について"; //Subject var strBody = strName + "さん\n\nお疲れ様です。; var strLimit_3Date = new Date(strLimit.getYear(), strLimit.getMonth(), strLimit.getDate() - 3); var strLimit_3Date_format = Utilities.formatDate(strLimit_3Date,"JST","yyyy/MM/dd"); var strLimit_7Date = new Date(strLimit.getYear(), strLimit.getMonth(), strLimit.getDate() - 7); var strLimit_7Date_format = Utilities.formatDate(strLimit_7Date,"JST","yyyy/MM/dd"); if ( today_format == strLimit_3Date_format || today_format == strLimit_7Date_format ) { var send = GmailApp.sendEmail( strTo, strSub, strBody, { from: strFrom } ); } }

}

以上です。

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

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

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

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

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

papinianus

2019/11/04 05:28

修正した結果とその後のエラーが対応していないですし、そのエラーとその36行目が対応していないですし、この経緯が書いてあるままだとしたら、上記対策のため、~とline36の~は同じコードでないと辻褄あわないので理解不能です。 デバッグできができていないのですから、下手に隠さず全部出してください。直前行にエラーがあっても次の行でエラーがでることだってあり得ますし、データに起因するエラーもあり得ますので、コードとデータサンプルを全てお示しください。
tanukichan

2019/11/04 09:30

分かりづらく大変失礼致しました。できる限り分かりやすく記載し直しましたので、ご確認いただけますでしょうか。
guest

回答1

0

回答

コードとエラー(修正前後含め)を拝見した限りでは、期限に日付っぽくないものが入っている(例えば11/31)か、空白であるために、発生しているエラーの可能性が高いです。
strNameのように空であることのチェックを(送信時に当然発生するエラーも考えると)メールアドレスや期限列に対しても実施するのが一つ。
それでもエラーになるなら、ロギング機能を使って、エラーはシートの何行目のどのデータで発生しているのかを突き止めることが考えられます。
また、300行というのをやめて、sheet.getLastRow()などまでのループにすることも必要な気がします。

自己満足

google app scriptに対してタダであることに価値を感じられておられる企業様だと思われます。メールの送信件数リミットや実行時間リミットのことを考えると、基本的にfor内でのgetRangeは全廃し、同一宛先へのメールはまとめることが必要かと思います。(将来的に300行がこれ以上増えないならそこまでしなくてもいいのかもしれないですが)
だいたい自己満足回答しかしませんが、今回のこれはスクリプトが停止されたりメールが送信できなかったり、といった実際に発生しそうな問題を踏まえているので、自己満足性は低いつもり

javascript

1function mailSend() { 2 const sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; 3 const today = (new Date()).toYYMMDD(); 4 const from = "hoge@gmail.com"; 5 // const cc = ""; 6 const filled = sheet1.getDataRange().getValues().slice(1).filter(function(r) { return r[2] !== "" && r[3] !== "" &&r[5] !== "";}).reduce(function(a,c){ 7 var cur = {"A":c[0],"B":c[1],"C":c[2],"E":c[4],"F":c[5],"G":c[6],"H":c[7],"I":c[8]}; 8 var threeDaysAfter = (new Date(cur["F"])).setDate(cur["F"].getDate() + 3).toYYMMDD(); 9 var sevenDaysAfter = (new Date(cur["F"])).setDate(cur["F"].getDate() + 3).toYYMMDD(); 10 if (today !== threeDaysAfter && today !== sevenDaysAfter) { return a;} 11 if(a[c[3]]) { 12 a[c[3]].push(cur); 13 } else { 14 a[c[3]] = [cur,]; 15 } 16 return a; 17 },[]); 18 Object.keys(filled).forEach(function(to) { return sender(to, from, filled[to]);}); 19} 20function sender(to, from, arrObj) { 21 const subject = "[お知らせ] " + arrObj.map(function(c) { return c["B"]}).join(",") + " 期限について"; 22 const body = arrObj.map(function(c) { return c["C"]}).join(",") + "さん\n\nお疲れ様です。"; 23 GmailApp.sendEmail( 24 to, 25 subject, 26 body, { 27 from: from 28 } 29 ); 30} 31Date.prototype.toYYMMDD = function () { 32 return Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd"); 33}

投稿2019/11/04 16:10

papinianus

総合スコア12705

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

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

tanukichan

2019/11/05 00:04

詳細に教えていただきありがとうございます。 記載いただいたスクリプトで実際に実行してみましたが、 「TypeError: Cannot find function getDate in object 返却期限. (line 8, file "Code")」と表示されてしまう場合、spread sheet上の返却期限の記載フォーマットに問題があるのでしょうか? 何度もすみませんがよろしくお願いします。
papinianus

2019/11/05 14:57 編集

E列とF列で一桁の日付に0がつくかどうかが異なっているのですが、どちらも日付であって書式で表示を異ならせているのですよね? 質問でのエラーもそうなのですが、もしかしていわゆる全角文字をいれていたりしますか?メニューの書式で表示を変化させることが可能ですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問