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

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

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

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

ドキュメント

ドキュメントは、IT用語では、ソフトウェアやハードウェアに関する情報であり、意図された目的、機能性、メインテナンスを含みます。ドキュメントは、多くの様々なフォームとフォーマットに存在しますが、その目的は常に教育することにあります。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

Q&A

解決済

1回答

836閲覧

スプレッドシートの最終行の値をドキュメントでreplaceする

sactac

総合スコア2

Google スプレッドシート

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

ドキュメント

ドキュメントは、IT用語では、ソフトウェアやハードウェアに関する情報であり、意図された目的、機能性、メインテナンスを含みます。ドキュメントは、多くの様々なフォームとフォーマットに存在しますが、その目的は常に教育することにあります。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

0グッド

0クリップ

投稿2021/02/23 11:03

前提・実現したいこと

初心者です。
自社(工場)で故障が起きた際に、作業者がFORMを送信。それをトリガーにして、複数のメールアドレスに自動メールが行くような仕組みをつくろうとしています。
メール本文に故障の場所や設備種類などFORMで回答したいくつかの事項を織り込んだメールにしたいのですが…。また送付先の複数メールアドレスは、スプレッドシートにメアドのリストを対象としています。

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

var factory = rangeValues2[LastRow][4];//工場
という行で、下記のエラーが出ます。

TypeError: Cannot read property '4' of undefined

該当のソースコード

GAS

1function sendMail() { 2 3 //故障報告がされたら、自動でリストにあるメアドへ通知メールを送る 4 5 // Googleドキュメントからメールの件名と本文を取得 6 var doc = DocumentApp.openById('XXX'); 7 var subject = doc.getName(); 8 var text = doc.getBody().getText(); 9 10 // Googleスプレッドシートからデータ取得 11 12 var ss = SpreadsheetApp.openById("ZZZ"); 13 //var spreadsheet = SpreadsheetApp.getActive(); 14 15 var sheet2 = ss.getSheetByName('故障報告');//故障報告シートを定義 16 var range2 = sheet2.getDataRange();//該当シートのデータ範囲を取得 17 var rangeValues2 = range2.getValues();//取得したデータ範囲の配列を取得 18 var LastRow = range2.getLastRow();//データ範囲の最終行を取得 19 20 var factory = rangeValues2[LastRow][4];//工場 21 var type = rangeValues2[LastRow][5];//設備種類 22 var reporter = rangeValues2[LastRow][3];//報告者メアド 23 var datetime = rangeValues2[LastRow][2];//報告日時(タイムスタンプ 24 var status = rangeValues2[LastRow][13];//状態 25 var demand = rangeValues2[LastRow][16];//要求 26 27 var replacedText = text.replace('{工場}',factory).replace('{設備種類}',type).replace('{報告者メアド',reporter).replace('{タイムスタンプ}',datetime).replace('{要求}',demand); 28 29 30 var sheet = ss.getSheetByName('故障通知メアド'); 31 var range = sheet.getDataRange(); 32 var rangeValues = range.getValues(); 33 34 for(var i = 1; i < rangeValues.length; i++) { 35 var name = rangeValues[i][0]; 36 var position = rangeValues[i][1]; 37 var email = rangeValues[i][2]; 38 39 var replacedText = text.replace('{氏名}', name).replace('{役職}', position); 40 41 MailApp.sendEmail(email, subject, replacedText);

試したこと

始めたばかりで、分からないことだらけですが、自分なりにネットでいろいろ探してみたのですが…。
お恥ずかしいような初歩的なことな気がしていますが、職場にも友人にも詳しい人がおらず、独学でやるしかない状況です。どうかよろしくお願いします。

補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

sawa

2021/02/24 00:39

解決された場合は、「解決済み」としましょう。
sactac

2021/02/24 00:45

すみません、いまやりました。 初めてで使い方がわからなくて、教えていただきありがとうございます。
guest

回答1

0

ベストアンサー

コードの中でセルを(配列で)指定する場合、行の始まり、列の始まりはゼロからスタートします。

たとえば、1行目、1列目を指定する場合は、
rangeValues2[1][1] ではなく、それぞれ1を引いて
rangeValues2[0][0]
としなければなりません。

同じように、10行目、4列目を指定する場合は、
rangeValues2[9][3]
と書く必要があります。


【現状】
「故障報告」シートに、たとえば10行まで入力済みの状態で。sendMailを実行すると、

var rangeValues2 = range2.getValues();//取得したデータ範囲の配列を取得 var LastRow = range2.getLastRow();//データ範囲の最終行を取得

の段階で、
・rengaValues2は、10行×16列のデータの塊(配列)になっており
・LastRowには10が代入されています。

次に

var factory = rangeValues2[LastRow][4];//工場

というように、 rangeValues2[10][4] にアクセスしようとしていますが、
これは実際には11行目 5列目のデータを取得する意味になり、10行までしかないrangeValuesの範囲を超えているため、エラーになってしまいます。

ですから、コード上は、指定する行・列の数字から1を引かなければなりません。

【修正】
アクセスする行・列の数値を1引きます。

diff

1(略) 2 var sheet2 = ss.getSheetByName('故障報告');//故障報告シートを定義 3 var range2 = sheet2.getDataRange();//該当シートのデータ範囲を取得 4 var rangeValues2 = range2.getValues();//取得したデータ範囲の配列を取得 5+ var LastRow = range2.getLastRow() - 1; //データ範囲の最終行を取得(1を引く) 6+ var factory = rangeValues2[LastRow][3];//工場 7+ var type = rangeValues2[LastRow][4];//設備種類 8+ var reporter = rangeValues2[LastRow][2];//報告者メアド 9+ var datetime = rangeValues2[LastRow][1];//報告日時(タイムスタンプ 10+ var status = rangeValues2[LastRow][12];//状態 11+ var demand = rangeValues2[LastRow][15];//要求 12(略)

投稿2021/02/23 11:57

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

sactac

2021/02/23 12:12

ありがとうございます!!解決しましたーーー(TT 配列はゼロからと教わっていたのに、列番号ばかりに気を取られて、行の方は忘れていました。 本当に助かりました、できて感動です。 また何かございましたら、お助けくださいm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問