初心者のFileMaker pro Q&A (旧掲示板)

みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。

1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)

You are not logged in.

Announcement

新しい掲示板は、こちら:https://fm-aid.com/forum/t/filemaker


#1 2020-05-19 12:05:16

しろ92
Member

JSONのデータ追加について

いつもお世話になっております。
JSONでのデータの追加の仕方が分からず困っております。

使用環境
FMpro17
windows 10

下記のデータAにデータBを追加したいのですが、どのようにすればよろしいでしょうか。
データは300件ほどあるのですが、一度に取得できるデータが100件までのため、最終一つのデータにしたいと考えております。


データA
{"product_stock":[{"id":1,"name":"アイボリー","product_id":5,"product_no":"A1234_1","stock":0,"stock_flag":1,"stock_parent":null},
{"id":2,"name":"ブラック","product_id":5,"product_no":"A1234_2","stock":2,"stock_flag":1,"stock_parent":null}],"meta":{"limit":2,"offset":0,"total":14}}

データB
{"product_stock":[{"id":3,"name":"アイボリー","product_id":6,"product_no":"B1234_1","stock":0,"stock_flag":1,"stock_parent":null},
{"id":4,"name":"ブラック","product_id":6,"product_no":"B1234_2","stock":2,"stock_flag":1,"stock_parent":null}],"meta":{"limit":2,"offset":0,"total":14}}

データAに追加
{"product_stock":[{"id":1,"name":"アイボリー","product_id":5,"product_no":"A1234_1","stock":0,"stock_flag":1,"stock_parent":null},
{"id":2,"name":"ブラック","product_id":5,"product_no":"A1234_2","stock":2,"stock_flag":1,"stock_parent":null},
{"id":3,"name":"アイボリー","product_id":6,"product_no":"B1234_1","stock":0,"stock_flag":1,"stock_parent":null},
{"id":4,"name":"ブラック","product_id":6,"product_no":"B1234_2","stock":2,"stock_flag":1,"stock_parent":null}]}


各データの最後の"meta"は不要のため、データ取得後、先にJSONDeleteElementで削除しよう考えております。
よろしくお願い致します。

Offline

#2 2020-05-19 14:29:42

koeda
Member

Re: JSONのデータ追加について

最初に回答を投稿したのですが、よく見たらバグっていたので地道にスクリプトを書きました。

#meta情報を取り除いたJSONを取得
変数を設定 [ $json; 値:JSONDeleteElement ( データA ; "meta" ) ]

#"product_stock"のオブジェクト数を取得
変数を設定 [ $itemsOfA; 値:ValueCount ( JSONListValues ( データA ; "product_stock" ) ) ]
変数を設定 [ $itemsOfB; 値:ValueCount ( JSONListValues ( データB ; "product_stock" ) ) ]

#ループしながら値をマージ
変数を設定 [ $index; 値:0 ]
Loop
   変数を設定 [ $json
         ;  値:JSONSetElement ( $json ;"product_stock[" & $itemsOfA + $index & "]" 
            ;  JSONGetElement ( データB ; "product_stock[" & $index & "]" )
            ;  JSONObject ) ]
   変数を設定 [ $index; 値:$index+1 ]
   Exit Loop If [ $index ≥ $itemsOfB ]
End Loop

#マージ結果をフィールドに格納
フィールド設定 [ マージ結果; JSONFormatElements ( $json ) ]

Last edited by koeda (2020-05-20 09:05:35)

Offline

#3 2020-05-19 14:38:18

koeda
Member

Re: JSONのデータ追加について

Offline

#4 2020-05-19 17:58:57

Hiro
Member

Re: JSONのデータ追加について

ループ計算式で求める式例、

Let(
[
   $jsn=JSONDeleteElement(データA;"meta");
   $nA=ValueCount(JSONListValues(データA;"product_stock"));
   $nB=ValueCount(JSONListValues(データB;"product_stock"));
   $i=0;
   $LOOP=
      "Case($i=$nB; JSONFormatElements($jsn);
         Let([
            $jsn=
                  JSONSetElement($jsn
                     ; ""product_stock["" & $nA+$i & ""]"" 
                     ; JSONGetElement(データB;""product_stock["" & $i & ""]"")
                     ; JSONObject );
            $i=$i+1
         ]; Evaluate($LOOP))
      )"
];
   Evaluate($LOOP)
)

Offline

#5 2020-05-19 18:25:00

koeda
Member

Re: JSONのデータ追加について

Hiroさん、ありがとうございます。
再帰式を書くの苦手で…

Offline

#6 2020-05-20 00:36:39

しろ92
Member

Re: JSONのデータ追加について

koedaさん、Hiroさんありがとうございます。

教えていただいた方法でデータを追加することができました。

自分なりに別の追加方法も考えたのですが、下記のようなやり方はダメでしょうか。

変数を設定 [ $jsonA; 値:JSONDeleteElement ( データA ; "meta" ) ]
変数を設定 [ $jsonB; 値:JSONDeleteElement ( データB ; "meta" ) ]
変数を設定 [ $kekka;
Let ( [
$pos = Position ( $jsonB ; "[" ; 1 ; 1 ) ;
$len = Length ( $jsonB ) ;
$tsuika = Right ( $jsonB ; $len - $pos ) ] ;
Substitute ( $jsonA ; "]}" ; "," & $tsuika )
)
]

上記は、受信した各データはエラーがない場合です。

よろしくお願い致します。

Offline

#7 2020-05-20 04:17:14

Hiro
Member

Re: JSONのデータ追加について

>#1でJSON関数が示唆されていたので、JSON関数で完結する方法をとりましたが、
#6のような従前のテキスト関数で処理するのも全然構わないと思いますよ。
(※ただし、従前のテキスト関数処理はデータのJSONフォーマット構文が固定的であまり自由度はありません。)

#6のスクリプトは、1つの計算式に纏めることもできます。

Let(
[
   #jsnA=SONDeleteElement(データA;"meta");
   #jsnB=SONDeleteElement(データB;"meta");
   #pos=Position(#jsnB;"[";1;1);
   #len=Length(#jsnB);
   #add=Right(#jsnB;#len-#pos)
];
   JSONFormatElements(Substitute(#jsnA; ["]}";","&#add]))
)

Offline

#8 2020-05-20 09:41:25

koeda
Member

Re: JSONのデータ追加について

しろ92 wrote:

自分なりに別の追加方法も考えたのですが、下記のようなやり方はダメでしょうか。

今回は単純な構造のJSONなので全く問題ないと思います。

ただ今回作成したマージのアルゴリズムは他の場面でも使えると思うので、
今回Hiroさんの提示してくださった計算式をカスタム関数にし、
データA、データB、オブジェクト名の3つをパラメータとして渡せるようにしておけば
「JsonAに、JsonBのオブジェクト"hoge"をマージする」
という汎用的な関数に仕立てることができるのではないでしょうか。

Last edited by koeda (2020-05-20 09:42:07)

Offline

#9 2020-05-20 12:44:40

koeda
Member

Re: JSONのデータ追加について

カスタム関数化したファイルです。
https://www.dropbox.com/s/1139fkg6ziu1r … fmp12?dl=0

(追記)あとから気づきましたが、汎用化するならJSONFormatElements ( )による整形はしない方が良いですね。

Last edited by koeda (2020-05-20 13:16:30)

Offline

#10 2020-05-20 13:20:48

Hiro
Member

Re: JSONのデータ追加について

前回答案でネックの面倒なループ処理を使わず、本案件に特化・最適化した安楽な互換式の提案です。

Let(
[
   #jsnA=JSONGetElement(データA;"product_stock");
   #jsnB=JSONGetElement(データB;"product_stock");
   #jsnAB=Substitute(List(#jsnA;#jsnB);["]¶[";","]);
   #jsn=JSONSetElement(""; "product_stock"; #jsnAB; JSONArray)
];
   JSONFormatElements(#jsn)
)

Offline

#11 2020-05-20 22:50:30

しろ92
Member

Re: JSONのデータ追加について

koedaさん、Hiroさん

いろいろ教えていただきありがとうございます。
早速試してみたいと思います。

Offline

#12 2020-05-21 05:23:52

Hiro
Member

Re: JSONのデータ追加について

【マルチデータ対応式を補足】

>#1『データは300件ほどあるのですが、一度に取得できるデータが100件までのため、最終一つのデータにしたいと考えております。』
この初期説明からすると、マージ対象データは2つだけでなく、3つ以上と云う事ですかネ?
なら、#10式の2つデータ対応を任意数のマルチデータに対応した修正式を以下に補足。
(※仮に、データAから任意データXまでとして式記述)
Let(
[
   #jsnA=JSONGetElement(データA;"product_stock");
   #jsnB=JSONGetElement(データB;"product_stock");
   ・・・   
   ・・・   
   #jsnX=JSONGetElement(データX;"product_stock");

   #jsnA2X=Substitute(List(#jsnA;#jsnB;・・・;#jsnX);["]¶[";","]);
   #jsn=JSONSetElement(""; "product_stock"; #jsnA2X; JSONArray)
];
   JSONFormatElements(#jsn)
)

Offline

#13 2020-05-26 10:31:11

しろ92
Member

Re: JSONのデータ追加について

Hiroさん、ありがとうございます。

返信が遅くなってすみません。
ここまでスッキリできるんですね(^^;)
大変勉強になりました。

ありがとうございます。

Offline

Registered users online in this topic: 0, guests: 1
[Bot] ClaudeBot

Board footer

Powered by FluxBB
Modified by Visman

[ Generated in 0.006 seconds, 7 queries executed - Memory usage: 549.53 KiB (Peak: 570.44 KiB) ]