この記事は FIXER Advent Calendar 2021(https://adventar.org/calendars/6788) 4日目の記事です。
Power Appsでコレクションデータの保存をするときにJSONに変換すると便利なことがあると思います。ところが残念なことに、Power AppsにはコレクションをJSONに変換する関数はあっても、JSONをコレクションに変換する関数は用意されていません。でも安心してください。先人の知恵を借りることでJSON⇒コレクションの変換も問題なくできます。
詳しくは以下のURLに詳しく書いてあるので参照していただければと思います
PowerAppsでJSONを解析して編集、格納 - Qiita
基本的にはこれに沿ってやれば簡単にできるのですが、この方法を使っているときに2点だけつまづいてしまったポイントがありました。もしかしたら同じことでつまづいた人もいるんじゃないかと思ったので共有させていただきます。
結論から言うと、
・変換したいコレクションの中にnullがあるときは空文字に置き換えてからJSONに変換する
・JSONの中の値の型が数値型のときは文字列型にする
の2点に気を付けていただきたいです。
まずは普通にJSONをコレクションに変換する
下準備として下のコレクションを作成します。(入力する場所はボタンコントロールのOnselectで構いません)
ClearCollect(
members,
{
name: "ライナー",
height: "188",
age: "17"
},{
name: "ベルトルト",
height: "188",
age: "16"
},{
name: "ジーク",
height: "183",
age: "28"
}
)
次にJSON関数を使ってこのコレクションをJSON形式に変換し、membersJSONという変数に格納します。
Set(membersJSON,JSON(members))
テキスト入力コントロール(TextInput1)を用意し、今作成したmembersJSONを表示します。
このmembersJSONを解析していきます。新しくボタンコントロールをつくり、以下のコードをOnselectに書き込みます。解析したJSONはItemSpecEntityというコレクションに格納しています。
With(
{TableFromJson:MatchAll(
TextInput1.Text,
"\{""age"":""(?<age>[^""]*)"",""height"":""(?<height>[^""]*)"",""name"":""(?<name>[^""]*)""\}"
)
},
If(CountRows(TableFromJson)>1,
ClearCollect(
ItemSpecEntity,
ShowColumns(
TableFromJson,
"age",
"height",
"name"
)
)
)
);
このコードを書き込んだボタンを押してみると、以下のように確かにコレクションに変換されています。
ここまでは想定通りです。
変換したいコレクション中にnullがあるとき
以下のように3行目のageの値が空の時はどうでしょう。
このJSONをさきほどと同様にコレクションに変換すると、以下のようなコレクションができます。
これを見ると確かに空文字にした部分が空になっているので何の問題もないように見えます。(実はnullが入っています。)
では、このコレクションを再びJSONに変換してみると...
なんと空文字にしたはずのageの部分がnullとなってしまいました。
このJSONを先ほどのコードで解析しようとすると、スキーマに合わないためうまくいきません。
より具体的にはnullのある行だけ認識されず、JSONにはもともと要素が3行あったのに、2行しかないコレクションが出来上がってしまいます。
これがどういう時に困るかというと、例えばユーザが自由に編集したコレクションを保存したり、保存したものを呼び出したりするようなアプリを作る場合です。このような場合にはコレクション⇒JSON、JSON⇒コレクションの変換を行うのですが、この現象が起こってしまうことで以前保存したものと全く同じものを呼び出すということができなくなってしまいます。
では、これを防ぐためにはどうすればよいかというと、実は空文字を含むJSONをコレクションに変換した時点でコレクションにはnullの値が入ってしまっているので、このnullが入ったコレクションをJSONに変換をする前にUpdateIf関数などを使ってコレクションのnullを空文字に変換しておきましょう。
JSONの中の値が数値型の時
今度は3行目のageを文字列型の"183"ではなく、数値型の183としてみました。
このJSONを先ほどと同じコードで解析してコレクションに変換してみると...
またしても3行目の要素が認識されず、2行だけのコレクションができてしまいました。
これもまた型がMatchAll関数に記述したスキーマに合わないためでしょう。
したがって、数値型を含むときはあらかじめ文字列型に変換しておくことが必要となります。
おわり
すごくニッチな内容になってしまいましたが、誰かの役に立てば幸いです!