🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Apps Script

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

4678閲覧

GASでドライブ内のJsonファイルから抽出したり、データを仕分けたりしたい

tatsu3

総合スコア11

Google Apps Script

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/10/14 12:17

相変わらず素人まる出しの質問で大変恐縮です。

気象庁が発表する「震源・震度に関する情報」というXML電文を、Google Apps Scriptで必要なデータだけ抜き出した上でJSONファイル化し、Google Driveに蓄積保存する仕組みを、試行錯誤しながら作りました。

このような感じで保存されています。

{"EventID":"20190901035701", "OriginTime":"2019/09/01 03:56:00", "HypoName":"◯◯沖", "HypoCode":"+35.8+140.9-30000/", "Magnitude":"3.3", "Intensity":[{"PrefName":"◯◯県", "CityName":"◯◯市", "MaxInt":"3"}, {"PrefName":"△△県", "CityName":"△△市", "MaxInt":"2"} ......]} ```1カ月間ほどさかのぼり、100以上のファイルがGoogle Drive内のフォルダにたまっています。 このファイルの中から、例えば北海道で震度を観測した地震、つまりIntensity>PrefNameに北海道を含む地震のファイルだけを抽出するには、どうしたらいいでしょうか。 また、Intensityの配列は、都道府県(PrefName)ごとに括られており、その中で震度(MaxInt)の降順に都市名(CityName)が並んでいるのですが、これをMaxIntごとに仕分けることはできないでしょうか。最終的に、 震度4 ◯県◯市、◯県◯市、◯県◯村.... 震度3 ◯県◯市、◯県◯町.... のような形で出力したいと考えているのですが。 filterやsortを使うなどして、いろいろ試したのですが、うまくできませんでした。 雑駁な質問で申し訳ありませんが、方向性だけでもご教唆頂けたらとても幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

雑駁な質問で申し訳ありませんが、方向性だけでもご教唆頂けたらとても幸いです。

ご要望を実現するには、小さいですがいくつかのテーマがあるように思いますので、やることを分解してひとつずつ考えると良いです。簡単に考えて、以下のような流れで実現できると思います。

  1. Googleドライブ内のJSONファイルが保存されているフォルダーを対象に、ファイル一覧を取得する。
    1. で取得したファイル一覧をもとに、JSONファイルひとつずつ処理を行う。

 (1) 県名を対象に処理したい場合
・2. のJSONファイルの内容について、Intensity の配列から対象の県名、例えば「北海道」を対象にして、その要素を処理する。
(2) MaxIntでグループ分け処理したい場合
・2. のJSONファイルの内容について、MaxIntをキーとして連想配列で値を保存していく。
こうすると、キー一覧がすなわちMaxIntのリストとなります。

簡単ですが、以下のJSONデータを作成して、サンプルコードで動作確認してみました。

Json

1{"EventID":"20190901035702", 2 "OriginTime":"2019/09/01 04:00:00", 3 "HypoName":"◯◯沖", 4 "HypoCode":"+35.8+140.9-30000/", 5 "Magnitude":"3.3", 6 "Intensity":[{"PrefName":"A県", 7 "CityName":"A1市", 8 "MaxInt":"3"}, 9 {"PrefName":"B県", 10 "CityName":"B1市", 11 "MaxInt":"2"}, 12 {"PrefName":"B県", 13 "CityName":"B2市", 14 "MaxInt":"1"}, 15 {"PrefName":"B県", 16 "CityName":"B3市", 17 "MaxInt":"1"}, 18 {"PrefName":"B県", 19 "CityName":"B4市", 20 "MaxInt":"2"}, 21 {"PrefName":"B県", 22 "CityName":"B5市", 23 "MaxInt":"1"}, 24 ] 25}

結果はBrowser#msgBoxで逐一表示します。forEachなども使っていませんし、コードとしては愚直な例で、すぐご理解できると思います。"MaxInt"でのグループ化後は特にソートしていませんし、質問者さんが使いたいデータに加工するにはまだまだだと思いますが、参考にしてみてください。

GAS

1// サンプルコード 2function processInTargetFolder() { 3 4 // Google Driveフォルダーからファイル一覧を取得 5 var folder = DriveApp.getFolderById(<GoogleドライブフォルダーID>"); 6 var files = folder.getFiles(); 7 8 // フォルダー内のファイル数分ループ 9 while (files.hasNext()) { 10 var file = files.next(); 11 12 // JSONファイルをUTF-8として内容を取得 13 var cont = file.getBlob().getDataAsString("utf-8"); 14 try { 15 var json = JSON.parse(cont); 16 for (var i = 0; i < json["Intensity"].length; i++) { 17 // B県を対象として処理 18 var name = json["Intensity"][i]["PrefName"] 19 if (name == "B県") { 20 // B県の処理ほにゃらら 21 Browser.msgBox("B県の市名: " + json["Intensity"][i]["CityName"]); 22 } 23 } 24 25 // MaxIntをキーとして、グループ化する。 26 var dict = {} 27 28 // Intensityの配列要素分処理 29 for (var i = 0; i < json["Intensity"].length; i++) { 30 var k = json["Intensity"][i]["MaxInt"]; 31 var v = dict[k]; 32 if (v) { 33 v += ", " + json["Intensity"][i]["CityName"] 34 } else { 35 v = json["Intensity"][i]["CityName"] 36 } 37 dict[k] = v; 38 } 39 40 for (var k in dict) { 41 Browser.msgBox(" -- MaxInt: " + k + "=" + dict[k]); 42 } 43 } catch (ex) { 44 Browser.msgBox("Exception: " + ex); 45 } 46 } 47 48 Browser.msgBox("-- done."); 49}

投稿2019/10/15 02:27

dodox86

総合スコア9256

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

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

tatsu3

2019/10/15 23:52

丁寧、親切に教えて下さり、本当にありがとうございました。 方向性が見えました。 後半部分のMaxIntをキーとしてグループ化する仕組みは、ひとまずコピペして試したところ、見事に仕分けされていてびっくりしました。後から自分なりにコードを解読してみて、深く納得したところです。 前半部分も、教えて頂いたやり方を参考に、これから試行錯誤して目指すものを作ってみたいと思います。 もしかしたら、またお尋ねすることがあるかもしれません。大変恐縮ですが、その際はどうぞよろしくお願いいたします。
dodox86

2019/10/16 00:47

お役に立てて良かったです。質問者であるtatsu3さんの過去回答内容とプロフィールを拝見し、感じ入った次第です。ぜひ、引き続き頑張ってください。(上から目線ぽくてすみません)
tatsu3

2019/10/16 02:07

「上から目線」だなんて、とんでもないです。雑駁な質問にお手間をかけてご回答下さり感謝しかありません。どうもありがとうございます。とても励まされました。引き続き「日曜大工」ならぬ「日曜プログラミング」で、一歩一歩前進したいと思います。
tatsu3

2019/10/20 14:04

dodox86さん、ご回答を参考にお陰様でプロジェクトはぐんと進みました。 ただ、教えて頂いたコードの詳細で完全に理解し切れていない部分があり、もし可能であればご説明をお願いできないでしょうか。 2点あります。 ひとつは、下段の // MaxIntをキーとして、グループ化する。 のパーツで、if-else文の意図についてです。その直前で、空の連想配列dictをつくり、キー(変数k)にcityNameごとの震度maxIntを代入すると定義した上で、値(変数v)はdict中のkに対応するものとする、としているところまでは分かりました。それ以降の処理が一旦は分かった気になったこともありましたが、ちょっと応用してみようとしたら理解し切れていないことを実感しました。 もうひとつは、前段を通してtry-catch構文を使う意味についてです。この構文については、いろいろ調べてみましたが、どういう場合に使うべきなのかイマイチ理解出来ません。このケースで、それを使う意味合い、意義付けを教えて頂ければ、理解が進むかもしれません。 追っての質問で大変恐縮ですが、何卒宜しくお願い致します。
dodox86

2019/10/20 15:34 編集

> もうひとつは、前段を通してtry-catch構文を使う意味 私のサンプルでは大雑把にハンドリングしてましたね。そう言う意味では理解を妨げたかもしれません。すみません。例えばこのプログラムではGoogleドライブのあるフォルダーからファイルをひとつずつ処理しますが、JSONファイルであることが前提です。ここでもしJSONファイルではない、未知のファイル(何でも良い。PDFでも、DOCでも)をfile.getBlob().getDataAsString("utf-8")などとして読み出すと、エラー扱いで例外(Exception)が送出(throw)されるはずです。他の部分でも変数がundefined状態のまま参照されるなど、不正な処理で、例外が送出されるケースがあるかもしれません。 そんな訳でtry~catchでくくった訳です。try~catchでくくって例外を捕捉しないと、コードの末端、Browser.msgBoxに到達せず、途中で異常終了しています。デバッグで1行1行トレースすると分かります。 > どういう場合に使うべきなのかイマイチ理解出来ません。 GASのAPIやJavaScriptで提供されるメソッドの内、いくつかのものは例外を送出することでエラーを報告します。逆に言うとメソッドを呼び出したときに例外が送出されなかったということは、エラー無く完了したということになります。つまり、それらの一連の処理をtry~catchでくくると、その間の処理は順次、エラーが無く進んでいるということになります。 エラーがあれば例外が送出され、catchで捕捉することでエラーに対する処理を一元化することができます。プログラムソースを読む上でも正常な場合の処理の流れをひと目で理解することができる、と言う効用もあります。しかしながら実際のところは、エラーの種類は様々であり、一緒くたにcacthで捕捉しても、どこでその例外が発生したか、種類は何か、が判定しずらくなることもあり、有効な対策が取れないことも多いです。ですので、結局は使い方次第です。ひとつ言えるのは、catchもしない、あるいはcatchしても何もしない、だとエラーがまったく分からず、問題の解決を妨げます。最低限デバッグの為にも、適切にcatchしてプログラマー自身が問題の原因を把握する必要があります。
tatsu3

2019/10/21 03:40

引き続き、どうもありがとうざいました。try~catchの意味について「なるほど」と得心しました。「デバッグで一行一行トレースすると分かります」のアドバイス、いろいろなことに通じると思われ、とてもヒントになりました。改めて感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問