
- 操作環境:
- OS:Windows 11
- Webブラウザー:Google Chrome
- 使用プラン:Google Workspace Business Starter(AppSheet Core)(*)
*AppSheetのライセンスの種類毎の機能は、公式記事に掲載されています
- アプリ使用環境:
- OS:Android
- アプリ:Google AppSheet
要件・項目の整理
以前紹介したAppSheetによる執務日報アプリでも、簡易的なワークフロー機能を実装しました。
今回は一般的なワークフローの雛形として、執務日報アプリのワークフロー機能の要件に加え、以下の機能を含めたワークフロー申請アプリを作成します。
- 申請部署の切り替えにより、選択した申請部署の上長を承認者に設定できるようにする
- 公開設定により、申請部署内のデータであれば、申請者・承認者でなくても所属メンバーが閲覧できるようにする
- 承認期限の設定により、期限当日・超過がアプリ上で分かるようにするとともに、日次で承認者に処理依頼のリマインダメールを送付する
- 承認者のアクションとして、承認・差戻しに加え、否認も実施できるようにする
- 監査証跡用にフロー履歴(誰が・いつ・何のアクションを行ったのか)を保持する
- 問い合わせ用に申請データの一意な連番として申請Noを設け、新規データ作成時に採番する
このアプリで扱う項目は以下の通りとします。申請TBLに対し、添付ファイルTBLとフロー履歴TBLがそれぞれ1:nの関係性となります。
| 項目名 | データ種類 | 表示 | 必須 | 初期値 | 特記事項 |
|---|---|---|---|---|---|
| 申請ID | Text | 自動 | UNIQUEID() | KEY | |
| 申請No | Number | (*1) | 自動 | (*1) | LABEL、*1.新規作成保存時に申請Noの最大値+1(新規作成保存前は非表示) |
| 申請日 | Date | ○ | ○ | TODAY() | |
| 申請者 | Ref(UserMST) | ○ | 自動 | (*2) | *2.申請者のGWSのユーザー名(画面上は表示名) |
| 申請部署 | Enum | ○ | ○ | (*3) | *3.申請者のGWSの部署名 |
| 承認者 | Enum-Ref(UserMST) | ○ | ○ | (*4) | *4.申請者の上長のGWSのユーザー名(画面上は表示名)。上長不在時は*2と同じ |
| 非公開 | Enum | ○ | ○ | いいえ | 選択肢:いいえ,はい |
| ステータス | Enum | ○ | 自動 | 下書き | 選択肢:下書き,差戻し,処理待,承認済,否認済 |
| 件名 | Text | ○ | ○ | ||
| 申請内容 | LongText | ○ | ○ | ||
| 承認期限 | Date | ○ | |||
| コメントtmp | LongText | ||||
| 作成日時 | DateTime | ○ | 自動 | NOW() | |
| 作成者 | Ref(UserMST) | ○ | 自動 | (*5) | *5.作成者のGWSのユーザー名(画面上は表示名) |
| 更新日時 | DateTime | ○ | 自動 | NOW() | |
| 更新者 | Ref(UserMST) | ○ | 自動 | (*6) | *6.更新者のGWSのユーザー名(画面上は表示名) |
| 項目名 | データ種類 | 表示 | 必須 | 初期値 | 特記事項 |
|---|---|---|---|---|---|
| ファイルID | Text | 自動 | UNIQUEID() | KEY | |
| 申請ID | Ref(申請TBL) | ○ | 自動(*1) | *1.申請TBLから引継ぐため変更不可 | |
| ファイル | File | ○ | LABEL | ||
| メモ | LongText | ○ | |||
| 作成日時 | DateTime | ○ | 自動 | NOW() | |
| 作成者 | Ref(UserMST) | ○ | 自動 | (*2) | *2.作成者のGWSのユーザー名(画面上は表示名) |
| 更新日時 | DateTime | ○ | 自動 | NOW() | |
| 更新者 | Ref(UserMST) | ○ | 自動 | (*3) | *3.更新者のGWSのユーザー名(画面上は表示名) |
| 項目名 | データ種類 | 表示 | 必須 | 初期値 | 特記事項 |
|---|---|---|---|---|---|
| フロー履歴ID | Text | 自動 | UNIQUEID() | KEY | |
| 申請ID | Ref(申請TBL) | ○ | 自動(*1) | *1.申請TBLから引継ぐため変更不可 | |
| アクション | Enum | ○ | 自動 | 選択肢:申請,申請取消し,差戻し,承認,否認 | |
| アクション者 | Ref(UserMST) | ○ | 自動 | (*2) | *2.アクション者のGWSのユーザー名(画面上は表示名) |
| コメント | LongText | ○ | 申請TBLのコメントtmpの値 | ||
| 作成日時 | DateTime | ○ | 自動 | NOW() | |
| 作成者 | Ref(UserMST) | ○ | 自動 | (*3) | *3.作成者のGWSのユーザー名(画面上は表示名) |
| 更新日時 | DateTime | ○ | 自動 | NOW() | |
| 更新者 | Ref(UserMST) | ○ | 自動 | (*4) | *4.更新者のGWSのユーザー名(画面上は表示名) |

添付ファイルTBLのファイル項目は、保存先のファイル名(パスを含む)を格納します。実際のファイルはGoogleドライブに保存します。

図表1-5 ステータス遷移
| メニュー | 利用者 | データ条件 | 更新アクション |
|---|---|---|---|
| 申請前 | 全員 | [ステータス]が"下書き"か"差戻し"で、[申請者]が利用者本人 | 申請、追加、編集、削除 |
| 申請取消し | 全員 | [ステータス]が"処理待"で、[申請者]が利用者本人 | 申請取消し |
| 処理待 | 上長 | [ステータス]が"処理待"で、[承認者]が利用者本人 | 承認、差戻し、否認 |
| 処理済 | 全員 | [ステータス]が"承認済"か"否認済"で、 [申請者]が利用者本人か、[承認者]が利用者本人か、 [非公開]が"いいえ"で[申請部署]が利用者の所属部署 |
|
| 閲覧 | 全員 | [申請者]が利用者本人か、[承認者]が利用者本人か、 [非公開]が"いいえ"で[申請部署]が利用者の所属部署 |
以前の記事で紹介したAppSheetの契約書管理アプリと同じ機能について、仕様を若干変更していますので、補足説明します。
| 機能 | 当アプリ【A】 | 契約書管理【B】 | 仕様補足 |
|---|---|---|---|
| 自動採番 | 申請No:申請データの新規作成時、保存を契機に採番 | 契約書コード_親:契約書データの新規作成時、登録画面の初期値として設定 | 【A】は大人数が使用する想定のため、同時に申請データの新規作成が行われたとき、自動採番の値の重複が起こらないよう考慮した。【B】は法務担当者のみ使用する想定 |
| ファイル添付 | 申請データ保存後に設定 | 契約書データの保存前/保存後ともに設定可 | 【A】【B】ともにファイル保存先のサブフォルダー名に自動採番の値を使用している。【A】は申請データの保存後に自動採番の値が決まるため、申請データの保存後に添付ファイルを設定する方式とした |
アプリの完成イメージ
先にアプリの完成イメージを紹介します。
まずは申請者による申請データの作成を行います。
- 左:[申請前]メニューをタップし、[+]をタップします。
*[申請前]メニューには、[ステータス]が"下書き"か"差戻し"で、申請者がアプリユーザーの申請データが表示されます
- 中:登録画面が表示されます。[申請部署]の初期値は[申請者]の所属部署、[承認者]の初期値は[申請者]の上長となり、それらは変更できます。
*[承認者]はGoogle Workspaceのユーザー情報にある[マネージャーのメール]という項目から取得しています。この項目が未設定(承認者が不在)の場合は、申請者本人を初期値とします
- 右(補足):[申請部署]を変更すると、その部署の上長が[承認者]のリストに表示されます。[承認者]が[申請部署]の上長でない場合、[Save]時やリスト選択時にエラーメッセージが表示されま。なお、上長が不在かつ自身が上長でないユーザーが申請する場合、選択した[申請部署]の上長にあたる人を誰かしら選択する想定です。

- 左:登録画面の下半分です。[非公開]・[件名]・[申請内容]・[承認期限](任意)を選択・入力し、[Save]をタップします。
*[非公開]が"いいえ"の場合、[処理済]メニューや[閲覧]メニューで、アプリユーザーが[申請者]か[承認者]のデータに加え、[申請部署]がアプリユーザーの所属部署のデータが表示されます*[承認期限]を設定すると、期限当日・超過の未処理データがアプリ上で目立つよう表記されたり、承認者に処理依頼のリマインダメールが日次送付されたりします
- 中:一覧画面に[Save]した申請データが表示されたら、これをタップします。
*各データの左上の[No.]の数字が[申請No]で、申請データを新規作成し[Save]すると自動採番されます
- 右:詳細画面下部に[添付ファイル]の欄が表示されますので、[Add]をタップします。

- 左:添付ファイルの登録画面が表示されたら、ファイルアイコンをタップします。
*[申請No]は申請データの詳細画面から引継がれます
- 中:添付ファイルを選択後、[Save]をタップします。
*[Save]後にファイル名が変わるため、メモ欄に元のファイル名の記載を推奨します
- 右(補足):[Add]をタップすると、さらに添付ファイルを追加できます

申請者による申請(承認者への処理依頼)と、申請取消し、再申請を行います。
- 左:[申請前]メニューの一覧画面に戻り、[申請]アイコンをタップします。
*[申請者]と[承認者]が同じ場合、[申請]アイコンをタップすると、ステータスは即時に"承認済"になります*[申請]は、データを選択して詳細画面を開き、そこからでも実施できます
- 中:コメント事項があれば適宜入力し、[Save]をタップします。
- 右:[申請取消し]メニューをタップすると、今申請したデータが表示されます。承認者の処理待状態であれば、ここから申請を取消し、下書き状態に戻すことができます。[申請取消し]アイコンをタップします。
*[申請取消し]メニューには、[ステータス]が"処理待"で、[承認者]がアプリユーザーの申請データが表示されます*[申請取消し]は、データを選択して詳細画面を開き、そこからでも実施できます

承認期限が設定されている場合は、一覧画面のNoの右にカッコ書きで表示されます。さらに承認期限が当日以前の場合は赤文字で表記となります。
また、[非公開]を"はい"とした場合は鍵マークが表示され、申請者・承認者以外のアプリユーザーにはデータが表示されません。
- 左:確認メッセージが表示され、[申請取消し]をタップすると、申請取消しが確定します。
*[NO]をタップすると[申請取消し]は行われません
- 中:コメント事項があれば入力し、[Save]をタップします。
- 左:[申請前]メニューに申請を取消したデータが表示されます。データ修正後、[申請]アイコンをタップし、必要に応じてコメントを入力し(画面割愛)、承認者の処理に進みます。
*[申請前]メニューでは、申請データだけでなく、添付ファイルの追加・変更・削除も実施できます

承認者による差戻し、再申請、承認者による承認を行ってみます。
- 左:承認者は[処理待]メニューが表示されます。これをタップすると、"処理待"の申請データが表示されます。データをタップして詳細画面を開きます。
*[処理待]メニューには、[ステータス]が"処理待"で、[承認者]がアプリユーザーの申請データが表示されます*一覧画面の[承認]・[差戻し]・[否認]アイコンからも処理することができます
- 中:詳細画面が表示されたら、[差戻し]アイコンをタップします。
- 右:確認メッセージが表示され、[差戻し]をタップすると、差戻しが確定します。
*[NO]をタップすると差戻しは行われません

- 左:コメント事項があれば入力し、[Save]をタップします。
- 中:[申請前]メニューに差戻された申請データが表示されます。データ修正後、[申請]アイコンをタップし、必要に応じてコメントを入力し(画面割愛)、承認者の処理に進みます。
- 右:承認者が[処理待]メニューをタップすると、再申請されたデータが表示されます。データをタップして詳細画面を開きます。

- 左:詳細画面が表示されたら、[承認]アイコンをタップします。
- 中:確認メッセージが表示され、[承認]をタップすると、承認が確定します。
*[NO]をタップすると承認は行われません
- 右:コメント事項があれば入力し、[Save]をタップします。

否認の操作は承認と同じなので割愛します。否認は差戻しと違って修正・再申請ができません。
- 左:[処理済]メニューに"承認済"や"否認済"の申請データが表示されます。データをタップして詳細画面を表示してみます。
*[処理済]メニューには、後述の[閲覧]メニューの表示条件のうち、[ステータス]が"承認済"か"否認済"の申請データが表示されます*"承認済"や"否認済"となった申請データの変更や削除はできません
- 中(補足):詳細画面の下の方にフロー履歴が表示されます。
- 右:[閲覧]メニューは[申請者]か[承認者]がアプリユーザーの申請データと、[非公開]が"いいえ"なら[申請部署]がアプリユーザーの所属部署の申請データが表示されます。[ステータス]に関わらず、このメニューではデータの変更はできません。

- 左:添付ファイルを追加・変更・削除したい場合は、[申請前]メニューで対象の申請データの詳細画面を表示します。追加は[Add]から実施できます。変更・削除は対象の添付ファイルをタップします。
*申請後の場合、ファイルアイコンから添付ファイルの閲覧やダウンロードのみ実施できます
- 中:添付ファイルの詳細画面が表示され、ここでも変更・削除ができます。
- 右:添付ファイルは、共有ドライブの[IT管理]下の、[WF添付ファイル>{申請Noのゼロ出し6桁}]フォルダーの下に格納しています。
*今回のアプリでは、誤操作によるファイル喪失を避けるため、変更・削除前のファイルも共有ドライブに残し、添付ファイルTBLのデータのみ変更・削除しています。不要ファイルを物理的に削除したい場合は、添付ファイルTBLに記録されていないファイルを物理削除するGASを定期実行するなどの対応が必要です

最後は通知メールの紹介です。
各通知メール下部の[アプリで確認する]ボタンをクリックすると、対象データの詳細画面を表示するようになっています。
- 左:申請者が申請を実行した時、承認者(CC:申請者)に処理依頼メールが送付されます。
- 右:承認者が差戻しを実行した時、申請者に差戻し通知メールが送付されます。

- 左:承認者が[承認]を実行した時、申請者に承認済通知メールが送付されます。
*否認済通知メールは"承認"が"否認"に置き換わるだけで内容は同じです
- 右:承認期限が当日以前の"処理待"の申請データについて、毎日定刻に承認者(CC:申請者)に処理依頼のリマインダメールが送付されます。

Googleスプレッドシート用意
この例では、データソースとなるGoogleスプレッドシートをGoogleドライブの共有ドライブの[IT管理]に用意します([新規>Googleスプレッドシート>空白のスプレッドシート]から新規作成できます)。

ファイルを開き、出力先シートとして[ユーザーMST]シートを作成します。
データは工程4のGoogle Apps Script(以降GASと表現します)で取得しますので、空白で問題ありません。
URLの「spreadsheets/d/xxxxxx/edit?」のxxxxxx部分(シートID)の値を控えておきます。

[申請TBL]シートを用意し、工程1の図表1-1の項目定義に従い、一行目の項目名を記載します。
画面イメージのデータはサンプルなので、空行で問題ありません。

[添付ファイルTBL]シートを用意し、工程1の図表1-2の項目定義に従い、一行目の項目名を記載します。
画面イメージのデータはサンプルなので、空行で問題ありません。

[フロー履歴TBL]シートを用意し、工程1の図表1-3の項目定義に従い、一行目の項目名を記載します。
画面イメージのデータはサンプルなので、空行で問題ありません。

Google Apps Script作成
GASのホーム画面にアクセスし、[新しいプロジェクト]を選択します。
左端の歯車アイコン(プロジェクトの設定)を選択し、画面の下の方にある[スクリプト プロパティを追加]を選択します。

工程3で控えたGoogleスプレッドシートのシートIDを定義し、[スクリプトプロパティを保存]を選択します。
左端のコードアイコン(コードエディタ)を選択し、[サービス]の右の[+]アイコンを選択します。

[Admin SDK API]を選択し、[追加]を選択します。
左メニューの[サービス]の下にサービスが追加されました。

スクリプトエディターのコード.gsにスクリプトを記述していきます。

/**
* GoogleWorkspaceのユーザー情報(マネージャー,部署含む)をスプレッドシートに出力する(定期更新)
*/
function getUserAndManagerAndDept() {
const ss = SpreadsheetApp.openById(PropertiesService.getScriptProperties().getProperty("sheet_id"));
const sheet = ss.getSheetByName("ユーザーMST");
sheet.clear();
// AppSheet用のヘッダー
sheet.appendRow(["ID", "DisplayName", "Manager", "Dept"]);
const users = AdminDirectory.Users.list({
customer: 'my_customer',
maxResults: 500
}).users;
if (!users) return;
let masterList = [];
// ユーザー(個人)をリストに追加し、同時に部署名をセットに格納
users.forEach(user => {
const name = user.name.fullName;
const dept = (user.organizations && user.organizations[0].department) ? user.organizations[0].department : "";
// 上長の情報を探す
let managerEmail = "";
if (user.relations) {
const managerRelation = user.relations.find(rel => rel.type === "manager");
if (managerRelation) {
managerEmail = managerRelation.value; // ここに上長のID(メールアドレス)が入る
}
}
// 個人をリストに追加(IDはメールアドレス)
masterList.push([user.primaryEmail, name, managerEmail, dept]);
});
// スプレッドシートに書き込み
if (masterList.length > 0) {
sheet.getRange(2, 1, masterList.length, 4).setValues(masterList);
}
}
スクリプト実装後、左端の時計アイコン(トリガー)を選択し、画面右下にある[トリガーを追加]を選択します。
この例ではgetUserAndManagerAndDept()を毎日午前0-1時に実行することとし、以下のように設定し、[保存]を選択します。
- 実行する関数を選択:getUserAndManagerAndDept
- イベントのソースを選択:時間主導型
- 時間ベースのトリガーのタイプを選択:日付ベースのタイマー
- 時刻を選択:午前0時~1時(GMT+09:00は日本時間)

GAS実行後のGoogleスプレッドシートの出力結果を確認します。
[申請者]・[申請部署]・[承認者]・[アクション者]・[作成者]・[更新者]のマスターとして使用する想定です。

Google AppSheet アプリ作成
この例では工程3で用意したGoogleスプレッドシートのデータを元にアプリを作成します。
AppSheetのホーム画面にアクセスし、[+Create]を選択し、[App>Start with existing data]を選択します。
以下の通り入力し、[Choose your data]を選択します。
- App name:ワークフロー申請
- Category:Other

[Google Sheets]を選択します。
工程3で用意したGoogleスプレッドシートのファイルを選択し、[Select]を選択します。

左端アイコンの[Data]を選択すると、[申請TBL]のみ追加されています。他データを追加するため、左メニューの[Data]行の右の[+]を選択します。
[Google Sheets]を選択します。もしくは、この画面例のように[Add Table "(追加対象シート)"]が表示される場合はこれを選択でも構いません。

工程3で用意したGoogleスプレッドシートのファイルを選択し、[Select]を選択します。
以下の通りデータに対するアクセス権を変更し、[Add 3 tables]を選択します。
- フロー履歴TBL:Add
- ユーザーMST:Read-only
残りのシートのデータが追加されることを確認します。

左端の歯車アイコン([Settings])を選択し、左メニューの[Information]を選択し、以下の通り設定します。
- Default app folder:/googledrive/shared_drives/IT管理
これにより、添付ファイルが工程3で用意した共有ドライブ[IT管理]の下に保存されるようになります。

次の記事では、引き続きAppSheetの設定を進めます(Data,Actions) 。
当ブログ内の関連記事