見出し画像

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 で解決

 いろいろと試してみたところ、次の方法で解決しました。

この2項目のVirtualColumn(仮想列)を追加しました。
  • EnumListで選択したRef先をリストにする仮想列をつくる
     もともとRef型はListとして扱われる(?)ようですが、Listのデータ型はVirtualColumn(仮想列)でしか設定できないので、テーブル外の仮想列(リスト型)を追加します。
     これにはもう一つ良いことがあって、DetailビューやFormビューでこの仮想列のテーブルを表示できるようになります。

Ref先のテーブルが表示されるとアプリっぽさが増します。
  • 重複した作業者を除いたリストを仮想列に作る

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 で備忘録的に記事にまとめてみようと思います。