AppSheetのRelated xxxxのAddボタンを非表示にしたい
AppSheetで経費申請系のワークフローアプリを作っていた時、申請提出後にまだ承認作業をしていないのに、リレーションで接続させた明細側の内容を申請者が勝手に追加出来てしまう。なので申請提出後はAddボタンを非表示にしたい(ステータスに応じて切り替える)。
しかしこれが一筋縄でいかないものでした。ということでこの制御方法についてまとめてみました。
目次
今回利用するサンプル等
- ステータスに応じてAdd出来なくする - AppSheet
通常の申請→承認という1段階の経費申請ワークフローです。最終的に申請側は申請実行のボタンをクリックする事で提出されて、承認側に届く仕組みになっています。
GASも使っておらず、今回の課題になる部分以外では複雑な仕組みとしては
- アクセスしてきてるユーザの役割に応じて承認ビューを表示切り替えする
- 申請・承認は同一テーブルに対してビューをセットしてるので、UserTriggerとAdminTriggerでAutomationの実行判定をしてる
の2つになります。これらは以下のエントリー内で解説しておりワークフローアプリを作る場合には必須の仕組みとなります。
※現在サンプルプロジェクト別途準備中
解決したい課題の詳細
ぶつかった課題
経費の申請ワークフローである為、テーブル構成としては申請・明細の2つで構成されています。この時、申請側が申請内容とそれにぶら下がる複数の経費項目を明細に追加する仕組みになっています。申請と明細の間は申請ID列をもってRefでリレーションシップが張られており、よくあるスタイルです。
問題はこれはワークフローアプリであり、申請を提出したら管理者により承認されるまでの間は申請者に申請内容について編集させたくない。
過去にEditボタンやDeleteボタンについてはステータス欄の値を元に、Actionsのボタンに対して条件判定をして非表示にすることは出来ました(申請テーブル側)。しかし、Related xxxxとして表示されてる中のAddボタン(追加ボタン)については同じ数式をセットしても正しく動作せず。
Related xxxxで表示されてる中身は明細テーブル側となり、このAddボタンを申請側のステータスが未申請と差し戻しの場合は表示し、申請中と完了の場合は非表示にしたいのが課題です。
図:明細側のAddボタンを消すのが目的
分析してみた
これまでの制御処理
EditボタンやDeleteボタンは申請側にあるので、以下の数式をBehaviorのOnly if this condition is trueにて、以下のような数式を入れることでステータスに応じて表示・非表示を実現出来ています。
1 2 3 4 5 6 |
SWITCH( CONTEXT("VIEW"), "申請者用_Detail", if(IN([ステータス], {"申請中", "完了"}),false,true), "承認者用_Detail", false, false ) |
申請者用_Detailのビューが対象のビューとなり、Switch関数およびContext関数にてビュー単位で判定し、ここでステータスを元にIN関数で調べて、申請中と完了の場合はfalseつまり非表示にするという処理を実現しています。
しかし、同様の関数の仕組みで明細側のAddボタンに対してセットしてみても、申請側のステータスに基づいて判定し、表示・非表示のコントロールをしてくれません(リレーションしてるので値は見えている)。
IFS関数を使って似たような処理を実装してみましたが、同様に作動せず。
図:申請中は追加ボタンは非表示にしたい
コミュニティでの解答
全く同じような内容の問い合わせがAppSheetのコミュニティに投稿されていました。この中での解答によると、EditやDeleteのような親フォーム側にあるボタン類は前述のように1レコード内にある情報であるため、関数で条件判定をして表示非表示が可能。しかし、明細側のように複数レコードの含まれるサブフォーム側の場合は、行レベルアクションでは無い為、ステータス欄を元に判定させての表示非表示が出来ないようです(複数レコードある為、どのステータスか特定出来ない)。
Lookup関数で申請IDを元に判定もしてみましたが、同様に表示制御は出来ませんでした。
コミュニティ内の解答は読み取り専用のスライスを作って、列に対して表示・非表示を数式で判定させるという手法がありましたので今回これを実装してみました。
AppSheetで実装する方法
今回のステータスに応じてAddボタンを非表示にするという仕組みは、ボタン非表示という観点から言うと実現出来ません。よって、考え方を変えてステータスに応じて2つのRelated xxxxを切り替えるという仕組みで実装します。
明細に読み取り専用のスライスを作成する
すでに明細テーブルから申請テーブル側に対して、申請ID列を元にリレーションを張っている為、申請テーブルには書き込み可なRelated xxxxという名前のList型仮想列が追加済みです。
それとは別に明細テーブルに以下の手順で読み取り専用のスライスを作成します。
- 左サイドバーのDataに於いて明細テーブルを選択し、隣の+ボタンをクリックする(Add slice to filter dataという名前)
- Create a new slice for 明細をクリックする
- Slice Nameを適当に入力する(明細ReadOnlyと命名しました)
- Row filter conditionは特に入力しない
- Update modeはReadOnlyを選択する
- 右上のSAVEボタンをクリックして保存する
図:読み取り専用の明細スライスを作る
申請テーブルに仮想列で追加する
前述で作成した明細ReadOnlyのスライスを申請テーブル側に対して、Related xxxxと同様に仮想列で追加します。
- 申請テーブルをクリックし、上部メニューのAdd virtual Columnという+ボタンをクリックする
- Column Nameは適当に入力する
- 数式は以下のような数式を入力する
1REF_ROWS("明細ReadOnly", "申請ID")
Related xxxxも同様の仕組みで、自動的にTypeはList型となり、Element TypeはRefになります。 - Doneをクリックする
- 右上のSAVEボタンをクリックして保存する。
これで申請には2つのList型のサブテーブル参照の仮想列が用意出来ました。
図:手動でRefとして参照する仮想列を追加する
列のShowを数式で判定させる
今回の課題のテーマで一番の肝であり、ハマりどころだったのが「列を数式で表示・非表示させる」手法。2つのList型の仮想列に対してそれぞれに対して条件式で表示非表示させることが可能です。
- まずは、Related 明細sの列の隣の鉛筆ボタンをクリックする(リレーションで自動作成される列)
- Showがチェックボックスなのですが、実はここの右にあるフラスコアイコンをクリックすると数式入力になります。
- テキストボックスをクリックして以下の数式を入力する(基本falseで申請者用_Detailが条件に合った時はfalse,そうでない時にだけtrueとする)
123456SWITCH(CONTEXT("VIEW"),"申請者用_Detail", if(IN([ステータス], {"申請中", "完了"}),false,true),"承認者用_Detail", false,false) - Doneをクリックして保存する
- 次に、前述で手動で追加した仮想列の隣の鉛筆マークをクリックする
- 同様にShowのフラスコアイコンをクリックして数式入力にする
- テキストボックスをクリックして以下の数式を入力する(前述とは反対の結果になる数式にするのがポイント)
123456SWITCH(CONTEXT("VIEW"),"申請者用_Detail", if(IN([ステータス], {"申請中", "完了"}),true,false),"承認者用_Detail", true,false) - Doneをクリックして保存する
- 右上のSAVEボタンをクリックして保存する
列表示がこれで表示・非表示となるので結果的に、未申請時の状態の時は書き込み可能な明細テーブルが表示され、申請中の場合は読み取り専用の明細スライスが表示されるようになり、結果的にAddボタンが消えたのと同じ結果を得ることが出来ました。
これで申請中に申請者が勝手に明細に追加するであったり、完了してるのに追加しちゃうなどを防ぐことが可能になります。
図:ここをクリックすると数式入力になる
図:列表示を数式で制御出来る
未処理の承認がある場合に赤バッジを表示
x.comではAppSheetに関する様々なテクニックの紹介や現場での取り組みが投稿されています。その中で、AppSheetには備わっていない機能を現場ならではの発想で装備された方がいました。
未処理の承認がある場合には、承認タブの名前に赤い🔴を表示することで、未処理のものがあるというのが一目でわかるテクニックです。今回のケースでは、「承認シートに於いて、ステータスが申請中のものをカウントして0だったら通常表示、そうでない場合は赤い🔴を追記」ということを関数で実現しています。
タブのDisplay Nameの数式で以下のような判定を入れてみました。
1 |
IF(COUNT(SELECT(申請[申請ID],[ステータス]="申請中")) = 0,"承認","承認 🔴") |
こうすることで、以下のスクショのように、データがある場合にはバッジ表示が擬似的について利用者によっていち早く情報を認知し、処理し忘れを防止することが可能です。
図:数式でバッジ表示を制御
図:実際にバッジ表示してみた
かんたん #AppSheet 小技!
View名の所に通知バッチみたいなものが有ると
分かりやすくて良いですよね🐼そんな時に「Display name」に
ちょっと関数を書いておくと…かんたんに設定ができますね!
(もちろん工夫次第で、いろいろな通知バッチが作れますね1⃣~9⃣) pic.twitter.com/cxS9vMD1dh— ヤスス(本田康志)🐼介護×ICT (@hy_11) April 11, 2025