こんにちは!MSP岡本です。
時短に最適なGoogleのノーコードツールの一つであるAppSheetってなじみあるでしょうか?
今回は、AppSheetを使った実践型のタスク管理アプリ作成の第二弾。
第一弾が気になる方はこちらも要チェックです。
第二弾ではGASとAppSheetを組み合わせたものをご紹介。
それではれっつスタート!
1.そもそもAppSheetって何?
AppSheet(アップシート)とは、Googleが提供するノーコード開発プラットフォーム。
プログラミング不要で業務アプリを素早く作成できるツールとなっています。
特に強みとしてはGoogle Workspaceとの連携が挙げられます。
・日報
・タスク管理
・資格管理
・在庫管理
などなどです。
2.AppSheetの用語(応用編)

Data:スプレッドシートからのデータが表示される項目です。 「Table」は読み込んだシートのこと、「Columns」がスプレッドシートの1行目にある項目名を指します。

View:AppSheetで表示する方法を決めるView。縦にタスクを並べたいなら「table」形式がおすすめです。

Format rules:強調したい文字やアイコンや大きさ、色を指定する部分になります。 メリットとしては ・カテゴリーやステータスといった情報が一目瞭然 ・アイコンや強調文字でデータがすぐに見つかる

Actions:追加のボタンを作成、変更することができるページです。

Automation:いわゆるbotを使って一連の流れを自動的にやってくれる機能。 詳しくは作り方コーナーで解説します。

Intelligence:予測モデルを作成するのに役立つページ。今回作りたいものには使われない機能なので説明はパスします。

Security:データのアクセスやAppSheetを使える人を制限する機能です。 重要な設定ですが、AppSheetの大枠作るには全く必要ないので今回も割愛します。
3.作ってみよう!AppSheet(ハードモード)
では今回は資格の管理と学習タスクの連携を考えてみます。
1.スプレッドシートの準備
今回必要なスプレッドシートは二つです。
一つ目は資格を管理するシートでここでは「資格管理」とします。二つ目は学習タスクを管理する「計画」シートです。
まずはシートを準備します。
1-1.「資格管理」シートの準備
まずは新しいシートを準備し、ここへ取得したい資格の一覧を記載します。
スプレッドシートにはキャプチャのように「種別」「レベル」「資格」「取得日」「有効期限」「種別による有効期限の期限」「期限の有効有無」 「related_id」の項目を準備します。

1-2.「計画」シートの準備
スプレッドシートにはキャプチャのように「ID」「種別」「レベル」「タスク名」「目標完了日」「残り時間」「完了フラグ」の項目を準備します。

2.AppSheetの作成
2-1.スプレッドシートの情報をAppSheetに取り込む
ここまでで作ったスプレッドシートのデータを元にAppSheetを作成します。
キャプチャのようにスプレッドシート右上の「拡張機能」>「AppSheet」>「アプリを作成」を選択します。
一つ目のtableはアプリを作成した際に読み込まれます。

2-2.AppSheetの「資格管理」tableの設定
続いて「資格管理」tableの設定です。
ここではいくつかのセルで設定がいるので要注意です!
2-2-1.「種別」「レベル」の設定
まずは、「種別」から。
「種別」の列の左側にある鉛筆マークを開き、キャプチャのようにValuesを設定します。
この時、TypeはEnumを選択します。同じ要領で「レベル」の列の左側にある鉛筆マークを開き、キャプチャのようにValuesを設定します。


2-2-2.「related_id」「資格」「取得日」の設定
続いては「related_id」「資格」「取得日」の3項目の設定です。
ここでは、Typeをそれぞれ以下のように設定します。
また、「related_id」についてはKey?のチェックを入れ、Source tableを「計画」にします。
| 項目名 | Type |
| 資格 | Text |
| 取得日 | Date |
| related_id | Ref |

2-2-3.「有効期限」「期限の有効有無」の設定
「資格管理」tableの最後の2箇所を設定しましょう。
「有効期限」では資格の有効期間を管理したいと思います。
今回は、資格の「種別」としてAWSやGoogle,Oracleなどをセレクトしたので、種別とレベルに合わせて以下のような期間で有効期限が切れるように設定しました。中身としてはAWSは取得から3年、Googleは上位資格だと2年で有効期限が切れるといったような設定になっています。

IF(ISBLANK([取得日]),
"",
EOMONTH([取得日],
SWITCH([種別],
"Google", IF([レベル] = "高", 24, 36),
"Oracle", 18,
"AWS", 36,
"Azure", 12,
0
)
) - (EOMONTH([取得日], 0) - [取得日])
)
「期限の有効有無」の設定では、「有効期限」と「取得日」から計算して資格が有効かどうかを自動判定します。
ここでは有効・無効のいずれかで表す形にします。
そのため、「期限の有効有無」の鉛筆マークをあけて、Valuesにて期限状態ステータスを表す有効・無効を設定します。
また、tableのFormulaにキャプチャのように式を挿入すると有効期限と取得日から自動で資格のステータスが表示されるように設定できます。


2-3.AppSheetの「計画」tableの設定
続いて、AppSheetのtableタブの左上にある+ボタンを押します。
するとどこのソースからデータを読み込むか?を聞かれるので、「計画」シートを作ったスプレッドシートを選択ください。


2-3-1.種別」「レベル」の設定
「種別」の列の左側にある鉛筆マークを開き、キャプチャのようにValuesを設定します。
この時、TypeはEnumを選択します。同じ要領で「レベル」の列の左側にある鉛筆マークを開き、キャプチャのようにValuesを設定します


2-3-2.「ID」「タスク名」「目標完了日」の設定
「計画」のtableにある「ID」「タスク名」「目標完了日」の項目では、以下のような設定を行います。
| 項目 | Type |
| ID | Text |
| タスク名 | Text |
| 目標完了日 | Date |
また、「ID」についてはKey?のチェックを入れ,Initial Valueに
UNIQUEID()
を設定します。
2-3-3.「残り時間」の設定
「残り時間」のタブでは2箇所を操作します。
| Type | Formula |
| Number |
HOUR([目標完了日] - TODAY()) / 24 |
2-3-4「完了フラグ」の設定
「完了フラグ」の列の左側にある鉛筆マークを開き、キャプチャのようにValuesを設定します。
この時、TypeはEnumを選択します。また、Update Behaviorの項目下にあるEditable?で次の内容を記載します。

CONTEXT("ViewType") <> "Form"

2-3-5.sliceの設定
仮想テーブルを作る設定のためにはSliceの設定が必要です。
設定内容は以下になります。
2.「Slice Name」にステータスの名前を入れます
3.「Source Table」は「計画」を選択します
4.「Slice Actions」はAuto assignを選択します

2-4.AppSheetの「資格管理」のViewの設定
ここでは「資格管理」シートの見た目を整えていきます。手順は以下の通りです。
2.「Primary Navigation」で+ボタンを押下、Viewを追加します。
3.「View name」に「資格管理」と記入します。
4.「For this data」で「資格管理」のtableを選びます。
5.「View type」でtableを選択します。
6.「Group by」で「種別」を選び、値には「Ascending」を選びます。
このGroup byを行うことで、表示のまとまりを持たせることができます。
Viewの全体設定をキャプチャしたものが以下になります。

2-5.AppSheetの「計画」のViewの設定
ここでは「計画」シートの見た目を整えていきます。手順は以下の通りです。
2.「Primary Navigation」で+ボタンを押下、Viewを追加します。
3.「View name」に「計画」と記入します。
4.「For this data」で「計画」のtableを選びます。
5.「View type」でtableを選択します。
6.「Group by」で「種別」を選び、値には「Ascending」を選びます。さらに追加で「完了フラグ」を選び、値には「Ascending」を選びます。
このGroup byを行うことで、表示のまとまりを持たせることができます。
Viewの全体設定をキャプチャしたものが以下になります。
2-6.AppSheetのView設定(追加編)
Menu Navigationを作成する手順になります。
ここでは、「Menu Navigation」を追加して、普段は表示しないものの種別ごとにAppSheetにミニタブができるよう設定します。
2.「Menu Navigation」で+ボタンを押下、Viewを追加します。
3.「View name」に「ステータスの名前」を記入します。※ここでは完了、進行中、未完了のいずれかです。
4.「For this data」で「ステータスのスライス」のtableを選びます。
5.「View type」でtableを選択します。

2-7.AppSheetの「資格管理」のFormat rules設定
「Format rules」では文字列の色や背景色の設定を行うことができます。
今回は、有効化された資格、そうでないものを色でもわかりやすく見せるための設定を行います。
設定内容はこちら。
2.「Rule name」にネームを入れます。
3.「For this data」で「資格管理」のtableを選択します
4.「If this condition is true」にて有効・無効の時の設定をします。
#無効の時 [期限の有効有無]<>"有効" #有効の時 [期限の有効有無]="有効"
5. 「Format these columns and actions」で「期限の有効有無」を選択します。
6.Highlight colorもしくはText colorで背景色もしくは文字色を選びます。


3.AppSheetのAction設定
3-1.AppSheetの「資格管理」のAction設定
ここではバックグラウンドで動くボタンとフロント側で目に見えての役割を果たすボタンの2種類を作っていきます。
バックグラウンドで動くボタンの役目:別シートへのデータの受け渡しや関連付けなどを行うボタン。
フロント側からも見えるボタンの役目:フロント側で動かすためのボタン。主にステータス管理など。
「資格管理」ではシートを編集しないのでバックグラウンドのみ作成します。
3-1-1.「資格管理」のバックグラウンドアクションの設定
「資格管理」のバックグラウンド処理では、「計画」にて完了したタスクのうち、資格として取り扱われているものでその資格が有効化された日付を記録するための処理を行います。
手順は以下になります。
2.「Action name」に「別シートの取得日を更新する」といった感じで取得日更新のためのボタンであることを記載します
3.「For a record of this table」で「資格管理」を選択します
4.「Do this」で「Data:set the values of some columns in this row」を選択します
5.「Set these columns」で「取得日」を選択し、値に以下を記載します。
UTCNOW() + "009:00:00"
6.「Position」をHideにしてボタンを隠します。

3-2.AppSheet側「計画」のAction設定
ここではバックグラウンドで動くボタンとフロント側で目に見えての役割を果たすボタンの2種類を作っていきます。
バックグラウンドで動くボタンの役目:別シートへのデータの受け渡しや関連付けなどを行うボタン。
フロント側からも見えるボタンの役目:フロント側で動かすためのボタン。主にステータス管理など。
3-2-1.「計画」のバックグラウンドアクションの設定
1.「計画」の「Action」にて+ボタンを押下し、アクションを追加します。
2.「For a record of this table」にて「計画」を選択します
3.「Do this」にて「Data:set the values of some columns in this row」を選択します
4.「Set these columns」にて「完了フラグ」を選択し値に
"完了"
と記載します
5.「Position」をHideにしてボタンを隠します。
# アクション「呼び出し」について
1.「計画」の「Action」にて+ボタンを押下し、アクションを追加します。
2.「For a record of this table」にて「計画」を選択します
3.「Do this」にて「Data:execute an action on a set of rows」を選択します
4.「Referenced Table」にて「資格管理」を選択します
5.「Referenced Rows」にて以下の値を設定します。
FILTER("資格管理", [related_id] = [_THISROW].[ID])
6.「Referenced Action」にて「別シートの取得日を更新する」のアクションを設定する。
7.Position」をHideにしてボタンを隠します
8.「Behavior」の「Only if this condition is true」の値をtrueにします


1.「計画」の「Action」にて+ボタンを押下し、アクションを追加します。
2.「For a record of this table」にて「計画」を選択します
3.「Do this」にて「Data:add a new row to another table using values from this row」を選択します
4.「Table to add to」にて「資格管理」を選択します。
5.「Set these columns」で「related_id」「種別」「資格」「レベル」を選択します。
値とカラム名の組み合わせは以下参照ください。
| 項目名 | 値(計画より値を挿入) |
| related_id | [ID] |
| 種別 | [種別] |
| 資格 | [タスク名] |
| レベル | [レベル] |
6.「Position」をHideにしてボタンを隠します。
7.「Behavior」にて「Only if this condition is true」を設定します。値は以下参照ください。
IN([種別], LIST("Oracle", "AWS", "Google", "Azure","その他"))


3-2-2.「計画」のフロントアクションの設定
1.「計画」の「Action」にて+ボタンを押下し、アクションを追加します。
2.「For a record of this table」にて「計画」を選択します
3.「Do this」にて「Data:set the values of some columns in this row」を選択します
4.「Set these columns」にて「完了フラグ」を選択し値にします
"進行中"
と記載します
#ステータス「完了」について
1.「計画」の「Action」にて+ボタンを押下し、アクションを追加します
2.「For a record of this table」にて「計画」を選択します
3.「Do this」にて「Grouped:execute a sequence of actions」を選択します
4.「Actions」にて「完了ステ」と「呼び出し」を選択します


4.AppSheetのAutomation設定
ここでは手順の3で仕掛けたバックグラウンドアクションボタンを自動化した動きを行います。
設定は、「Automation」のタブを選択し、「When this EVENT occurs」にて「計画」tableを選ぶようにしながら適当なイベントネームを入れます。
次に、「Run this PROCESS」にて「Run a data action」を選択し、「種別管理/ID管理」のアクションを選択するだけです。
こうすることで、「計画」にて登録されたタスクのうち資格のみが「資格管理」に移動します。

5.スプレッドシートのGAS設定
スプレッドシート右上の「拡張機能」>「App Script」を選択し、次のコードをキャプチャのように入れます。

function createDailyTodoFromAppSheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('計画');
const data = sheet.getDataRange().getValues();
const rawHeaders = data[0].map(h => String(h).trim());
const colRemaining = rawHeaders.indexOf('残り時間 (h)'); // 厳密な名称一致
const colStatus = rawHeaders.indexOf('完了フラグ');
const colTaskName = rawHeaders.indexOf('タスク名');
if (colRemaining === -1 || colStatus === -1 || colTaskName === -1) {
throw new Error("必要な列が見つかりません。ヘッダー名を確認してください。");
}
const targetTasks = [];
for (let i = 1; i < data.length; i++) {
const row = data[i];
const taskName = row[colTaskName];
const status = String(row[colStatus]).trim();
const val = row[colRemaining];
// 空欄(Virtual Columnの結果が反映されていない等)はスキップ
if (val === "" || val === null || isNaN(val)) continue;
const remaining = Number(val);
if ((status === '未' || status === '進行中') && remaining <= 100) { targetTasks.push({name: taskName, val: remaining}); } } if (targetTasks.length > 0) {
targetTasks.sort((a, b) => a.val - b.val);
const topTask = targetTasks[0];
const taskTitle = "【TODO】" + topTask.name;
try {
const taskLists = Tasks.Tasklists.list();
if (!taskLists.items || taskLists.items.length === 0) {
console.error("タスクリストが見つかりません。");
return;
}
const taskListId = taskLists.items[0].id;
const newTask = Tasks.newTask().setTitle(taskTitle).setNotes(`AppSheetより自動生成 (残り時間: ${topTask.val}h)` ).setDue(new Date().toISOString());
Tasks.Tasks.insert(newTask, taskListId);
console.log(`成功: ${taskTitle}`);
} catch (e) {
console.error("Tasks API エラー: " + e.message);
}
}
}
次に、GAS画面の左側にある「サービス」から『TaskAPI』を選択して、押下します。

最後に、キャプチャの「トリガー」を選択し、画面の右下にある「トリガーを追加」ボタンをクリックします。
実行してもらうタイミングを設定し、保存します。


この時、認証の画面が出現します。Googleから「権限を確認」をされたら、ご自身のGoogleアカウントを選択してください。
「このアプリはGoogleによって検証されていません」という警告画面が出ることがありますが、個人アプリあるあるです。
個人の利用や特定チームのみで外部と共有して使わない場合は問題ないので、「詳細」>「[無題のプロジェクト] に移動」を選択します。
Googleアカウントで「アクセスを求めています」という許可画面が表示されます。「続行」ください。
4.完成
タスクの残期間が短くなると通知してくれる資格管理と計画AppSheetの完成です!
終わりに
いかがだったでしょうか?
AppSheetを使えば簡単なログとりやタスク管理、進捗管理ができてしまいます。
また今回のように複数組み合わせておけばメール通知はできなくてもカレンダー通知を無料で行うことができます!
| メリット | デメリット | |
| 某社ノーコードツール | 直観的に作れる | 人数にかかわりなく有料 |
| AppSheet | 個人レベルのタスクをAppSheetで管理するなら無料利用あり※ | UIから全てという意味では詳細カスタマイズができない。学習コストがかかる |
※個人アカウントでもAppSheetは利用可能です。ただし、アプリデプロイや10人を超える複数編集者の機能、メール通知には有料契約が必要です。
それぞれのニーズに合わせてツールを選んでみてください。
最後に、弊社アイレットでは、cloudpackというサービスでGoogle Cloud、AWSやOCIの移行、構築、設計、運用、請求代行などをサポートしております!最近リリースしたgaipackもお見逃しなく♪

