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

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

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

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

Gmail

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

Google Apps Script

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

3回答

2272閲覧

GASでGmailの本文を分割してスプレッドシートに転記する方法

fuku-chann

総合スコア82

Google スプレッドシート

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

Gmail

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

Google Apps Script

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

1クリップ

投稿2020/05/02 14:45

編集2020/05/04 07:55

GASで特定のGmailをスプレッドシートに抜き出しています。
現在デバック中で本文を分割して表示させることを実施しています。

まず本文の中にある「ご予約名」を隣の列に抜き出すことを実施していますが、うまくいかなかったためご相談させていただきます。37行目のコードで本文が抜き出されますが、ここからご予約名を抜き出すことはできますでしょうか?

37 mymsg[i][4] = msgs[i][j].getPlainBody()

【調べたこと】
fetchDataが使えそうでしたが、いろいろ試しましたがエラーがでました。

下記コードはエラーでした。fetchDataは使えないのでしょうか?

mymsg[i][4] = fetchData(msgs[i][j].getPlainBody(),'ご予約','\r');

GAS

1function contact_Gmail() { 2 var rowNumber = 2; 3 var mysheetname = 'Gmail解析_' + Utilities.formatDate(new Date(), 'JST', 'yyyyMMddHHmmss'); 4 5 var GmailSS = SpreadsheetApp.create(mysheetname); 6 var mySheet = GmailSS.getSheets()[0]; 7 mySheet.setName(mysheetname); 8 mySheet.getRange(1,1).setValue("日時"); 9 mySheet.getRange(1,2).setValue("送信元"); 10 mySheet.getRange(1,3).setValue("件名"); 11 mySheet.getRange(1,4).setValue("本文"); 12 mySheet.getRange(1,5).setValue("ご予約"); 13 mySheet.getRange(1,6).setValue("お名前"); 14 mySheet.getRange(1,7).setValue("電話番号"); 15 mySheet.getRange(1,8).setValue("メールアドレス"); 16 17 var newfolder = DriveApp.createFolder(mysheetname); 18 19 var searchQuery = 'subject:(”予約が確定" OR "finalized") '; 20 var threads = GmailApp.search(searchQuery, 0, 200); 21 22 var mymsg=[]; 23 24 var msgs = GmailApp.getMessagesForThreads(threads); 25 26 for(var i = 0; i < msgs.length; i++) { 27 mymsg[i]=[]; 28 for(var j = 0; j < msgs[i].length; j++) { 29 mymsg[i][0] = msgs[i][j].getDate(); 30 mymsg[i][1] = msgs[i][j].getFrom(); 31 mymsg[i][2] = msgs[i][j].getSubject(); 32 var nbsp = String.fromCharCode(160); 33 mymsg[i][3] = msgs[i][j].getPlainBody().replace(/<("[^"]*"|'[^']*'|[^'">])*>|nbsp/g,'').replace(/&; | /g,'').substring(0,50000); 34 mymsg[i][4] = fetchData(mymsg[i][3],'Appointments:','Name'); 35 } 36 } 37 if(mymsg.length>0){ 38 GmailSS.getSheets()[0].getRange(2, 1, i, 4).setValues(mymsg); //シートに貼り付け 39 } 40} 41 42function fetchData(str, pre, suf) { 43 var reg = new RegExp(pre + '.*?' + suf); 44 var data = str.match(reg)[0] 45 .replace(pre, '') 46 .replace(suf, ''); 47 return data; 48}

2020年5月4日朝7時前の状況を添付します。(変数の値)
イメージ説明

2020年5月4日午後5時の状況を添付します。(変数の値)(同じコードで44行目までデバックしました)
イメージ説明

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

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

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

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

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

draq

2020/05/02 17:27

fetchData はどこに定義されているのでしょうか。標準で定義されている関数ではないと思います。
fuku-chann

2020/05/03 01:39

draq様 ご回答ありがとうございます。 根本的な部分が間違っているようでした。 定義追加しました。 いろいろ試していますが、まだエラーが復旧されません。。。 コードの意味が理解できていませんので、修正とともに勉強させていただきたく、ご教示お願いします。
draq

2020/05/03 04:47

eneko0513さんの追記された回答(変数名sheetが間違ってる)で解決しそうですが、DateString関数も再確認した方がいいです。 今の実装だと月日時分秒が1桁の場合に期待とは違う出力になってそうです。例えば、 console.log(DateString(new Date("2020-12-01T01:11:01"))); //20201111111 console.log(DateString(new Date("2020-02-01T11:01:11"))); //20201111111 とかやって確認してみてください。2つの日時は違うの出力は同じになります。 あとJavaScriptの昔からある罠ですが Date.getMonth() は実際の月-1を返すことも注意です。 (例えば5月の場合、Date.getMonth()は4を返します。) 以上の問題を避ける意味でも、GASでは日付のフォーマットは Utilities.formatDate() を利用することをおすすめします。
fuku-chann

2020/05/03 06:16

draq様 ご回答ありがとうございます。 ご指摘の通り不備がありそうなので、Utilities.formatDate()に変更したいのですが、使ったことがないため調べてコーディングしましたが、エラーが出てしまいます。今回のコードにどのように適応すればよいかがわからないため、ご教示いただきたく、よろしくお願いします。(コード更新しました)
draq

2020/05/03 06:47

エラーが出てしまいました、ではなくどんなエラーか正確にコピペしてください。
fuku-chann

2020/05/03 07:02

draw様 ご回答ありがとうございます。 説明不足ですみません。下記のエラーが出ています。 SyntaxError: Unexpected token '{'(行 41、ファイル「コード.gs」) コードは mymsg[i][4] =...を追加する前の問題のないバージョンを使用しています。そのため、本件のみ変更したので他のエラーはないはずです。
draq

2020/05/03 07:28

メッセージの通り文法間違い(SyntaxError)です。
guest

回答3

0

DateStringの代わりにUtilities.formatDateを使うというのは、DateStringをバッサリ削除して
Utilities.formatDateを呼び出すということです。

JavaScript

1// var mysheetname = 'Gmail解析_' + DateString(new Date()); 2var mysheetname = 'Gmail解析_' + Utilities.formatDate(new Date(), 'JST', 'yyyyMMddHHmmss'); 3

投稿2020/05/03 07:27

draq

総合スコア2573

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

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

fuku-chann

2020/05/03 07:41

draq様 ご回答ありがとうございます。 感動です。作成日が正しく表示されました。
guest

0

下記のサイトを参考にした感じではこの関数が不足しているからではないでしょうか?

GASでフォーム送信メールからデータを取得してスプレッドシートに蓄積するツールの完全版

GAS

1function fetchData(str, pre, suf) { 2 var reg = new RegExp(pre + '.*?' + suf); 3 var data = str.match(reg)[0] 4 .replace(pre, '') 5 .replace(suf, ''); 6 return data; 7}

// 2020/05/03 追記
頂いた情報を見た所、エラーの内容はsheet というものが存在しないというのがまず1つ出ていますね。
ご自身のソースを見ると sheet というオブジェクトに行を追加しようとしていますがそれが存在しないためエラーになっていそうです。

今回であれば

GAS

1 var mysheetname = 'Gmail解析_' + DateString(new Date()); 2 3 var GmailSS = SpreadsheetApp.create(mysheetname); 4 var mySheet = GmailSS.getSheets()[0];

このあたりが怪しいですね。
追加しようとしているシートのオブジェクトはどれでしょうか・・?
なのでsheetという名前を該当のシートのオブジェクトの変数に変えてみると結果が変わるかもしれません。(mySheetが今回はあたりかな・・?)

// 追記2
mymsg[i][4]を追加したこととなにか関係があるかでいうとあると思います。

GAS

1 sheet.appendRow([ 2 mymsg[i][4] = fetchData(mymsg[i][3],'Appointment:','\r'), 3 id 4 ]);

ここでappendRowをしていますよね。
このときに追加対象となるsheet情報が無いからエラーになっていると推測しています。

ReferenceError.sheet is not defined(行34、ファイル「コード」)

再度切り分けです。
・これがなければ正常に動く という点においての「これ」は何を指しますか?
34行目自体が無いこと? mymsg[i][3] までは取得できていて[i][4]を追加したら駄目ということ?
・fetchData関数に到達していますか?
・Logger関数などで正しくmymsg[i][3]までが表示されることは確認していますか
・わたしの前コメントで書いた内容にした時にエラーは変わりましたか

fetchDataに関してはわたしは動作確認はしていないのでまったくないとは言い切れませんが
エラーの内容を見るにその関数の中に到達できていないのではないかと思っています。

エラーの要因で現時点でぱっと思いつくのは下記ですよね
・msgs[i][3]の中身がおかしい
・fetchData関数の中身がおかしい
・fetchData関数を呼び出す前のsheet.appendRow()がおかしい

確認のためLogger.logを仕込んで(下記のようなイメージ)到達しているか確認して下さい。
Logger.logの確認方法については基本的な所なのでご存知なければ検索してみて下さい。

GAS

1 for(var j = 0; j < msgs[i].length; j++) { 2 mymsg[i][0] = msgs[i][j].getDate(); 3 mymsg[i][1] = msgs[i][j].getFrom(); 4 mymsg[i][2] = msgs[i][j].getSubject(); 5 var nbsp = String.fromCharCode(160); 6 mymsg[i][3] = msgs[i][j].getPlainBody().replace(/<("[^"]*"|'[^']*'|[^'">])*>|nbsp/g,'').replace(/&; | /g,'').substring(0,50000); 7 Logger.log("start"); 8 sheet.appendRow([ 9 mymsg[i][4] = fetchData(mymsg[i][3],'Appointment:','\r'), 10 id 11 ]); 12 Logger.log("end"); 13 }

GAS

1function fetchData(str, pre, suf) { 2 Logger.log("fetchDataStart"); 3 var reg = new RegExp(pre + '.*?' + suf); 4 Logger.log("fetchData_reg"); 5 var data = str.match(reg)[0] 6 .replace(pre, '') 7 .replace(suf, ''); 8 Logger.log(data); 9 return data; 10}

追記
ちょっとかかりすぎてしまったので今回が最後の回答にさせて下さい。
idは不要です、それも次のエラーになる内容です。(いまはその前で止まっている)

シンプルに切り分けしましょう。
わたしのほうでもらったmymsg[i][3]のテキストを変数に入れてfetchDataで処理したら
dataの中に該当の文字列は取れていました。
イメージ説明
あとは格納の仕方とかを見直して見て下さい。

何もわからずappendrowしているならなおさら消して下さい。

GAS

1 sheet.appendRow([ 2 mymsg[i][4] = fetchData(mymsg[i][3],'Appointment:','\r'), 3 id 4 ]); 56 mymsg[i][4] = fetchData(mymsg[i][3],'Appointments:','Name');

で一度内容を見てください。

投稿2020/05/02 18:53

編集2020/05/03 09:06
eneko0513

総合スコア349

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

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

fuku-chann

2020/05/03 01:40

testnow様 ご回答ありがとうございます。 根本的な部分が間違っているようでした。 定義追加しました。 いろいろ試していますが、まだエラーが復旧されません。。。 コードの意味が理解できていませんので、修正とともに勉強させていただきたく、ご教示お願いします。
eneko0513

2020/05/03 02:27

エラーという情報だけだと具体的にどのような状態なのかがわかりません。 原因の切り分けをする必要があると思います。 ・具体的なエラーのメッセージ文は何なのか ・mymsg[i][2] = msgs[i][j].getSubject(); var nbsp = String.fromCharCode(160); mymsg[i][3] = msgs[i][j].getPlainBody().replace(/<("[^"]*"|'[^']*'|[^'">])*>|nbsp/g,'').replace(/&; | /g,'').substring(0,50000); sheet.appendRow([ mymsg[i][4] = fetchData(mymsg[i][3],'Appointment:','\r'), とありますが、mymsg[i][4]以外の所は正しく値が取れていますか? 特にmymsg[i][3]の値を今回用いて[4]としているようなので[3]の時点で意図しない結果になっていませんか? 関数自体は正規表現で元のhtmlテキスト(str)から指定した先頭文字(pre)と末尾文字(suf)にの間のテキストデータを取得するものと思います。 わたしが前回答で記載したページに関数の説明がありました。 必要であれば情報の追加をお願いします。
fuku-chann

2020/05/03 02:59

testknow様 ご回答ありがとうございます。 説明不足ですみません。 [3]の時点では問題ありません。[4]を追加するとエラーになります。 エラー内容:ReferenceError.sheet is not defined(行34、ファイル「コード」) 行34はmymsg[i][4]...の行です。
fuku-chann

2020/05/03 04:38

eneko0513様 ご回答ありがとうございます。 sheetが存在していないとありますが、mymsg[i][4]を追加したこととなにか関係があるのでしょうか? これがなければ正常に動きますので、fetchData周辺のコードのどこかに間違いがあるように思いますが、いかがでしょうか?
eneko0513

2020/05/03 05:12

追記しました。 どこまで動作確認をされたのかわからないので断言はできません。 fetchData関数の処理中にエラーが発生していることは確認できていますか?
eneko0513

2020/05/03 05:23

そもそもAppendRowの中で変数代入ってできない気がしますね・・。 sheet.appendRow([ fetchData(mymsg[i][3],'Appointment:','\r'), id ])
draq

2020/05/03 05:29

難しく考えすぎです。 エラーメッセージにあるように変数 sheet が未定義なだけでは? 多分 sheet ではなく mySheet に直すだけだと思います。 > sheetが存在していないとありますが、mymsg[i][4]を追加したこととなにか関係があるのでしょうか? > これがなければ正常に動きますので それはここ以外で変数 sheet を使ってないからです。
eneko0513

2020/05/03 05:32

同じくそう思っています・・。
fuku-chann

2020/05/03 05:52

draq様、eneko0513様 ご回答ありがとうございます。 mySheetに修正することで一歩前進できました。 しかし、まだ後半の56行目に問題があるようです。(var data = str.match(reg)[0]) TypeError: Cannot read property '0' of null (行56、ファイル「コード」) []の中の数値を0~5まで試しましたがどれもエラーになりました。 ここの[]はどのような意味なのでしょうか?
eneko0513

2020/05/03 06:03

前進ということで良かったです。 とりあえず先に言いたいのはまず言われた内容を試してから回答しましょう。 mySheetに変えたらという所のインプットはしているわけですしそこを試さずに なにか関係があるのか?というのは些か失礼かと思います、原因の切り分けにもならないですし。 今回のエラーの内容をそのままコピーするだけでも解説はたくさんでてきますよ。 → JavaScriptでよく見るエラーとその対策 https://sbfl.net/blog/2019/02/01/javascript-error-messages/ 質問主さんは配列とかをあまりご存知ないとお見受けしますので一つずつ検索しつつで対応して見て下さい。 今回のstr.match(reg)[0]でいうと、それは条件に該当した一番最初の要素をdataに入れるという意味になります。 ただ今回は、該当した値が1つも無いため存在しない要素を格納しようとしてエラーになっています。 fetchDataに渡している条件の見直しか、fetchDataの処理に問題があるかを切り分けて行く必要があります。
fuku-chann

2020/05/03 06:36

eneko0513様 ご回答ありがとうございます。 私の理解力不足と作業が間に合っていないことも重ねてご迷惑をおかけしております。 一応配列そのものは知っていますが、この辺りのコードが何を示しているのかが理解できていないと思います。 行34はmymsg[i][4]...の行を追加すると、なぜ該当する値がなくなるのでしょうか?
eneko0513

2020/05/03 06:45

mySheet.appendRow([ mymsg[i][4] = fetchData(mymsg[i][3],'Appointment:','\r'), id ]); これの処理の順番はわかりますか? > mymsg[i][4]...の行を追加すると、なぜ該当する値がなくなる おそらくfetchData関数の中には到達しているのですよね。 そこの条件にマッチしないからエラーになっています。 エラーになっている原因はなんでしょうか ・わたしているデータの内容が悪い ・fetchData関数の処理側の問題 ここの切り分けが必要という意味です。(ここはご自身じゃないと判断できないです) msg[i][3]は本当に条件に合致する内容が入っていますか。
fuku-chann

2020/05/03 07:30

eneko0513様 ご回答ありがとうございます。 エラー表示は変わりませんが、一点スペルミスがありました。(appointmentには最後にsが付きます) mymsg[i][4] = fetchData(mymsg[i][3],'Appointments:','\r'), mymsg[i][3]は該当のメールが正しく表示されているので間違いないと思っています。
eneko0513

2020/05/03 07:39 編集

メール本文の中で Appointments: [何かしらの文章] の所はありますか。 正規表現にマッチしていないのがエラーの原因だと思いますのでそのあたり見てみて下さい。
fuku-chann

2020/05/03 07:53

eneko0513様 ご回答ありがとうございます。 実はAppointmentsの後は空白で改行された次の行を抜き出したいのですが、AppointmentsからNameに変えても同様のエラーが表示されるので、これが問題ではないと思っています。 メール本文を下記に記載します。 When you send the email, the reservation will be finalized. Appointments: - 04/28/2020 08:30-11:00 (+ USB port expansion) Name: ふく Phone number: 090-8765-4321
eneko0513

2020/05/03 07:59

- 04/28/2020 08:30-11:00 (+ USB port expansion) とりあえずここを取れればいいってことですか? fetchData(mymsg[i][3],'Appointment:','Name'), にするとどうなりますか? fetchDataの引数は元テキスト、正規表現のパターンの始点、終点 だと思うので \rの改行コードを指定すると一行目の空を取得してしまっているのではないかと思っています。
fuku-chann

2020/05/03 08:47

eneko0513様 ご回答ありがとうございます。 そうです。とりあえず下記を取得したいです。 - 04/28/2020 08:30-11:00 (+ USB port expansion) 下記コードに変更しましたが、同様のエラーが発生してしまいます。 mymsg[i][4] = fetchData(mymsg[i][3],'Appointments:','Name:'), TypeError: Cannot read property '0' of null(行 47、ファイル「コード」) すぐ下にidというコードがありますが、これは問題ないでしょうか?
eneko0513

2020/05/03 09:06

最後の追記です。
fuku-chann

2020/05/03 09:19

eneko0513様 ご回答ありがとうございます。 コード修正しましたが、依然とエラーが修復されない状況が続いております。 SyntaxError: Unexpected token '}'(行 35、ファイル「コード.gs」)
eneko0513

2020/05/03 09:30

末尾の,が間違えています。 ;です このあたりにはご自身で見て気づいてほしいです・・。
fuku-chann

2020/05/03 09:52

eneko0513様 ご回答すみません。 コード修正しましたが、同様のエラーが継続されます。 TypeError: Cannot read property '0' of null(行 44、ファイル「コード」)
guest

0

自己解決

お世話になっております。
量指定子の問題でした。
'.*?'から'[^"]+'に変更することで問題が解決されました。
ご教示いただきありがとうございました。

GAS

1function contact_Gmail() { 2 var rowNumber = 2; 3 var mysheetname = 'Gmail解析_' + Utilities.formatDate(new Date(), 'JST', 'yyyyMMddHHmmss'); 4 5 var GmailSS = SpreadsheetApp.create(mysheetname); 6 var mySheet = GmailSS.getSheets()[0]; 7 mySheet.setName(mysheetname); 8 mySheet.getRange(1,1).setValue("日時"); 9 mySheet.getRange(1,2).setValue("送信元"); 10 mySheet.getRange(1,3).setValue("件名"); 11 mySheet.getRange(1,4).setValue("本文"); 12 mySheet.getRange(1,5).setValue("ご予約"); 13 mySheet.getRange(1,6).setValue("お名前"); 14 mySheet.getRange(1,7).setValue("電話番号"); 15 mySheet.getRange(1,8).setValue("メールアドレス"); 16 17 var newfolder = DriveApp.createFolder(mysheetname); 18 19 var searchQuery = 'subject:("finalized") '; 20 var threads = GmailApp.search(searchQuery, 0, 200); 21 22 var mymsg=[]; 23 24 var msgs = GmailApp.getMessagesForThreads(threads); 25 26 for(var i = 0; i < msgs.length; i++) { 27 mymsg[i]=[]; 28 for(var j = 0; j < msgs[i].length; j++) { 29 mymsg[i][0] = msgs[i][j].getDate(); 30 mymsg[i][1] = msgs[i][j].getFrom(); 31 mymsg[i][2] = msgs[i][j].getSubject(); 32 var nbsp = String.fromCharCode(160); 33 mymsg[i][3] = msgs[i][j].getPlainBody().replace(/<("[^"]*"|'[^']*'|[^'">])*>|nbsp/g,'').replace(/&; | /g,'').substring(0,50000); 34 mymsg[i][4] = fetchData(mymsg[i][3],'Appointments:','Name:'); 35 } 36 } 37 if(mymsg.length>0){ 38 GmailSS.getSheets()[0].getRange(2, 1, i, 5).setValues(mymsg); //シートに貼り付け 39 } 40} 41 42function fetchData(str, pre, suf) { 43 var reg = new RegExp(pre + '[^"]+' + suf); 44 var data = str.match(reg)[0] 45 .replace(pre, '') 46 .replace(suf, ''); 47 return data; 48}

投稿2020/05/04 12:08

fuku-chann

総合スコア82

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

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

eneko0513

2020/05/04 12:20

解決とのことでよかったです。 ただ、自己解決のような扱いにされていますがdraqさんや私の意見もあった上で 完成できている部分もある程度はあると思っています。 fetchDataの定義もなかった時点からアドバイスで徐々に進んでいっているわけですし。 ベストアンサーをつけろというわけではありませんがちゃんとそのあたりはしてほしいです。 役立っていた回答なら高評価をつけるというルールもありますし。 私個人がポイントがほしいとかではなく仁義の点のご指摘です。 特にfuku-channさんは私が添付した画像を使用して別の質問を作成されていたりしますよね? そのあたりの礼節を欠くようなことはしないでほしいです。 とりあえず解決したとのことでおめでとうございました。
fuku-chann

2020/05/04 12:33

eneko0513様 確かにその通りですね。 とても勉強になり感謝しております。 添付資料の件はすみませんでした。
eneko0513

2020/05/04 12:38

とりあえずわたしの回答が約だったのであれば評価お願いします。
fuku-chann

2020/05/04 12:41

eneko0513様 +2にしたかったのですが、+1が最大のようです。 気持ちは+2以上です。 ありがとうございました。
eneko0513

2020/05/04 12:43

お疲れ様でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問