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

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

新規登録して質問してみよう
ただいま回答率
85.45%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

Q&A

解決済

2回答

613閲覧

GASのfor文で繰り返すと1回目で時間フォーマットが合わないとエラーになる

manmosu

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

0グッド

0クリップ

投稿2023/03/28 07:28

実現したいこと

当日の日付にあった当番をSlackに通知する

詳細

スプレッドシートに記載してある「日付」「名前」「当番内容」「担当時間」から、日付が当日の日付とマッチした場合にSlackに通知するbotをつくっています。

2023/03/28 さとう そうじ 9:00
2023/03/29 たなか せんたく 10:00
2023/03/28 いとう せんたく 11:00

上記のようなデータがスプレッドシートにあり、当日の日付が「2023/03/28」の場合、Slackには2行通知されるとおもいますが、「Utilities.formatDate」の「"JST","HH:mm"」と指定しているとエラーになります。
フォーマットを指定しない場合エラーはでませんが、下記のように2行目だけが正常に通知され1行目はフォーマットされてないデータでSlack通知されてしまいます。

2023/03/28 さとう そうじ Sat Dec 30 1899 09:00:00 GMT+0900 (Japan Standard Time)
2023/03/28 いとう せんたく 11:00

1行目も2行目も正しい時間表記で通知するにはどうしたら良いのでしょうか?

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

エラーメッセージ Exception: The parameters (String,String,String) don't match the method signature for Utilities.formatDate.

該当のソースコード

GAS

1function myFunction() { 2 3 var webhook = "https://hooks.slack.com/xxxxxx"; 4 5 var today = new Date(); 6 var date = today.getFullYear() + '年' +(today.getMonth() + 1) + '月' + today.getDate() + '日'; 7 8 var spread_sheet = SpreadsheetApp.openByUrl('https://docs.xxxxxxxxxxxxx'); 9 var target_sheet = spread_sheet.getSheetByName("xxxxxxxxxxxxx 10 var data_arrays = target_sheet.getDataRange().getValues(); 11 var message = ""; 12 var num=0; 13 14 data_arrays.forEach(function( data_array ){ 15 cell_date = new Date(data_array[0]); 16 if(cell_date.getFullYear() == today.getFullYear() && cell_date.getMonth() == today.getMonth() && cell_date.getDate() == today.getDate()) 17 { 18 for (var i = 1; i <= 1; i++) { 19 start_time = data_array[0*i]; //日付 20 start_time2 = data_array[1*i]; //なまえ 21 start_time3 = data_array[2*i]; // 掃除内容 22 start_time4 = data_array[3*i]; // 時間 23 if(start_time != ""){ 24 time_text = start_time 25 message += Utilities.formatDate(start_time,"JST","MM/dd") + start_time2 + start_time3 + Utilities.formatDate(start_time4,"JST","HH:mm") + "\n"; 26 } 27 } 28 num++; 29 return false; 30 } 31 }) 32 33 var jsonData = {"username": "おしらせbot", "text": message}; 34 var payload = JSON.stringify(jsonData); 35 var options = 36 { 37 "method" : "post", 38 "contentType" : "application/json", 39 "payload" : payload 40 }; 41 42 // 1件もない時は通知しない処理をいれる 43 if ( num != 0 ) { 44 UrlFetchApp.fetch(webhook, options); 45 } 46}

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

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

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

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

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

guest

回答2

0

ベストアンサー

当初の回答に修正を加えました。

--<当初の回答>--

forEachの中なので、
for(;;)ループはいらないと思います。

そして、ver i も不要なので配列インデックスは、
そのまま0,1,2,3として、

javascript

1start_time = new Date(data_array[0]); 2start_time2 = data_array[1]; 3start_time3 = data_array[2]; 4start_time4 = new Date(data_array[3]);

と日付、時刻は一度オブジェクトにしてから代入しましょう。

for (var i = 1; i <= 1; i++) {
の行とfor(;;)ループを閉じる
}
の行を削除します。

(iPhoneからなので、回答が整形できてるか確認できませんが)

オブジェクトにすると、何かしらの日付になるので、

javascript

1if(start_time != ""){ 2 time_text = start_time 3 message += Utilities.formatDate(start_time,"JST","MM/dd") + start_time2 + start_time3 + Utilities.formatDate(start_time4,"JST","HH:mm") + "\n"; 4}

のところも、if文を外して、
使っていないのなら、
time_text = start_time
の行も削除しましょう。

--<以降は回答の追加です。>--

まず、日付、時刻の全角入力やセミコロンの入力を訂正して日付オブジェクトを生成する補助関数を
myFunctionの前か後に保存します。

javascript

1//日付、時刻の文字列から日時のオブジェクトを返す 2function genDate(_date) { 3 if (Object.prototype.toString.call(_date) != "[object Date]") { 4 //日付オブジェクトでない→セミコロン、全角数字を修正 5 _date = _date.toString().replace(/[:;;]/g, ":"); 6 _date = _date.replace(/[0-9]/g, s => String.fromCharCode(s.charCodeAt(0) - 0xFEE0)); 7 //'22:22'→'1989/12/30 22:22:00' 8 var hhmm = /^\d+:\d+$/; 9 if (hhmm.test(_date)) { 10 _date = "1899/12/30 " + _date + ":00"; 11 } 12 return new Date(_date); 13 } else { 14 //日付オブジェクトならそのまま返す 15 return _date; 16 } 17}

そしてforEach文をこれに合わせて修正します。

javascript

1 data_arrays.forEach(function (data_array) { 2 var cell_date = genDate(data_array[0]);//日付 3 if (cell_date.getFullYear() == today.getFullYear() && 4 cell_date.getMonth() == today.getMonth() && 5 cell_date.getDate() == today.getDate()) { 6 start_time = cell_date; 7 start_time2 = data_array[1];//なまえ 8 start_time3 = data_array[2];//掃除内容 9 start_time4 = genDate(data_array[3]);//時刻 10 message += Utilities.formatDate(start_time, "JST", "MM/dd") + 11 start_time2 + start_time3 + 12 Utilities.formatDate(start_time4, "JST", "HH:mm") + "\n"; 13 num++; 14 // return false;//←この行は不要 15 } 16 })

最後に不要な行がもう一つありましたので、削除(コメントに)します。

javascript

1 // var date = today.getFullYear() + '年' + (today.getMonth() + 1) + '月' + today.getDate() + '日';

以上で、日付、時刻に全角数字など不用意な入力があっても、ある程度は対応できるようになります。

投稿2023/03/28 09:04

編集2023/03/28 12:45
YellowGreen

総合スコア731

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

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

manmosu

2023/03/28 10:50

フォーマットの形成とループを正しくしたら解決しました。 大変助かりました。ありがとうございます!
YellowGreen

2023/03/28 10:54

あと、日付や時刻を質問者さんだけが入力しているのなら問題ないと思いますが、いろんな方が入力する場合は、どうしても時刻にセミコロンを使ったり、数字を全角で入力したりということが起きます。 そのような場合に対応できるスクリプトの修正例をお示ししたいのですが、しばらく後になると思います。
YellowGreen

2023/03/28 12:48

修正をアップしました。
guest

0

スプレッドシートに記載している「担当時間」の具体値の型が文字列になっているのではないでしょうか。

投稿2023/03/28 07:33

arcxor

総合スコア2859

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

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

manmosu

2023/03/28 07:38

ご回答ありがとうございます。表示形式を時間にしても、書式なしテキストなどにしてみても、エラーが解消しない状況でした。
arcxor

2023/03/28 08:02

表示形式を時間にした際の実際のセルに表示された内容をご提示ください。
manmosu

2023/03/28 08:45

時:分で表示形式を時間にして、実際のセルには「9:00」「10:00」「11:00」と表示されています。
manmosu

2023/03/28 10:49

yellowgreenさんの回答にて、フォーマットの形成とループを正しくしたら解決しました。ご回答いただきありがとうございました!助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問