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

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

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

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

Google Apps Script

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

Q&A

解決済

4回答

983閲覧

GASで最後の1行の処理ができない

退会済みユーザー

退会済みユーザー

総合スコア0

Google スプレッドシート

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

Google Apps Script

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

0グッド

2クリップ

投稿2023/09/08 09:04

実現したいこと

GASを用いて、スプレッドシート上で値が入力されている最後の行まで処理を行いたい。

前提

https://teratail.com/questions/tdhhsye5sh2cca
先日上記の質問をした者です。

いただいた回答で納得したつもりだったのですが、やっぱり思っていた挙動と違ったので、再質問させてください。

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

function QRSendMail(){ var sheetname = 'customer_list'; const spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetname); const lastRow = spreadsheet.getLastRow(); var rangeValues = spreadsheet.getDataRange().getValues(); for(var i=3 ; i<=lastRow ; i++){ var sending = rangeValues[i][0];

最初、上記のように書いていて、いただいた回答に従い、下記のように修正しました。(ifの条件内の=の削除)

function QRSendMail(){ var sheetname = 'customer_list'; const spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetname); const lastRow = spreadsheet.getLastRow(); var rangeValues = spreadsheet.getDataRange().getValues(); for(var i=3 ; i<lastRow ; i++){ var sending = rangeValues[i][0];

当初の「i<=lastRow」だと、前回の質問のようなエラーが出てしまうのですが、
「i<lastRow」だと、エラーが出ない代わりに最後の行の1つ上の行までしか処理されません。

4~21行に値が入っている時、4~20行が処理されます。

配列の考え方がなかなか理解できず情けないのですが、なるべく分かりやすい説明と解決策をいただけると幸いです。
宜しくお願いいたします。

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

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

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

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

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

pecmm

2023/09/08 09:48

質問文のソースが途中で途切れていますが、forブロック内の記載してない範囲でも i を用いた処理を何か記述されていますか? もしもそこでrangeValues配列にアクセスしたり、シート(spreadsheet変数)のメソッド呼び出しで i を使っているならば、インデックスがずれているせいで結果がおかしく見えているのかもしれません。 配列の添え字が0開始(処理範囲は3-20)、シート関数の行番号指定は1開始(処理範囲は4-21)となるので 全ての処理でそれらの整合性を取る必要があります。
退会済みユーザー

退会済みユーザー

2023/09/08 10:04

var dept2 = rangeValues[i][6]; のように、別の複数の列の値を取ったあとに、 if(dept2 != ''){ GmailApp.sendEmail(mail, title, text1, options); spreadsheet.getRange(i+1,2).setValue(today); } として、メールを送り、メールを送った日付を2列目の4行目以降のセルに入力するように、書いたつもりです!
pecmm

2023/09/08 10:27

申し訳ないですが、断片的なソースコードでは断片的な回答しかできません。 全文を質問文に追加すればよりよい回答が得られるかもしれません。 エラーが出ないのに部分的な処理しかできなかったのであれば、もしかすると自動メール送信の上限にひっかかっているかもしれません。(私は上限まで送ったことないので、エラーがでるのか単に処理が打ち切られるのか、どうなるのか把握していませんが……) 一時的に実際の処理(シート書き込みとかメール送信とか)をコメントアウトし代わりにconsole.log などにデバッグ出力して、どのデータに対してどんな処理がされる予定であったか確認してみれば分かりやすいかもしれません。
退会済みユーザー

退会済みユーザー

2023/09/08 10:40 編集

iを使っているのは、rangeValuesが[i][0]~[i][11]で複数列に並んでいるものと、 追記したspreadsheet.getRange(i+1,2).setValue(today)のみです。 何回か試して同じように最後の1行のみ処理されないため、メール送信数の上限は関係ないです。
YellowGreen

2023/09/08 20:06

G21のセルの値をご確認ください。 値が入力されていますか?
guest

回答4

0

19:50修正
質問へのコメントを見ての情報も追加して少し分かりやすくなるようにしてみました。
ループ内でB列にデータを書き込む処理を追加してあります。

提示されているコードを実行した結果です。
コードは実行できるよう}を追加しています。

JavaScript

1function QRSendMail(){ 2 3 var sheetname = 'customer_list'; 4 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetname); 5 const lastRow = spreadsheet.getLastRow(); 6 var rangeValues = spreadsheet.getDataRange().getValues(); 7 8 Logger.log(`lastRow = ${lastRow}`); 9 Logger.log(rangeValues); 10 11 for(var i=3 ; i<lastRow ; i++){ 12 var sending = rangeValues[i][0]; 13 Logger.log(`i = ${i} : sending = ${sending}`); 14 spreadsheet.getRange(i+1,2).setValue(`today${sending}`); 15 } 16}

実行前のスプレッドシート

イメージ説明

出力されたログ

19:42:05 お知らせ 実行開始
19:42:05 情報 lastRow = 21
19:42:05 情報 [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0], [7.0], [8.0], [9.0], [10.0], [11.0], [12.0], [13.0], [14.0], [15.0], [16.0], [17.0], [18.0], [19.0], [20.0], [21.0]]
19:42:05 情報 i = 3 : sending = 4
19:42:05 情報 i = 4 : sending = 5
19:42:05 情報 i = 5 : sending = 6
19:42:05 情報 i = 6 : sending = 7
19:42:05 情報 i = 7 : sending = 8
19:42:05 情報 i = 8 : sending = 9
19:42:05 情報 i = 9 : sending = 10
19:42:05 情報 i = 10 : sending = 11
19:42:05 情報 i = 11 : sending = 12
19:42:05 情報 i = 12 : sending = 13
19:42:05 情報 i = 13 : sending = 14
19:42:05 情報 i = 14 : sending = 15
19:42:05 情報 i = 15 : sending = 16
19:42:05 情報 i = 16 : sending = 17
19:42:05 情報 i = 17 : sending = 18
19:42:05 情報 i = 18 : sending = 19
19:42:05 情報 i = 19 : sending = 20
19:42:05 情報 i = 20 : sending = 21
19:42:07 お知らせ 実行完了

実行した結果のスプレッドシート

イメージ説明

ログを見てもらえば、配列の添え字と実際の行の関係が分かるのではないかと思います。

投稿2023/09/08 10:16

編集2023/09/08 10:50
YAmaGNZ

総合スコア10489

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

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

退会済みユーザー

退会済みユーザー

2023/09/08 10:28 編集

質問へのコメントで追記しているのですが、値を取得したのちにメールを送り、送った日付を記入する処理をしています。 そこの整合性が取れていないのかなと思われますが、どこが間違っているのか分からず困っています。
YAmaGNZ

2023/09/08 10:51

コメントにあったループ内の処理であろう spreadsheet.getRange(i+1,2).setValue(today); を追加して、結果のスプレッドシートを追記しました。
退会済みユーザー

退会済みユーザー

2023/09/09 11:47

ご回答ありがとうございましたmm
guest

0

(既にYAmaGNZさんも似たようなことを提案されていますが……)

js:確認のためのサンプルコード

1function test_QRSendMail(){ 2 var sheetname = 'customer_list'; 3 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetname); 4 const lastRow = spreadsheet.getLastRow(); 5 var rangeValues = spreadsheet.getDataRange().getValues(); 6 7 for(var i=3 ; i<lastRow ; i++){ 8 var sending = rangeValues[i][0]; 9 10 // 省略されている処理 11 12 console.log('dept2', dept2, dept2 != ''); // ※ここ 13 if(dept2 != '') { 14 //GmailApp.sendEmail(mail, title, text1, options); 15 console.log('GmailApp.sendEmail', mail, title, text1, options); // ※ここ 16 //spreadsheet.getRange(i+1,2).setValue(today); 17 console.log(`spreadsheet.getRange(${i+1},2), setValue ${today}`); // ※ここ 18 } 19 } 20}

一時的に実際の処理(シート書き込みとかメール送信とか)をコメントアウトし代わりにconsole.log などにデバッグ出力して、どのデータに対してどんな処理がされる予定であったか確認してみれば分かりやすいかもしれません。

少なくとも提示されている範囲では、dept2 の判定辺りが怪しいといえば怪しいです。

投稿2023/09/08 11:06

pecmm

総合スコア722

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

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

退会済みユーザー

退会済みユーザー

2023/09/09 11:27

ご回答いただきありがとうございましたmm
guest

0

配列が原因ではなかったと明言したらいいのではないですか?
ここまで引っ張っておきながら、プライバシーですか?
それを伏せて原因を説明すると思いますが、それをしないでおしまいにするのは、後味が悪いですね。
これまで考えて提案してしきた方のことをどのように考えているのでしょうか?

投稿2023/09/09 11:36

YellowGreen

総合スコア827

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

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

YellowGreen

2023/09/09 11:43

あなたが配列の処理がおかしいとタイトルに書いて、前回の回答が間違っているかのような質問をあげたので、皆さんあなたに配列を具体例を挙げて説明してきたのですよ。
退会済みユーザー

退会済みユーザー

2023/09/09 11:50 編集

煮詰まって書いていた部分を全て消して書き直したらうまくいきました。 正直なところ、質問に載せておらず消した部分のどこが悪かったのか、一番の原因は分からないままでしたが、 質問した部分は間違っていませんでしたと自己解決のところに記載しています。 考えて回答していただいた方々には感謝しております。 デバッグやログの見方を提案していただいたのは初心者の私にとって勉強にはなりましたが、 直接的な解決方法ではなかったためベストアンサーとしては選べませんでした。 配列が間違っていると思う、という私の質問であるのは確かですが、 載せている部分だけでは間違っているとは断定できないよ、というのが皆さんの総意であると受け取りました。 不快にさせてしまい申し訳ございません。 口論をしたいわけではないので、これ以上のコメントは控えさせていただきます。
YellowGreen

2023/09/09 11:50

当方もこれ以上コメントしたくありません。
YellowGreen

2023/09/09 12:00

上のコメントをこれ以上編集しないでください。
guest

0

ベストアンサー

自己解決できました、、

質問に載せていたiの設定は間違っておらず、
載せていなかった部分のコードを一部書き直し、一晩頭を冷やしたら解決できました。
質問しているのにプライバシーに関わりうると判断し載せられなかった部分なので、私が悪いです。
ちょっと煮詰まってしまっていたんだと思います;;

ご迷惑をおかけしました。回答やコメントをしていただいてありがとうございました。

投稿2023/09/09 11:23

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

YellowGreen

2023/09/09 11:40

こんな解決は悲しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問