みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。
1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)
You are not logged in.
Pages: 1
質問させて下さい。
またまた初心者すぎる質問かも知れません(汗)
["{}";
["年齢";フィールド名前;2];
とした場合、空欄でも0が返ってくるけど、0歳児の0もあります。
空欄の場合、どうやって空欄もしくはフィールドが未入力の場合は出力しないようにしたいのですが、
Letの中でどうやって分岐させればよいかわからないのです。
1フィールド単位でifを書いてゆくのでしょうか?
またLetの中なので「=""」は使えないしなぁ...
後、日付とかタイムスタンプとかは事前に文字列に変換しておく必要があるのでしょうか?
JSON便利だけど、あまりWebに情報がないです。
よろしくお願いします(m_m)
ハゲ
IsEmpty() を使ってみては。
Offline
JSONの数値にNULLはないので、「2」ではだめです。
Shinさん
himaganeeさん
ご返信ありがとうございます。
なるほどJSONNumberにJSONNullは使えないのですね。
知らなかったです。
一度文字列にしてから戻す時はGeTAsNumberで数値に戻すしかないのですね。
またまた初心者な質問なんですけど、
Let([
_A="3";
_B="東京太郎";
_C = if ( not IsEmpty(_A) ; JSONString; JSONNull);
_json=JSONSetElement("{}";
["年齢"; _A ; _C];
["名前"; _B ; JSONString])
];
_json
)
上手くNullの表示がでました。
しかしこれを手入力するのは大変なので、カスタム関数にするのがよいのでしょうか?
まだカスタム関数は経験がないので挑戦してみます。
皆様やっかいなハゲをいつもありがとうございます(m_m)
ハゲ
すみません、引き続きお願いしたいのですが(汗)
質問というか、カスタムタグで
このようなカスタムタグ(json_add)を作りました。
計算フィールドにいれて値を引数の位置に直接書き込むとちゃんと生成してくれます。
でもカスタムタグを登録して、計算フィールド内で使用すると「計算式の一覧を使用できませんのエラー」がでてしまうのです。
単体で使う分には使えるのですがJSONSetElement("{}";
json_add ( "主キー" ; 主キー ; 1 );
)
といれるとエラーが出て舞うのです。
SONSetElementの中で動作させるには、どこが不都合なのか全然わかりません。
Let([
%A=key; //要素名
%B=value; //値
%C=type; //FileMakerのフィールド型 1.テキスト 2.数字 3.日付 4.タイムスタンプ
/*日付とタイムスタンプのtypeをJSONNumber(2)に統一する*/
%D=Case(
%C=1;1;
%C=2;2;
%C=3;2; //日付
%C=4;2;); //タイムスタンプ
/*typeが日付(3)とタイムスタンプ(4)の場合GetAsNumberに変換する必要がある*/
%B=Case(
%C=1;%B;
%C=2;%B;
%C=3;GetAsNumber(%B);
%C=4;GetAsNumber(%B));
/*value(フィールド)が空欄の場合出力しない*/
%json=if(not IsEmpty(%B);
"[\"" & %A & "\";\"" & %B & "\";" & %D & "]";"")];
%json
)
/*jsonの配列を正しく定義するカスタム関数(FMPに戻す使用)*/
/*もし日付やタイムスタンプを読める形(日付やタイムスタンプを数値かテキストに変換)してJSONを出力する事*/
何卒よろしくお願いします
ハゲ
取り合えず、赤字の1ヵ所は明らかにダメですネ。
式が見にくいとミスる元です。見易い式の記述を心がけましょう。
Let([
%A=key; //要素名
%B=value; //値
%C=type; //FileMakerのフィールド型 1.テキスト 2.数字 3.日付 4.タイムスタンプ
/*日付とタイムスタンプのtypeをJSONNumber(2)に統一する*/
%D=Case(
%C=1;1;
%C=2;2;
%C=3;2; //日付
%C=4;2 ; ); //タイムスタンプ ※ ←「 ; 」が不用
/*typeが日付(3)とタイムスタンプ(4)の場合GetAsNumberに変換する必要がある*/
%B=Case(
%C=1;%B;
%C=2;%B;
%C=3;GetAsNumber(%B);
%C=4;GetAsNumber(%B));
/*value(フィールド)が空欄の場合出力しない*/
%json=if(not IsEmpty(%B);
"[\"" & %A & "\";\"" & %B & "\";" & %D & "]";"")];
%json
)
Offline
Hiroさん
いつもいつもすみませーん(汗)
お恥ずかしい...
わかりやすいコードの書き方気を付けます!
でもやっぱ動かないです。
JSONSetElementの中で
動かすのがダメなんですかねぇ....
ハゲ
>『でもやっぱ動かないです。』
見易くした下式では動作してますヨ!
Let([
%A=key; //要素名
%B=value; //値
%C=type; //FileMakerのフィールド型 1.テキスト 2.数字 3.日付 4.タイムスタンプ
%D=
Case(
%C=1; 1;
%C=2; 2;
%C=3; 2; //日付
%C=4; 2 //タイムスタンプ
); //日付とタイムスタンプのtypeをJSONNumber(2)に統一する
%B=
Case(
%C=1; %B;
%C=2; %B;
%C=3; GetAsNumber(%B);
%C=4; GetAsNumber(%B)
); //typeが日付(3)とタイムスタンプ(4)の場合GetAsNumberに変換する必要がある
%json=
if(
not IsEmpty(%B)
; "[\"" & %A & "\";\"" & %B & "\";" & %D & "]"
; ""
) //value(フィールド)が空欄の場合出力しない
];
%json
)
更に私風の式にすると、
Let([
#A=key; //要素名
#B=value; //値
#C=type; //FileMakerのフィールド型 1.テキスト 2.数字 3.日付 4.タイムスタンプ
#D=
Choose(#C
; ""
; 1
; 2
; 2 //日付
; 2 //タイムスタンプ
); //日付とタイムスタンプのtypeをJSONNumber(2)に統一する
#B=
Choose(#C
; ""
; #B
; #B
; GetAsNumber(#B)
; GetAsNumber(#B)
); //typeが日付(3)とタイムスタンプ(4)の場合GetAsNumberに変換する必要がある
#json=
Choose(IsEmpty(#B)
; "[" & Quote(#A) & ";" & Quote(#B) & ";" & #D & "]"
) //value(フィールド)が空欄の場合出力しない
];
#json
)
Offline
Hiroさん
ありがとうございます。
Hiroさんの書き方を見て
俺後何年かかるんだろう?
っと秩父の山々を見ながらため息を着く...。
プロの方ってすごいですね。
生きてるうちに書けるようになるかどうかわかりませんが、
勉強します!
秩父の山の中ではFileMaker仲間は見つからず。
いつも一人でモンモンとやっているハゲなので、
このサイトやHiroさんShinさんなどパワーユーザーの方々には
助けられてばかりです(m_m)
ハゲ
Hiroさん
JSONSetElement以外で書くと、表示されますが、
JSONSetElement("{}";
json_app("主キー";主キー;1);
)
っとすると
引数が足りませんとエラーが出るようになってしまいました。
うーん。
何でだろう...
Hiroさんのコードをただ貼り付けてカスタムタグを生成しただけだし、
Let([
_json=JSONSetElement("{}";
json_add("A";"あれ";"1");
json_add("B";"これ";"1")
)
];
_json
)
こんな感じで書いたのですが、、
引数も3つであっているしなぁ
ハゲ
続きです。
私はWin7なので
改行コードとですかねぇ
ハゲ
例えば、キー="要素名"、値=2019/1/1 0:00:00、タイプ=4 (タイムスタンプ)
の時、["要素名"; 201911000; JSONNumber] を得るカスタム関数は、●カスタム関数: JsonAdd(key; value; type) (例:JsonAdd("要素名"; 「2019/1/1 0:00:00」; 4))
●引数: key、value、type
●関数式:Let(
[
#A=key; //要素名
#B=value; //値
#C=type; //FileMakerのフィールド型 1.テキスト 2.数字 3.日付 4.タイムスタンプ
#D=
Choose(#C>1; "JSONString"; "JSONNumber"); //日付とタイムスタンプのtypeをJSONNumber(2)に統一する
#B=
Choose(#C>1; Quote(#B); GetAsNumber(#B)) //typeが日付(3)とタイムスタンプ(4)の場合GetAsNumberに変換する必要がある
];
Choose(IsEmpty(#B); "[" & Quote(#A) & "; " & #B & "; " & #D & "]") //value(フィールド)が空欄の場合出力しない
)
とココまで書いて、ふっと、無駄な余計な事をやっているのでは?...と!
もともと、JSON値の「データタイプ」と「空欄数値」問題の対策式だったのですが、
このままでは、保存JSONデータの再利用時にデコード処理など諸々と問題がありそうな?
それなら、データタイプに関わらず一律テキスト("値"; JSONString)で扱っておけば、
空欄数値問題も不問となります。と云う訳で、こんなカスタム関数も不必要??
Offline
そういう文字列で結果を返してもオヤジさんが誤用したようには使えず、Evaluateが必要になってしまいますよね。。。
脇からの質問で御免なさい、空白と0をjsonの結果に表示するだけなら
JSONRaw では駄目なのですか?・・・JSON 要素 (値が有効な JSON ではない場合は JSON 文字列)とあるので
/*typeが日付(3)とタイムスタンプ(4)の場合GetAsNumberに変換する必要がある*/
私的に必要があるのでしょうか???
日付もタイムスタンプも JSONString で良いですよ。Google API のJSONも日付,タイムスタンプは、テキストで入っています。
Offline
値がないときは、 null が入るようにしておけばよいだけ?なのでは。
例:
Let([
_KEY="id"
;_Value=testJSON::TM
;_TYPE=If ( IsEmpty ( _Value ) ; JSONNull ; JSONNumber )
];
JSONSetElement ("" ; _KEY ; _Value ; _TYPE )
)
Offline
カスタム関数にするなら以下とか...
JSONSetElementCustom ( JSON ; KEY ; VALUE ; JSONTYPE )
JSONSetElement (JSON ; KEY ; VALUE ; If ( IsEmpty ( VALUE) ; JSONNull ; JSONTYPE ))
使用例:
JSONSetElementCustom ( "" ; "年齢" ; テーブル::年齢 ; JSONNumber )
テーブル::年齢 が空欄の場合:{"年齢":null}
テーブル::年齢 が 0 の場合:{"年齢":0}
Offline
Hiroさん
そうかもですね。
日付でもタイムスタンプも「JSONString」で出力しても問題ないようです。
何かのWebサイトを見てて、JSONNumberに統一しなきゃっと思い込んでいました。
hiroさんには、本当に色々手を煩わせてしまってすみませんでした。
すっごい勉強になりました。
ありがとうございました(m_m)
ハゲ
qb_dpさん
ありがとうございます。
Null値として残すか、出力自体しないのか悩む所です。
ハゲ
取り合えず、任意FM「値」からJSONデータタイプを判別計算する式例です(※空白数値は「JSONString」へ仕分け。)
Choose(値フィールド=値フィールド*1; "JSONString"; "JSONNumber")
上式を基に、対象レコードを一括でJSON変換するサンプルファイルをアップしときます。
●作例サンプル「JSON要素の一括生成.fmp12」→ https://1drv.ms/u/s!AlaCGhTKTWEOqAH535E … 1?e=oGxo3s
【設定説明】
面倒な「カスタム関数」や「ループ式」「ループスクリプト」は使わず、代わりに、
「繰り返しフィールド」や「グローバルフィールドの全置換」などで代用した安易な作例。
レコード内「名」と「値」を繰り返しフィールドへ一括格納する。
「名」と「値」から「要素」を繰り返し計算フィールドへ算出する。
繰り返し「要素」を1つにまとめた「オブジェクト」を生成する
グローバルフィールドに、計算値による「フィールド内容の全置換」を適用して、
対象レコードを一括でJSON変換、してお終い。
【FMレコードのJSON変換結果例】
{
"レコードID= 1" :
{
"伝票No" : "0001",
"備考" : "",
"単価" : 200,
"商品" : "リンゴ",
"数量" : "",
"日付" : "2019/09/15"
},
"レコードID= 3" :
{
"伝票No" : "0003",
"備考" : "フィリッピン産",
"単価" : 300,
"商品" : "バナナ",
"数量" : 5,
"日付" : "2019/09/15"
}
}
Last edited by Hiro (2020-05-12 22:19:58)
Offline
Pages: 1
[ Generated in 0.007 seconds, 10 queries executed - Memory usage: 577.89 KiB (Peak: 598.8 KiB) ]