Appsheet 覚書き- Enum List型について
上記のようなアプリを Google Appsheet で作成しているところです。
白ネギの収穫情報を記録して、正品率や収穫効率を見直すためのアプリとして作成しています。
EnumList型(Basetype:Ref型)に詰まる
今回やりたかったこと
別途運用中の日報入力アプリのデータベースから白ネギ収穫に該当するレコードを絞り込んでリストに。
そのリストを絞り込む関数式(下記参照)を [日報ID] Data Validity --> Valid if に記述してやることで、関連した日報IDを Enum List に列挙させます。
select(日報DB[ID],
and([日付]=[_THISROW].[収穫日],
[作目]="白ネギ",
[作業項目]="収穫",
[圃場]=[_THISROW].[圃場名]
)
)
入力したい記録と対応した日報レコードを選択しておき、これを参照することで他項目のForm入力をスムーズにしたい考えです。
EnumList型の項目に[日報ID]がリストとして記述されるが
想定していたように、複数選択可能なEnumList型のドロップダウンには、該当する[日報ID]のリストが表示されます。
そして、選択した項目には、
{"00000000","11111111","22222222"}
のようなIDの値を持つリストが入ります。
実際には、見出しとして設定した Label の項目がform上で表示されます。
ここまでは満足のいく挙動です。
次に、この[日報ID]を参照して、top画像にある[人数]を関数で自動入力しようとしました。
Web検索でAppsheetのコミュニティを検索してみると、少しAppsheetを触った人なら悩むこともないような簡単な記述がみつかります。
EnumList型の項目を単純にcount()する
count(
[_thisrow].[日報ID]
)
ただ、Basetype が Ref 型の EnumList だからでしょうか。
数えるだけの単純な式がうまく動きません。
検索しても正解にたどり着くことができませんでした。
ですが、Text型を無理やり List型 にできる split() を使ってみるという方法を発見しました。
count(
split([_thisrow].[日報ID],",")
)
これにより、EnumListで選択した数を計上できました。
計上はしたが、しかし
そもそもの話ですが、ここで本来やりたいのは「その日の収穫作業に従事した人数」の自動計算です。
じつは、日報データベースのテーブルでは、作業の入力を
午前の収穫作業 と 午後の収穫作業 を分けて入力される
ことがしばしばあります。
同じ作業者のレコードが複数回入力されている場合には、本来の作業者以上の人数が表示されてしまう。
つまり、これまでの関数式では、あくまで EnumList で選択されたレコードの数を数えることしかできていなかったのです。
じゃあRef型Listなんだし、「作業者」カラムでUnique関数するか
これまでそれなりにAppsheetはいじってきた私です。
それなら、と思いついたのが、[日報ID]カラムで選択された List を作業者名で重複を削除すればいいのでは、でした。
ですが、ここからが泥沼です。
[_thisrow].[日報ID]
ここまではわかります。
ここからどうやって「日報テーブル」の[作業者]カラムに触ればいいのかが分からずに時間をとられました。
[_thisrow].[日報ID].[作業者]
これだとエラー
[_thisrow].[日報ID][作業者]
これでもエラー
結局のところ VirtualColumn で解決
いろいろと試してみたところ、次の方法で解決しました。
EnumListで選択したRef先をリストにする仮想列をつくる
もともとRef型はListとして扱われる(?)ようですが、Listのデータ型はVirtualColumn(仮想列)でしか設定できないので、テーブル外の仮想列(リスト型)を追加します。
これにはもう一つ良いことがあって、DetailビューやFormビューでこの仮想列のテーブルを表示できるようになります。
重複した作業者を除いたリストを仮想列に作る
Select( [対応した日報DBのList][作業者] , true , true )
前述の仮想列に作ったListでは各カラムに対して参照することができました。
これで漸く、重複を除いた[作業者]リストを返すことができます。
これには Appsheet の頻出関数、Select関数の第3引数を利用します。
第2引数をTrueにしてしまうことで対象の全てのリストを選択しています。
この操作も一つの仮想列で完結できれば楽だったのですが、1つの仮想列で済ませようとするとエラーになってしまいました。
Virtual Column を駆使することで、アプリの挙動を円滑にしていくことの一例でしょうか。
EnumList型のBasetype : Ref型の扱いは設定項目が多く混乱しました。
備忘録として、また、誰かの何かの助けになれば幸いです。
追記:より簡潔に完結できました。
[_THISROW] にこだわり過ぎていた
EnumList型のRef先にアクセスするための簡単な記述に気づきました。
今回のケースで言えば、以下のように記述すれば良かったようです。
[日報ID][作業者]
Formで入力する際、入力した項目を参照するときに[_THISROW]をつけることが多いです。
なので私は
[_THISROW].[日報ID][作業者]
だろうと思い込み
select([_THISROW].[日報ID][作業者],true,true)
と記述してエラーが消えず、泥沼になっていました。
select([日報ID][作業者],true,true)
と [_THISROW] を取って記述してやることできちんと参照してくれました。
実際に人数カウントのカラムには以下の関数式を記述しました。
count(select([日報ID][作業者],true,true))
想定通りの挙動を示してくれたので、仮想列も不要となりました。
ただし、EnumListで選択したリストを子テーブルとして表示できるのはべんりだったので、今回でいうところの [対応した日報DBのList] の仮想列だけは残して運用していくつもりです。
結局自己解決してしまったのですが、記事にしながら正解にたどり着けたようなものなので、今後も適宜 note で備忘録的に記事にまとめてみようと思います。