はじめに
先日、家庭用に家計簿アプリを作成していて、ふと「自分で設定した色情報(RGBA 値)って、保存しておけないもんかなー」と思ったのです。
例えばデータベース側にユーザ毎の設定情報枠を設けておいて、それを読み書きしてアプリ側に反映できれば、ユーザーが各々好みの色味に変更して利用することもできるよなーと。
ということで、これまで色々と試行錯誤した結果、一番簡単な方法はとってもシンプルであることが分かりました。
が、せっかくなので、ここでは失敗した方法や煩わしい方法も含めて、実際に私が行った4つの試行錯誤を備忘録としてまとめてみました。
なかなか答えにたどり着かない歯がゆさをご堪能ください。笑
(Advent Calendar の初日からこんなグダグダでいいのか!?)
やりたいこと
こんな画面で、ユーザーが色を設定し登録したら、次回起動した際も設定された色が反映されるようにする。
事前準備
今回は SharePoint リスト "ColorSet" をデータベースとして利用してみます(もちろん CDS でも OK)。
SharePoint 側に色情報を格納するリストを作っておきます。
列の型はとりあえず1行テキストを用意。
やったこと
試行錯誤① RGBA 関数の記載をそのまま文字列として保存してみる
まず思い付いたのは、色を設定する際に記述されている RGBA 関数の記述をまるごと SharePoint に読み書きすることでした。
ということで、まずは SharePoint 側に保存した RGBA 関数の記述をアプリ側に反映できるかを試してみました。
まずは SharePoint 側に RGBA 関数を記述しておきます。
続いて、この値をアプリの Screen の背景(Fill)に反映してみました。
リストの1レコード目は First 関数で取得できます。
First(ColorSet).ColorData
失敗。Fill には Color 値が必要なのですが、RGBA 関数の記述が文字列として認識されてしまい、エラーとなります。
どうやらこの方法ではうまくいかないようです。
試行錯誤② "#FF7F00FF" の RGB 16進表記で保存してみる
試行錯誤①で"Color 値が必要です"と表示されていたので、ここでようやく Color 値について調べ始めた私。
PowerApps の Color 列挙型と ColorFade、ColorValue、および RGBA 関数
ふむふむ、なるほど。
RGBA 関数を一旦止めて、RGBA の各色の値を16進数で記述する ColorValue 関数を使えばうまくいくのではと考えました(今思えばこの判断が余計な試行錯誤の元凶だった)。
10進数で記載する RGBA 関数と、16進数で記載する ColorValue 関数の関係はこんな感じなので、まずは SharePoint 側に ColorValue 関数の中身を登録しておきます。
続いて、この 16進数値をアプリ側で読み込み、ColorValue 関数で包んで Screen の背景(Fill)に反映してみました。
ColorValue(First(ColorSet).ColorData)
おー!うまくいった!
さて、今度はアプリ側で色を設定し、先ほどの16進数値に変換して SharePoint に登録する処理を追加します。
さすがにユーザ側に "#FF7F00FF" などと直入力させるのは嫌なので、RGBA の各値をスライダーで変え、スライダーの各値(10進数)を16進数値に変換する処理を追加してみます。
まずはスライダーを以下のように配置。
続いて、テキストラベル"Label_SubmittedDataValue"の Text に、各スライダーの10進数値を16進数値に変換して1つテキストにする処理を追加。
今回は、結果的にこの処理は重要ではないので、説明は割愛させてくださいm(_ _)m
"#"
& Mid("0123456789ABCDEF", 1 + Mod(RoundDown(Slider_R.Value / 16, 0), 16),1)&Mid("0123456789ABCDEF", 1 + Mod(Slider_R.Value, 16),1)
& Mid("0123456789ABCDEF", 1 + Mod(RoundDown(Slider_G.Value / 16, 0), 16),1)&Mid("0123456789ABCDEF", 1 + Mod(Slider_G.Value, 16),1)
& Mid("0123456789ABCDEF", 1 + Mod(RoundDown(Slider_B.Value / 16, 0), 16),1)&Mid("0123456789ABCDEF", 1 + Mod(Slider_B.Value, 16),1)
& Mid("0123456789ABCDEF", 1 + Mod(RoundDown(Slider_A.Value / 16, 0), 16),1)&Mid("0123456789ABCDEF", 1 + Mod(Slider_A.Value, 16),1)
あとはこのテキストデータを SharePoint 側に登録します。
Submit ボタンの OnSelect 処理に以下を追記。
Patch(ColorSet, First(ColorSet),
{
ColorData: Label_SubmittedDataValue.Text
})
さて、これだけでは次回起動時に現在の SharePoint の設定値をスライダーに反映させる処理が入っていません。
よし追加するか…と思ったのですが、SharePoint 側のデータは16進数表記なので、
「あぁ今度は16進数を10進数に変換するのか。。クソめんどくさい。。」
ってなったんですよね。
で、ここで次の案が浮かんだのです。
「スライダーの RGBA の各値をそのまま SharePoint に保存し、SharePoint 側で10進数→16進数変換を行えば、読み書きの両方が楽になるのでは?」
と。
試行錯誤③ RGBA の各値を保存し、DB 側で RGB 16進表記に変換してみる
早速、まずは SharePoint 側に RGBA の各値を保存する列を数値型で追加します。
続いて、RGBA の各列を 16進数表記に変換する列 Hex を、集計列で作成します。
試行錯誤②で記述した変換処理をほぼそのまま集計列に移植するイメージです。
="#"
&MID("0123456789ABCDEF",1+MOD(ROUNDDOWN(R/16,0),16),1)&MID("0123456789ABCDEF",1+MOD(R,16),1)
&MID("0123456789ABCDEF",1+MOD(ROUNDDOWN(G/16,0),16),1)&MID("0123456789ABCDEF",1+MOD(G,16),1)
&MID("0123456789ABCDEF",1+MOD(ROUNDDOWN(B/16,0),16),1)&MID("0123456789ABCDEF",1+MOD(B,16),1)
&MID("0123456789ABCDEF",1+MOD(ROUNDDOWN(A/16,0),16),1)&MID("0123456789ABCDEF",1+MOD(A,16),1)
あとは、アプリ側の Screen の色設定はこの集計列 Hex を参照して…
続いて、アプリから SharePoint 側へ設定値を登録する際は RGBA の各値を登録させます。
Submit ボタンの OnSelect 処理を以下のように書き換えます。
Patch(ColorSet, First(ColorSet),
{
R: Slider_R.Value,
G: Slider_G.Value,
B: Slider_B.Value,
A: Slider_A.Value
})
そして、アプリの各スライダーの初期値は SharePoint のRGBA の各値を利用すれば…
…ん?
んんん???
こんなに煩わしい処理する必要ある??
ここでようやく、私は違和感に気が付いたのです。
試行錯誤④:RGBA の各値をそのまま読み書きする
①②③と試行錯誤を繰り返していて、「あれ?もしかして頑張って16進数変換とかして ColorValue 関数使わなくても、格納した RGBA の各値をそのまま色の設定に反映させたらよくね?」と気付いたのです。
ということで、やってみました。
Screen の Fill で、格納した RGBA の各値をそのまま RGBA 関数の各引数に代入します。
以下に書き換え。
RGBA(First(ColorSet).R, First(ColorSet).G, First(ColorSet).B, First(ColorSet).A)
なんだ。。これだけでできるんじゃん。。
読むのも書くのも、RGBA の各値をそのまま扱えばいいんじゃん。。
10進数と16進数の変換処理も、SharePoint 側のテキスト列も、集計列も、不要じゃん。。
今までの試行錯誤は一体。。
まとめ
色の設定をデータベースに保存したい場合は、RGBA の各値をそのまま保存し、そのまま色設定に反映させましょう。ちゃんちゃん。
ということで、私は度々このようなお恥ずかしい試行錯誤を繰り返しているのですが、何かの参考になればと思い、思い切って開示してみました。
今回に関しては、結果的には10進数を16進数に変換する処理を学べたので、よしとします。笑
何かヒントになれば幸いです。