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

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

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

JSON

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

Q&A

解決済

2回答

16438閲覧

JSONファイルをVBAで読み込んでexcelの表形式に変換したい。(PowerQueryを使わずに)

nkiki

総合スコア18

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

JSON

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

0グッド

1クリップ

投稿2021/11/06 09:54

編集2021/11/09 01:59

下記のようなjsonをVBAだけを使ってエクセルに出力したいです。

json

1[ 2 { 3 "AA": "XXXX1", 4 "BB": { 5 "B1": "XXXX2", 6 "B2": {"DDD": "XXXX3"}, 7 "B3": { 8 "EE1": "XXXX4", 9 "EE2": "XXXX5" 10 } 11 }, 12 "CC": "XXXX6", 13 "DD": {"D1": "XXXX7"}, 14 "EE": { 15 "G1": "XXXX8", 16 "G2": "XXXX9" 17 } 18 }, 19 { 20 "AA": "XXX10", 21 "BB": { 22 以降、省略 23 }, 24 { 25 以降、省略 26 } 27]

下記のような出力イメージで考えているのですが、微妙なネスト状態になっているので
アイデアが思い浮かびません。。。。
jsonファイルは、見やすいように改行しましたが、これが全部、改行無しでくっついて
一行扱いになっているのでどうやって、VBAで読み込んだらいいか、調べているところです。
どなたか、ご教授いただけると助かります。。。
ちなみに、上記のデータセットは「以降、省略」と記載されている部分だけで5000セットくらいあります。
あたまの”AA"が5000千回くるかんじです。

イメージ説明

実現したいことを整理します。
VBAで下記のコードを実現したいのです。
・改行が無いため先頭から読み込む。
・先頭から読み込みながら、「: {」があったら階層を一つ下がって「BB.B3.EE1」して、
その値を読み込む。
・「}」があれば一つ階層を上げる。(「BB.B3」階層に戻る)
・項目はエクセルの一行目と一致したら出力する。

上記を実現する方法をVBAで書きたい。。。
と思って調べているところです。。「先頭から読み込む」では無く「一行づつ」なら、いけそうな
感じもするのですが、、、、。

VBA

1 Dim buf, str As String 2 With CreateObject("Scripting.FileSystemObject") 3 With .GetFile("D:\XXX\ex.json").OpenAsTextStream 4 buf = .ReadAll 5 .Close 6 End With 7 End With 8 buf = Replace(buf, "[", "") 9 buf = Replace(buf, "]", "") 10 Dim Json: Set Json = JsonConverter.ParseJson(buf) 11 MsgBox Json("AA")

VBA-JSONを使って上記のように記載した場合は、最初の"AA"は取り出すことができますが、二週目の"AA"の"XXX10"が取り出すことができなくて困っています。二週目の"AA"の値が指定して取り出せれば、VBA-JSONでも構いません。
jsonファイルに同じ名前の付いた2週目のファイルの取り出し方が分からなかったため、他の方法を探していた次第です。

使用環境は 64bit版エクセルとなります。

上記のVBA-JSONはcx20さんが教えてくださった下記を使用しています。
■ VBA-JSON
https://github.com/VBA-tools/VBA-JSON

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

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

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

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

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

meg_

2021/11/06 11:28

> 微妙なネスト状態になっているので 普通のjsonファイルに見えますが、どのあたりが"微妙なネスト状態"なんでしょうか? > 上記のデータセットは5000セットくらいあります jsonファイルが5000ファイルという意味でしょうか?
cx20

2021/11/06 11:57

VBA だと VBA-JSON というライブラリがあるようですね。(使ったことは無いですが) 項目が固定であれば単純に項目数分マップすればよいかと思います。 項目が非構造(もしくは複雑)な場合、マップは難しいかも知れないですね。。 ■ VBAでparseしたJSONデータの要素を取得する方法 https://dampgblog.hinohikari291.com/jsonparse/ ■ VBA-JSON https://github.com/VBA-tools/VBA-JSON
nkiki

2021/11/07 23:25

meg_さん ご指摘ありがとうございます。 普通のjsonファイルですね。申し訳ありません。 jsonファイルは一つです。その中に5000個分ほどの{}のセットが並びます。 cx20さん 情報ありがとうございます。 VBAで下記のコードを実現したいのです。。。 ・改行が無いため先頭から読み込む。 ・先頭から読み込みながら、「: {」があったら階層を一つ下がって「BB.B2.DDD」とする。 ・「}」があれば一つ階層を上げる。 ・項目はエクセルの一行目と一致したら出力する。 VBA-JSONの存在は私も知っていましたが、上記を実現する方法をVBAで書きたい。。。 と思って調べているところです。。「先頭から読み込む」では無く「一行づつ」なら、いけそうな 感じもするのですが、、、、。
退会済みユーザー

退会済みユーザー

2021/11/08 05:09 編集

書きたいなら書けばいいじゃないですか。質問文見るに漠然としすぎていて、何も書いてるように見えませんが。作ってる過程で不明な点があるなら、その部分をピンポイントで質問してください。そういうものを作って欲しいという話であれば、お金出してどっかに依頼してください。 [推奨していない質問] https://teratail.com/help/avoid-asking [質問するときのヒント] https://teratail.com/help/question-tips
退会済みユーザー

退会済みユーザー

2021/11/08 08:13

外部ライブラリ(VBA-JSON)を使用したのであれば、そこのリンクも貼るようにしてください。リンクの挿入(鎖アイコン)を使用するとよいです。
guest

回答2

0

【追記】
VBA-JSONを使用した例です。
下記ではDebug.Printを使用して動作確認しています。
必要に応じて配列に入れるなど工夫してください。

jsonの階層がもっと深い場合には再帰処理した方が良さそうです。

VBA

1Sub test() 2 3 Dim fso As Object 4 Dim json As Object 5 Dim jsonText As String 6 Dim jsonParse As Object 7 Dim i As Variant 8 Dim j As Variant 9 Dim k As Variant 10 11 Set fso = CreateObject("Scripting.FileSystemObject") 12 Set json = fso.OpenTextFile("C:\Users\test.json", 1) 13 jsonText = json.ReadAll 14 json.Close 15 16 Set jsonParse = JsonConverter.ParseJson(jsonText) 17 18 For Each i In jsonParse 19 For Each j In i 20 Debug.Print j 21 If VarType(i(j)) = 9 Then 22 For Each k In i(j) 23 Debug.Print k 24 If VarType(i(j)(k)) = 9 Then 25 For Each m In i(j)(k) 26 Debug.Print m 27 Debug.Print i(j)(k)(m) 28 Next m 29 Else 30 Debug.Print i(j)(k) 31 End If 32 Next k 33 Else 34 Debug.Print i(j) 35 End If 36 Next 37 Next i 38 39End Sub 40

Excel32bit版の場合です

[VBA]VBAでjsonをパースするを参考に作ってみました。

json

1[ 2 { 3 "AA": "XXXX1", 4 "BB": { 5 "B1": "XXXX2", 6 "B2": {"DDD": "XXXX3"}, 7 "B3": { 8 "EE1": "XXXX4", 9 "EE2": "XXXX5" 10 } 11 }, 12 "CC": "XXXX6", 13 "DD": {"D1": "XXXX7"}, 14 "EE": { 15 "G1": "XXXX8", 16 "G2": "XXXX9" 17 } 18 } 19]

VBA

1Option Explicit 2 3Sub test() 4 5 Dim buf As String 6 With CreateObject("ADODB.Stream") 7 .Charset = "UTF-8" 8 .Open 9 .LoadFromFile "./test.json" 10 buf = .ReadText 11 .Close 12 End With 13 14 Dim obj As Object 15 Dim json As Object 16 Dim json2 As Object 17 Dim json3 As Object 18 Dim json4 As Object 19 Dim i As Variant 20 Dim j As Variant 21 Dim k As Variant 22 23 Set obj = CreateObject("ScriptControl") 24 obj.Language = "JScript" 25 obj.AddCode "function jsonParse(s){ return eval('('+s+')');}" 26 27 Set json = obj.codeobject.jsonParse(buf) 28 Set json2 = CallByName(json, 0, VbGet) 29 30 Dim js As Object 31 Dim keys As Object 32 Dim keys2 As Object 33 Dim keys3 As Object 34 35 Set js = CreateObject("ScriptControl") 36 js.Language = "JScript" 37 js.AddCode "function getKeys(h) { var keys=[]; for(var k in h){keys.push(k);} return keys; };" 38 39 Set keys = js.codeobject.getKeys(json2) 40 For Each i In keys 41 Debug.Print i 42 If Not CallByName(json2, i, VbGet) = "[object Object]" Then 43 Debug.Print CallByName(json2, i, VbGet) 44 Else 45 Set keys2 = js.codeobject.getKeys(CallByName(json2, i, VbGet)) 46 For Each j In keys2 47 If Not CallByName(json2, i, VbGet) = "[object Object]" Then 48 Debug.Print json3 49 Else 50 Set json3 = CallByName(json2, i, VbGet) 51 Debug.Print j 52 If Not CallByName(json3, j, VbGet) = "[object Object]" Then 53 Debug.Print CallByName(json3, j, VbGet) 54 Else 55 Set json4 = CallByName(json3, j, VbGet) 56 Set keys3 = js.codeobject.getKeys(CallByName(json3, j, VbGet)) 57 For Each k In keys3 58 Debug.Print k 59 Debug.Print CallByName(json4, k, VbGet) 60 Next 61 End If 62 End If 63 Next 64 End If 65 Next 66 67End Sub 68 69'AA 70'XXXX1 71'BB 72'B1 73'XXXX2 74'B2 75'DDD 76'XXXX3 77'B3 78'EE1 79'XXXX4 80'EE2 81'XXXX5 82'CC 83'XXXX6 84'DD 85'D1 86'XXXX7 87'EE 88'G1 89'XXXX8 90'G2 91'XXXX9

この方法は使いやすいとは言えないので他の方法の方が良いかと思います。
JSONファイルを扱うのであればjavascriptやPythonが扱いやすいのではないかと思います。

投稿2021/11/08 05:53

編集2021/11/08 06:56
meg_

総合スコア10580

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

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

nkiki

2021/11/08 06:02

色々とありがとうございます。私の質問の仕方がものすごく悪く、他の方からも指摘されている上で時間を割いていただきありがとうございます。 私の使っているExcelが64bit版になります。。。 「Set js = CreateObject("ScriptControl")」部分でエラーになるため、VBA-Jsonか、自力か。。。を考えているところです。
guest

0

ベストアンサー

vba

1 buf = Replace(buf, "[", "") 2 buf = Replace(buf, "]", "")

ここで置換しているせいで、正しくJSONを解釈出来ていないのでは?
ここをコメントアウトして質問文っぽい感じのJSONを読ませてみましたが、特に問題なさそうですが。
デバッグウィンドウ

投稿2021/11/08 07:56

編集2021/11/08 08:03
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

nkiki

2021/11/08 08:24

おおお!まさしく私が知りたかったのは、一週目が「Json(1)("AA")」で二週目が「Json(2)("AA")」でアクセスできる手法でした。。。 言いたいことが正確に表現できずに申し訳ありません。 みなさま、本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問