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

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

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

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

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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

解決済

Googleフォームで申請・スプレッドシートに集約・Gmailに確認のメール送信と承認

退会済みユーザー

退会済みユーザー

総合スコア0

Google スプレッドシート

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

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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

1回答

0評価

0クリップ

701閲覧

投稿2022/04/26 08:16

編集2022/04/28 20:10

出張に関する承認フローをタイトルの流れで作成しようと思っています。
https://tonari-it.com/gas-workflow-url-parameter/
上記の方を参考にし、質問内容や行列の数値などを変更して作成しましたが、下記のようなエラーメッセージが出て実行できません。
『TypeError: Cannot read property 'parameter' of undefined
doGet @ コード.gs:2』
申請のフォームから集約するスプレッドシートを作成しており、上記のエラーが出るたびにコードを書き換えたり試してみたのですが、rangeやvalueやrowやparameterに関するところだけ同じエラーになっています。
大変恐縮ですが、どなたかお力添えいただきたく存じます。
よろしくお願いします。

作成したスクリプトは下記です。

function doGet(e) {
const row = e.parameter.row;
const sheet = SpreadsheetApp.getActiveSheet();
const values = sheet.getRange(row, 1, 1, 12).getValues()[0];
const bodies = generateBodies(values);
const answer = e.parameter.answer;
const result = {
ok: '承認',
ng: '否認'
};

sheet.getRange(row, 12).setValue(result[answer]);

const recipient = bodies.email;
const subject = 出張申請${result[answer]}のお知らせ;
let body = '';
body += 出張申請が${result[answer]}されました。\n\n;
body += bodies.plain;

let html = '';
html += <h1>出張申請${result[answer]}のお知らせ</h1>;
html += <p>以下の出張申請が${result[answer]}されました。</p>;
html += bodies.html;

GmailApp.sendEmail(recipient, subject, body, {htmlBody: html});
html = '';
html += <h1>出張申請の${result[answer]}</h1>;
html += <p>あなたは以下の出張申請を${result[answer]}しました</p>;
html += bodies.html;
return HtmlService.createHtmlOutput(html);
}

function generateBodies(values){
const [number,date,name,reason,organization,place,leeding,lodging,car,freeway] = values;

let plain = '';
plain += ・公文書番号: ${number}\n;
plain += ・日付: ${date}\n;
plain += ・名前: ${name} \n;
plain += ・主張理由: ${reason}\n;
plain += ・主催: ${organization}\n;
plain += ・出張場所: ${place}\n;
plain += ・引率: ${leeding}\n;
plain += ・宿泊: ${lodging}\n;
plain += ・交通手段: ${car}\n;
plain += ・高速の有無: ${freeway}\n\n;
let html = '<ul>';
html += <li>・公文書番号: ${number}</li>;
html += <li>・日付: ${date}</li>;
html += <li>・名前: ${name}</li>;
html += <li>・主張理由: ${reason}</li>;
html += <li>・主催: ${organization}</li>;
html += <li>・出張場所: ${place}</li>;
html += <li>・引率: ${leeding}</li>;
html += <li>・宿泊: ${lodging}</li>;
html += <li>・交通手段: ${car}</li>;
html += <li>・高速の有無: ${freeway}</li>;
html += '</ul>';
return {
email: email,
plain: plain,
html: html
};
}
function sendMessage(e) {

const row = e.range.getRow();
const sheet = e.range.getSheet();
sheet.getRange(row, 12).setValue('確認中');
const bodies = generateBodies(e.values);
let url = 'https://script.~';
url += ?row=${row}&answer=;

const recipient = '担当のメールアドレス';
const subject = '出張申請のお知らせ';
let body = '';
body += '以下の申請があります。\n\n';
body += bodies.plain;
body += '承認する場合は、以下URLをクリックしてください\n';
body += url + 'ok';
body += '否認する場合は、以下URLをクリックしてください\n';
body += url + 'ng';

let html = '';
html += '<h1>出張申請のお知らせ</h1>';
html += '<p>以下の申請があります。</p>';
html += bodies.html;
html += <p>承認する場合は、<a href="${url}ok">[承認]</a>をクリックしてください</p>;
html += <p>否認する場合は、<a href="${url}ng">[否認]</a>をクリックしてください</p>;

GmailApp.sendEmail(recipient, subject, body, {htmlBody: html});

}

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

qnoir

2022/04/26 09:24

そのエラー情報だけだと、どこで発生したエラーかが不明です。 TypeError: Cannot read property 'range' of undefinedのあとに続く数字や英文によって、その情報がわかる場合がありますので、エラーメッセージは省略せず全部記載してください。
退会済みユーザー

退会済みユーザー

2022/04/26 09:44

メッセージありがとうございます。 該当のエラーメッセージですが、全文を記載しました。また、コードを変更したり入れ替えたりする過程で別のものになっておりましたので、そこも変更しております。 旧『TypeError: Cannot read property 'range' of undefined』 ⇒新『TypeError: Cannot read property 'parameter' of undefined doGet @ コード.gs:2』 ご査収・手ほどきの程よろしくおねがいいたします。
qnoir

2022/04/26 11:30 編集

このエラー(TypeError: Cannot read property 'parameter' of undefined)が発生するのは、どのような操作を行ったときでしょうか? (もし、エディタ上でdoGet関数を実行したときにこのエラーが発生するというのならば、それは仕様であり、本来の使い方とは異なります)
退会済みユーザー

退会済みユーザー

2022/04/26 11:41

スプレッドシートの拡張機能にて、Apps Scriptから上記のコードをずらっと記入して、トリガーを作成し、実行した時にエラーとなります。 これが仰っているエディタ上でのdoGet関数実行にあたるのでしょうか?
qnoir

2022/04/26 11:53 編集

まず、今回エラーが出ているdoGet関数の正しい「呼び出し方」は、 ・フォームに投稿したときに送信されてくるメール内のURLをクリックする、 という動作です。 そのような動作を行ったときに「TypeError: Cannot read property 'parameter' of undefined doGet @ コード.gs:2」というエラーが発生しているのでしょうか? (ソースやトリガー設定が全部正しいのであれば、フォーム送信後に送られてくるメール内のURLをクリックすることで、doGet関数が自動的によびだされます。 それ以外の動作でdoGet関数を呼び出すことは、元記事でも想定されていません) )
退会済みユーザー

退会済みユーザー

2022/04/26 12:18

いいえおそらくそのような動作は行っていません。質問文のコードを全て一つにまとめてdoGet関数を選択し、実行しているので順番もあったものではないと思います。恥ずかしながら正しい手順を理解しないまま、コピペしております。
qnoir

2022/04/26 15:32 編集

零から作る場合の手順を記しました。 もしフォームの設定が終わっている場合は、⑩以降が参考になるかもしれません。 確認したところコード自体、一部修正しないとエラーになる部分がありますので追記しています。
退会済みユーザー

退会済みユーザー

2022/04/26 15:55

夜も遅いところを丁寧に詳しい手順まで記載いただき、ありがとうございます。ここ何日かずっと悩んでいたので、目から鱗でした。絶対に自分だけの発想では辿り着けなかったと思います。ありがとうございました。 明日職場で早速試してみようと思います。完成しましたら、また改めてご連絡させてください。
退会済みユーザー

退会済みユーザー

2022/04/27 07:52 編集

提示いただいた手順で実行したところ、「不明なエラーが発生しました。しばらく経ってからお試しください。」とでました。ずっと膠着状態だったので少し光明が見えた気がします。何度か試してみようと思います。 →しばらく経って全く新しいフォームから作ってみたところ「TypeError: Cannot read property 'parameter' of undefined doGet @ コード.gs:2」と最初と同じエラーが出ました。 別件ですが質問があります。 1、実行に移る際デバッグの隣の実行する関数についてはdoGetでいいのでしょうか? 2、トリガーをsendMessageを関数にして作成しましたが、doGetやgenerateBodiesのトリガーは作らなくていいのでしょうか? 3、引用元の方は8個の変数を代入しなければいけないところを、6個に分割代入しているように見えます。これは引用元の方も間違っているのでしょうか? お忙しいところ申し訳ございません。お手隙の時お返事いただければ幸いです。
qnoir

2022/04/27 11:30

> 最初と同じエラーが出ました。 フォームの送信時にそのエラーが出たということでしょうか? であればdoGetにトリガーを設定してしまっていませんか?doGetにフォーム送信時のトリガーを設定するのは間違いなので、もしそうであればトリガーを修正するか、削除してください。 > 1、実行に移る際デバッグの隣の実行する関数についてはdoGetでいいのでしょうか? →どれでも構いません。 デバッグの隣にあるドロップダウンに指定する関数は、エディタから直接関数を実行する場合に関係するものですが、本件はエディタから直接関数を実行する必要はないため、どの関数が選択されていようが影響はありません。 2、トリガーをsendMessageを関数にして作成しましたが、doGetやgenerateBodiesのトリガーは作らなくていいのでしょうか? →doGetやgenerateBodiesに対してトリガーを設定する必要はないです。もし設定していたらそれは間違いなので、そのトリガーは削除してください。 本件は、sendMessage関数に、「フォーム送信時」のトリガーを設定するだけでよいです。 > 3、引用元の方は8個の変数を代入しなければいけないところを、6個に分割代入しているように見えます。これは引用元の方も間違っているのでしょうか? →いいえ。 記事の最初の方にある、スプレッドシートの画像 ttps://tonari-it.com/wp-content/uploads/071-form-data-680x314.png を見るとわかりますが、フォームの回答を蓄積するシートの1列目に タイムスタンプ、メールアドレス、購買先、品名、単価、数量、Memo の7項目が並んでいます。 タイムスタンプは、フォームを作成すると1列目に必ず設定されます。 メールアドレスは、私の回答②のように、「メールアドレスを自動収集する」にチェックを入れると設定されます。 残り5つ(購買先、品名、単価、数量、Memo)はフォームを編集して作られた項目です。 申請者がフォームを送信すると、トリガーによって、sendMessage関数が自動的に呼ばれます。 sendMessage関数内の const bodies = generateBodies(e.values); のところで generateBodies 関数が呼ばれます。このとき、generateBodies関数の引数 e.values に フォーム送信者が回答した7つの回答項目が入っています。 そして generateBodies 内の const [number,date,name,reason,organization,place,leeding,lodging,car,freeway] = values; のところで、valuesの内容がそれぞれ代入されます。 ここで、分割代入は、前詰めで代入されるというルールがあるため valuesのうち、最後のmemoを除いた6つの項目が、左辺の各変数に(正常に)代入されます。 数の不一致自体は問題ありません(この点私の回答が誤解を生じる表現になっていたため修正します)
退会済みユーザー

退会済みユーザー

2022/04/27 23:08 編集

おそらく私はqnoil様が当初仰っていたような勘違いをしているのかもしれません。デバッグの隣の実行ボタンを押して、きちんと実行完了がされないと、この一連の動作が機能しないのかと思っていました。qnoil様の手順の後(新バージョンにしてデプロイを完了後)にこのスクリプトは完成しているため、後はフォームを送って動作を確認する、という流れでしょうか。 ⇒今朝、フォームを送信すると無事承認までできておりました。完全に私の勘違いで、振り回してしまい申し訳ございませんでした。qnoil様のおかげで誤っている個所や理解につながりました。本当にありがとうございました。
qnoir

2022/04/28 11:10

ご連絡ありがとうございます。解決したのであれば、ベストアンサーを選んでいただき、この質問をクローズしてください。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Google スプレッドシート

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

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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