結論

AppSheetとは、スプレッドシートなどの表から、コードを書かずに業務アプリを作るGoogleのサービスです。読み方は「アップシート」です。

この記事でわかること

  • 料金4プランとWorkspaceで無料になる条件
  • 列の型37種・関数35個の早見表
  • キーとRef型をSQLで組んだ実物と崩れる例5つ

2026年10月22日更新|PostgreSQL 16.15・Python 3.11で表の設計を実行

AppSheet のアプリは、表(データ)を読み込むところから始まり、列の型を決め、画面(ビュー)とボタン(アクション)を足し、最後に自動処理(オートメーション)を足す順で組み上がります。

flowchart TD
    A[データ スプレッドシートなど] --> B[テーブル 1シート=1表]
    B --> C[列の型 Text・Date・Ref など]
    C --> D[ビュー 一覧・詳細・フォーム]
    D --> E[アクション ボタンで値を変える]
    E --> F[オートメーション 通知・定期実行]

急ぎの人向けに、よく調べられる点を先にまとめます。

知りたいこと 答え 例・補足
料金 1ユーザー月額 Starter 5ドル・Core 10ドル・Enterprise Plus 20ドル 2026年10月22日時点
無料で使えるか 開発とテストは作成者を含め10人まで無料 業務で配るには有料
Google Workspace Business Starter など多くのエディションに Core が含まれる 追加料金なし
作り方 スプレッドシートの[拡張機能]→[AppSheet]→[アプリを作成] 1行目が列名になる
表どうしのつなぎ方 Ref 型の列に、相手の表のキーの値を入れる [備品ID].[備品名] で値を引く
キー 初期値 UNIQUEID() の ID 列を作る 行番号はキーに向かない
使える端末 iOS・Android の AppSheet アプリとブラウザ バーコードはアプリのみ
データの上限 1アプリの圧縮後データ5MBか10MB(端末による) シートは10万行・1,000列まで
Power Apps との違い 元にするデータと料金の数え方が違う 下の比較表

確認環境:Ubuntu 24.04.4・PostgreSQL 16.15・Python 3.11.15・requests 2.34.2・curl 8.5.0。AppSheet の元になる表(キー・Ref に当たる外部キー・逆参照・行番号キーのずれ・名前での参照)は PostgreSQL 16 で組んで実行し、CSV に書き出したシートの点検は Python で実行しました。AppSheet API に送るリクエストは、自作の擬似サーバーで受けて中身を記録しました。AppSheet の画面の名前・列の型・関数・料金・制限は AppSheet ヘルプ(日本語版・英語版)と about.appsheet.com の料金ページで、Power Apps・kintone・Bubble は各公式ページで確かめました(確認日 2026年10月22日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「AppSheetとは|使い方・料金・関数とRef型の表設計を実例で解説」

AppSheetとは(読み方・できること)

この節では、AppSheet がどんなサービスで、何ができるかが分かります。

AppSheet(アップシート)は、Google が提供するノーコードのアプリ開発サービスです。 Google スプレッドシートなどの表を読み込むと、一覧・詳細・入力フォームを持つアプリが自動で作られ、スマホ(iOS・Android)とブラウザで使えます。プログラムは書かず、列の型の設定と、スプレッドシートの関数に似た「式」で動きを決めます。

項目 内容
提供 Google(Google Cloud)
生まれ 2014年に米国シアトルで創業。2020年1月14日に Google Cloud による買収を発表
作れるもの 業務アプリ(入力・一覧・承認・在庫・点検など)、チャットアプリ
使う場所 iOS・Android の AppSheet アプリ、パソコンやスマホのブラウザ
料金 1ユーザー月額5ドルから。Google Workspace の多くのエディションに Core が含まれる

1表からアプリを作る

スプレッドシートの1シートが1つの表になり、1行目の見出しが列名になる。最初の画面は自動で作られる。

2スマホの機能を使える

写真・署名・位置情報・バーコード読み取り・オフラインでの入力。外での点検や棚卸しに向く。

3自動で通知・処理する

データの変更や決まった時刻をきっかけに、メール・通知・PDF 作成・Webhook を動かせる。

4Google Workspace とつながる

スプレッドシート・フォーム・ドライブ・カレンダー・Gmail のデータを使える。Gemini でアプリの下書きも作れる。

AppSheetのメリットとデメリット

向いている点

コードを書かずに、表から数分で動くアプリができる

スマホ対応・オフライン入力・写真・署名が最初から使える

Workspace を使う会社は Core を追加料金なしで使える

気を付ける点

画面の見た目の自由度は、ビューの種類と設定の範囲にとどまる

1アプリのデータは圧縮後5MBか10MBまで。大量のデータは向かない

英語の情報が中心。型名・関数名・設定名は英語のまま

式と表の設計は覚える必要がある。多数のシステムをつなぐ連携は、連携専用のサービスと役割を分けることもある

AppSheetで作れるアプリの例

この節では、AppSheet がよく使われる業務と、そのときの表の形が分かります。

アプリ 元にする表 よく使う機能
備品の貸出管理 社員・備品・貸出 Ref 型、返却日の空欄で「貸出中」を判定
在庫・棚卸し 商品・入出庫 バーコード読み取り、合計の仮想列
日報・作業報告 社員・日報 写真・署名・位置情報、フォーム
設備点検 設備・点検記録 オフライン入力、異常時のメール通知
申請・承認 申請・承認履歴 アクション(承認ボタン)、オートメーション
顧客・案件管理 顧客・案件・活動 地図ビュー、ダッシュボード
予約・受付 部屋・予約 カレンダービュー、重複のチェック(Valid if)
タスク管理 担当者・タスク スライスで「自分の未完了」だけ表示

つなげるデータ(データソース)

ヘルプ(日本語版)「データソースの管理」に載っている主なデータソースです。

区分 データソース
ネイティブ AppSheet データベース
スプレッドシート Google スプレッドシートなど
データベース MySQL・PostgreSQL・SQL Server・Oracle・MariaDB・Google BigQuery・AWS DynamoDB・オンプレミスのデータベース
その他 Google フォーム・Google カレンダー・Gmail・Google ドライブ・Box・Dropbox・Salesforce・Smartsheet・Airtable・OData・Apigee・Looker Studio

料金ページでは、Salesforce・BigQuery・OData・Apigee・REST API などの接続は Enterprise Plus の機能です。

この記事では、いちばん上の 備品の貸出管理 を例にして、表の設計から式・ビュー・オートメーションまでを通して説明します。

AppSheetの料金と無料で使える範囲(2026年10月22日時点)

この節では、AppSheet のプランごとの料金と、無料で使える範囲、Google Workspace に含まれる条件が分かります。

AppSheet の料金は、アプリを使う人数(ユーザー数)に対して1人あたり月額でかかります。 料金ページの価格です(米ドル、1ユーザーあたりの月額。2026年10月22日時点)。

プラン 月額(1ユーザー) 主な違い
Starter 5ドル アプリとオートメーションの基本機能
Core 10ドル バーコード・NFC、Webhook と定期実行、ユーザーの役割とセキュリティフィルター
Enterprise Plus 20ドル 機械学習・OCR、Salesforce・BigQuery・REST API などの接続、管理機能
Publisher Pro 1アプリ月50ドル ログイン不要の公開アプリ。人数は無制限
10人無料でテストできる人数作成者を含む。期間の制限は無い
10ドルCore の1ユーザー月額Workspace の多くのエディションに含まれる
50ドルPublisher Pro の1アプリ月額ログインなし・機密データなしの公開アプリ向け

無料で使える範囲

AppSheet ヘルプの「AppSheet を無料で使う」によると、開発中のプロトタイプとテスト、個人での利用は無料です。サブスクリプションを買うまで、アカウントは無料のままです。無料で使える条件は次のとおりです。

  • 個人(業務ではない)の利用であること
  • テストの利用者は作成者を含めて10人以下
  • 無料のアカウントで使えない機能(プレミアム機能)を使わないこと
  • オートメーションのメールは自分のアカウントあてだけ

メール送信や定期実行のボットは、無料のままでも設定はできますが、ヘルプには「サブスクリプションを買うまで期待どおりに動かない」とあります。業務で同僚に配る(デプロイする)ときは、使う人数分のライセンスが要ります。

Google Workspace に含まれる条件

Google Workspace の多くのエディションでは、ドメインを確認済みのユーザーに AppSheet Core の利用権が追加料金なしで付きます。 Workspace の管理者向けヘルプに載っているエディションです(2026年10月22日時点)。

区分 AppSheet Core が含まれるエディション
Business Business Starter・Business Standard・Business Plus(Business Base はインドのみ)
Enterprise Enterprise Starter・Enterprise Standard・Enterprise Plus
Education Education Standard・Education Plus
Essentials Enterprise Essentials Plus
Frontline Frontline Starter・Frontline Standard・Frontline Plus
Non-profit Google Workspace for Nonprofits
  • Core の利用権は自動で付き、管理者が1人ずつ割り当てる操作はありません。管理者は、組織で AppSheet を使えるかどうかをオン・オフできます。
  • すでに appsheet.com で Core を買っている場合、使う人が全員 Workspace の組織内なら不要になることがあります。
  • Enterprise Plus は Workspace の管理者だけが購入できます。
  • Gemini でアプリを作る機能(AI でのアプリ作成)は、有料の Google Workspace ライセンスを持つユーザーだけが使えます。

ユーザー数の数え方

料金ページとヘルプの「サブスクリプションの選び方」では、ライセンスの数は デプロイしたすべてのアプリの、重複しない利用者の合計 で数えます。

状況 必要なライセンス
同じ10人が3つのアプリを使う 10
アプリAを10人、アプリBを別の5人が使う 15
ログインを求めないアプリを30台の端末で開く 端末ごとにゲストとして数えられる

ログイン(ユーザー認証)を求めないアプリは、起動した端末ごとに別のゲストユーザーとして数えられるので、社内アプリではログインを必須にします。

AppSheetの始め方:Googleスプレッドシートからアプリを作る

この節では、スプレッドシートを用意してから、アプリが動くまでの手順が分かります。

1

スプレッドシートで表を作る

1つのシートに1つの表を置き、1行目に列名を書きます。先頭の列に 貸出ID のような ID 列を用意します。結合したセル・空の列・表の上のタイトル行は置きません。

1シート=1テーブル

2

[拡張機能]からアプリを作る

スプレッドシートのメニューで[拡張機能]→[AppSheet]→[アプリを作成]を選びます。AppSheet の画面が開き、表から作られたアプリが表示されます。

Google アカウントでログイン

3

残りのシートを表として足す

エディタの[Data](データ)で「+」から、同じスプレッドシートの別のシートを表として追加します。社員・備品・貸出の3つを足します。

表ごとにキーを確かめる

4

列の型とキーを直す

各列の Type(型)を確かめ、ID 列を Key に、相手の表を指す列を Ref にします。ID 列の Initial value に UNIQUEID() を入れます。

ここが設計の中心

5

ビュー・アクション・オートメーションを足す

[App](アプリ)でビューを、[Actions]でボタンを、[Automation]で通知を作ります。右側のプレビューで動きを確かめ、右上の[Save]で保存します。

保存するとすぐアプリに反映

6

共有してデプロイする

テストの人に共有して試してもらい、[Manage]→[Deploy]でデプロイの点検を通して公開します。

業務で使うなら有料ライセンス

ほかに、AppSheet の[My Apps]ページの[+ Create]から始める方法もあります。ヘルプの「アプリを作成する: 必須事項」では、選択肢は次の4つです。

始め方 向いている場面
自分のデータから始める スプレッドシートやデータベースがすでにある
サンプルのアプリ テンプレートを使用して始める 似た業務のテンプレートを見て作りたい
中身のないアプリを作成して始める AppSheet データベースで一から表を作る
Gemini を使用して始める 作りたいアプリを文章で説明して下書きを作る(有料の Workspace ライセンス)

エディタの画面の名前

アプリエディタの左のナビゲーションです。ヘルプ(日本語版)の表記と英語の表記を並べます。

日本語のヘルプでの名前 英語の表記 ここで設定するもの
データ Data 表・列の型・キー・仮想列・スライス
アプリ App ビュー(画面)・見た目・表示の仕方
アクション Actions 画面の移動・値の変更・外部リンクを開くボタン
自動化 Automation ボット(イベント→プロセス→タスク)
チャットアプリ Chat apps Google Chat で動くアプリ
インテリジェンス Intelligence 予測・OCR などの機械学習
セキュリティ Security ログインの必須化・セキュリティフィルター
設定 Settings テーマ・性能・ローカライズ(表示文言)
管理 Manage バージョン・デプロイ・利用状況
詳細 Learn 使い始めの案内と機能の説明

以前のエディタでは、左のメニューが Info・Data・UX・Behavior・Automation・Security・Intelligence・Manage でした。「UX」は今の[App]、「Behavior」は今の[Actions]に当たります。以前の画面で書かれた解説と見比べるときの対応表として使えます。

アプリができるまでの流れ(データ→テーブル→列の型→ビュー→アクション→オートメーション)

この節では、AppSheet の部品がどの順に重なってアプリになるかが分かります。

段階 AppSheet での名前 決めること 備品の貸出管理での例
1 データ Data source どこにデータを置くか Google スプレッドシート「備品管理」
2 テーブル Table どのシートを表にするか、追加・更新・削除を許すか 社員・備品・貸出
3 列の型 Column type 各列の型・キー・初期値・入力チェック 貸出.備品ID を Ref(備品)
4 ビュー View どの表をどんな画面で見せるか 貸出中の一覧(Table)、備品のカード(Deck)
5 アクション Action ボタンで何をするか 「返却」ボタンで返却日に今日を入れる
6 オートメーション Bot いつ、何を自動でするか 毎朝、延滞している人にメール

ビュー・アクション・オートメーションは、すべて 表と列の型の上に乗っています。列の型とキーがずれていると、後の段階をいくら直しても動きが合いません。次の節で、土台になる表の設計を SQL で確かめます。

元になる表の設計:キーとRef型をSQLで確かめる

この節では、AppSheet の Key と Ref 型が、データベースの主キー・外部キーとどう対応するかを、実際に動かした結果で確かめられます。

AppSheet の Ref 型の列には、参照先の表の「キーの値」が入ります。 ヘルプの「テーブル間の参照」には「Ref 列は、参照先の行のキー列の値を常に保存する」とあります。これはリレーショナルデータベースの外部キーと同じ考え方です。ただし、Google スプレッドシートには主キーや外部キーの制約が無いので、シートを直接編集すると、キーの重複や切れた参照がそのまま入ります。ここでは、同じ表を PostgreSQL 16 で組み、AppSheet の設定と SQL を1つずつ対応させます。

3つの表(社員・備品・貸出)

erDiagram
    社員 ||--o{ 貸出 : 借りる
    備品 ||--o{ 貸出 : 貸し出される
    社員 {
        text 社員ID PK
        text 氏名
        text メール
        text 部署
    }
    備品 {
        text 備品ID PK
        text 備品名
        text 種類
    }
    貸出 {
        text 貸出ID PK
        text 備品ID FK
        text 社員ID FK
        date 貸出日
        date 返却予定日
        date 返却日
    }

スプレッドシートには、次の3つのシートを作ります。ID は、AppSheet の UNIQUEID() が作るのと同じ8文字の英数字にしています。

シート 列(1行目) キー Ref にする列
社員 社員ID・氏名・メール・部署 社員ID ―
備品 備品ID・備品名・種類 備品ID ―
貸出 貸出ID・備品ID・社員ID・貸出日・返却予定日・返却日 貸出ID 備品ID → 備品、社員ID → 社員

同じ表を PostgreSQL で作った DDL です。コメントに、AppSheet で設定する型と式を書いています。

CREATE TABLE 社員 (
  社員ID  text PRIMARY KEY,          -- AppSheet: Text・Key・初期値 UNIQUEID()
  氏名    text NOT NULL,             -- Name・Label
  メール  text NOT NULL UNIQUE,      -- Email
  部署    text NOT NULL CHECK (部署 IN ('開発','営業','総務'))  -- Enum
);
CREATE TABLE 備品 (
  備品ID  text PRIMARY KEY,
  備品名  text NOT NULL,             -- Label
  種類    text NOT NULL CHECK (種類 IN ('PC','モニター','その他'))
);
CREATE TABLE 貸出 (
  貸出ID     text PRIMARY KEY,
  備品ID     text NOT NULL REFERENCES 備品(備品ID),   -- AppSheet: Ref(備品)
  社員ID     text NOT NULL REFERENCES 社員(社員ID),   -- AppSheet: Ref(社員)
  貸出日     date NOT NULL DEFAULT current_date,      -- 初期値 TODAY()
  返却予定日 date NOT NULL,
  返却日     date
);
INSERT INTO 社員 VALUES
 ('e7a1c3f0','青木 花子','aoki@example.com','開発'),
 ('3b9d0e12','佐藤 健','sato@example.com','営業'),
 ('c40f8a6d','鈴木 一郎','suzuki@example.com','総務');
INSERT INTO 備品 VALUES
 ('9f2c4e81','ノートPC A-01','PC'),
 ('51ab7d03','ノートPC A-02','PC'),
 ('d8e06b5c','27型モニター M-01','モニター'),
 ('0a7f39e2','プロジェクター P-01','その他');
INSERT INTO 貸出 VALUES
 ('k1f0a2b3','9f2c4e81','e7a1c3f0','2026-10-01','2026-10-08','2026-10-07'),
 ('k2c9d8e7','9f2c4e81','3b9d0e12','2026-10-14','2026-10-21',NULL),
 ('k3e5f6a1','d8e06b5c','e7a1c3f0','2026-10-15','2026-10-29',NULL),
 ('k4b2c3d4','0a7f39e2','c40f8a6d','2026-10-20','2026-10-21','2026-10-21');
CREATE TABLE
CREATE TABLE
CREATE TABLE
INSERT 0 3
INSERT 0 4
INSERT 0 4

以下の出力で列名が 貸出id のように小文字になるのは、PostgreSQL が引用符の無い英字を小文字にそろえるためです。

[備品ID].[備品名] は JOIN と同じ

貸出の行から、参照先の備品名や社員の部署を引く式は、ヘルプの「デリファレンス式」で [Ref 列].[値の列] と書きます。貸出の表に仮想列を作り、App formula に [備品ID].[備品名] と書くと、備品の表で備品ID が一致する行の備品名が返ります。SQL では JOIN です。

=> SELECT k.貸出ID, k.備品ID, b.備品名, s.氏名, s.部署
   FROM 貸出 k
   JOIN 備品 b ON b.備品ID = k.備品ID
   JOIN 社員 s ON s.社員ID = k.社員ID
   ORDER BY k.貸出日;
  貸出id  |  備品id  |       備品名        |   氏名    | 部署 
----------+----------+---------------------+-----------+------
 k1f0a2b3 | 9f2c4e81 | ノートPC A-01       | 青木 花子 | 開発
 k2c9d8e7 | 9f2c4e81 | ノートPC A-01       | 佐藤 健   | 営業
 k3e5f6a1 | d8e06b5c | 27型モニター M-01   | 青木 花子 | 開発
 k4b2c3d4 | 0a7f39e2 | プロジェクター P-01 | 鈴木 一郎 | 総務
(4 rows)

アプリの画面では、Ref 列には参照先の行の Label(表示名)にした列が表示されます。備品の表で備品名を Label にしておくと、貸出の一覧には 9f2c4e81 ではなく「ノートPC A-01」と出ます。

逆参照(Related 貸出s)は LEFT JOIN と集計

Ref 列を作ると、参照される側の表に 逆向きの参照の仮想列 が自動で足されます。ヘルプによると、この列は関連する行のキーの一覧で、App formula には REF_ROWS() が入ります。備品の表なら Related 貸出s という名前の列ができ、式は REF_ROWS("貸出", "備品ID") です。SQL では、備品を軸にした LEFT JOIN と集計に当たります。

=> SELECT b.備品ID, b.備品名,
          coalesce(array_agg(k.貸出ID ORDER BY k.貸出日) FILTER (WHERE k.貸出ID IS NOT NULL), '{}') AS "Related 貸出s",
          count(k.貸出ID) AS 貸出回数
   FROM 備品 b LEFT JOIN 貸出 k ON k.備品ID = b.備品ID
   GROUP BY b.備品ID, b.備品名
   ORDER BY b.備品名;
  備品id  |       備品名        |    Related 貸出s    | 貸出回数 
----------+---------------------+---------------------+----------
 d8e06b5c | 27型モニター M-01   | {k3e5f6a1}          |        1
 9f2c4e81 | ノートPC A-01       | {k1f0a2b3,k2c9d8e7} |        2
 51ab7d03 | ノートPC A-02       | {}                  |        0
 0a7f39e2 | プロジェクター P-01 | {k4b2c3d4}          |        1
(4 rows)

AppSheet の式では、貸出回数は COUNT([Related 貸出s]) です。一度も貸していない「ノートPC A-02」も、空の一覧(0件)として出ます。備品の詳細画面には、この逆参照の一覧(その備品の貸出の履歴)が自動で表示されます。

仮想列(状態・延滞)は SELECT の計算列

スプレッドシートに列を足さずに、式で計算した値を持たせる列が 仮想列(Virtual column) です。貸出の表に次の2つを作ります。

仮想列 App formula 型
状態 IF(ISBLANK([返却日]), "貸出中", "返却済") Text
延滞 AND(ISBLANK([返却日]), [返却予定日] < TODAY()) Yes/No

SQL では SELECT の計算列です(今日を 2026年10月22日として計算)。

=> SELECT 貸出ID,
          CASE WHEN 返却日 IS NULL THEN '貸出中' ELSE '返却済' END AS 状態,
          (返却日 IS NULL AND 返却予定日 < DATE '2026-10-22') AS 延滞
   FROM 貸出 ORDER BY 貸出ID;
  貸出id  |  状態  | 延滞 
----------+--------+------
 k1f0a2b3 | 返却済 | f
 k2c9d8e7 | 貸出中 | t
 k3e5f6a1 | 貸出中 | f
 k4b2c3d4 | 返却済 | f
(4 rows)

返却予定日が10月21日で、まだ返していない k2c9d8e7 だけが延滞になりました。

SELECT() とセキュリティフィルターは WHERE

ある社員の、まだ返していない貸出の ID を集める式は SELECT(貸出[貸出ID], AND([社員ID] = "e7a1c3f0", ISBLANK([返却日]))) です。SQL の WHERE と同じです。

=> SELECT 貸出ID FROM 貸出 WHERE 社員ID = 'e7a1c3f0' AND 返却日 IS NULL;
  貸出id  
----------
 k3e5f6a1
(1 row)

ログインした人に自分の貸出だけを見せるには、貸出の表の セキュリティフィルター(Core 以上)に [社員ID].[メール] = USEREMAIL() と書きます。ログインした人のメールアドレスを aoki@example.com として、同じ条件を SQL で動かしました。

=> SET app.useremail = 'aoki@example.com';
SET
=> SELECT k.貸出ID, k.備品ID FROM 貸出 k JOIN 社員 s ON s.社員ID = k.社員ID
   WHERE s.メール = current_setting('app.useremail') ORDER BY 1;
  貸出id  |  備品id  
----------+----------
 k1f0a2b3 | 9f2c4e81
 k3e5f6a1 | d8e06b5c
(2 rows)

AppSheet の設定と SQL の対応表

AppSheet の設定 SQL で当たるもの
Key の列(初期値 UNIQUEID()) PRIMARY KEY
Ref 型の列 REFERENCES(外部キー)
Ref の「Is a part of」 ON DELETE CASCADE
[備品ID].[備品名] JOIN
Related 貸出s(REF_ROWS) LEFT JOIN と array_agg
COUNT([Related 貸出s]) GROUP BY と count
仮想列の App formula SELECT の計算列
SELECT(表[列], 条件) SELECT 列 FROM 表 WHERE 条件
Enum(選べる値の一覧) CHECK (列 IN (…))
セキュリティフィルター 行を絞る WHERE

キーとRefが崩れる5つの例(SQLで再現)

この節では、スプレッドシートを元にしたアプリで起きやすいキーと参照の崩れ方と、それを見つける SQL・Python が分かります。

1. 存在しないキーを入れる・参照されている行を消す

PostgreSQL では、外部キー制約が止めます。

=> INSERT INTO 貸出 VALUES ('k5aaaaaa','ffffffff','e7a1c3f0','2026-10-22','2026-10-29',NULL);
ERROR:  insert or update on table "貸出" violates foreign key constraint "貸出_備品id_fkey"
DETAIL:  Key (備品id)=(ffffffff) is not present in table "備品".
=> DELETE FROM 備品 WHERE 備品ID = '9f2c4e81';
ERROR:  update or delete on table "備品" violates foreign key constraint "貸出_備品id_fkey" on table "貸出"
DETAIL:  Key (備品id)=(9f2c4e81) is still referenced from table "貸出".

スプレッドシートには、この制約がありません。制約の無い表(シートと同じ状態)を作り、シートの上で備品の行を消してから、親のいない貸出を探しました。

=> CREATE TABLE シート_備品 AS SELECT * FROM 備品;
SELECT 4
=> CREATE TABLE シート_貸出 AS SELECT * FROM 貸出;
SELECT 4
=> DELETE FROM シート_備品 WHERE 備品ID = '9f2c4e81';
DELETE 1
=> SELECT k.貸出ID, k.備品ID FROM シート_貸出 k
   LEFT JOIN シート_備品 b ON b.備品ID = k.備品ID
   WHERE b.備品ID IS NULL;
  貸出id  |  備品id  
----------+----------
 k1f0a2b3 | 9f2c4e81
 k2c9d8e7 | 9f2c4e81
(2 rows)

削除はエラーにならず、2件の貸出が「どの備品か分からない」行として残りました。アプリでは、この2件の備品欄から備品名を引けません。

2. キーが重複する

シートに手で行を足して、同じ備品ID を2回入れた状態です。重複は GROUP BY と HAVING で見つかります。

=> INSERT INTO シート_備品 VALUES ('d8e06b5c','HDMIケーブル','その他');
INSERT 0 1
=> SELECT 備品ID, count(*), string_agg(備品名, ' / ') FROM シート_備品
   GROUP BY 備品ID HAVING count(*) > 1;
  備品id  | count |            string_agg            
----------+-------+----------------------------------
 d8e06b5c |     2 | 27型モニター M-01 / HDMIケーブル
(1 row)

ヘルプの「キーとは」には、キーが重複した行を更新・削除しようとすると「誤った行が更新または削除される場合がある」とあります。貸出の d8e06b5c がモニターとケーブルのどちらを指すかも決まりません。

3. 行番号(_RowNumber)をキーにする

キーにできる列が見つからないと、AppSheet はシートの行番号 _RowNumber をキーにします。ヘルプは「行番号は良いキーではない」と書き、エディタも警告を出します。理由を確かめるため、シートの行番号(1行目は見出しなので、データは2行目から)を作り、途中の行を消しました。

CREATE TABLE 行シート (並び int, 備品名 text);
INSERT INTO 行シート VALUES (1,'ノートPC A-01'),(2,'ノートPC A-02'),(3,'27型モニター M-01'),(4,'プロジェクター P-01');
CREATE VIEW 行番号つき AS
  SELECT row_number() OVER (ORDER BY 並び) + 1 AS "_RowNumber", 備品名 FROM 行シート;
=> SELECT * FROM 行番号つき;
 _RowNumber |       備品名        
------------+---------------------
          2 | ノートPC A-01
          3 | ノートPC A-02
          4 | 27型モニター M-01
          5 | プロジェクター P-01
(4 rows)

=> DELETE FROM 行シート WHERE 備品名 = 'ノートPC A-02';
DELETE 1
=> SELECT * FROM 行番号つき WHERE "_RowNumber" = 4;
 _RowNumber |       備品名        
------------+---------------------
          4 | プロジェクター P-01
(1 row)

「4」を指していた貸出は、3行目を消しただけで、モニターからプロジェクターに変わりました。 行を消す・並べ替える・途中に挿入するたびに、行番号で参照していた行が別の行を指します。

行番号をキーにする行の削除・並べ替えで番号が変わり、参照先がずれる
→
ID 列をキーにする先頭に ID 列を作り、Initial value に UNIQUEID() を入れる

ヘルプでは、UNIQUEID() は8文字の英数字を作り、複数の人がオフラインで追加しても重ならないとしている

名前で参照する名前を直すと、直す前の名前で入っている行がつながらなくなる
→
キーで参照し、名前は Label にするRef 列にはキーを入れ、画面には Label の名前を出す

キーの値は行がある間ずっと変えない。表示を変えたいときは Label の列だけを直す

4. 名前で参照する

社員の氏名をキーのように使い、貸出に氏名を入れていた場合です。氏名の表記を直すと、直す前の名前で入っている貸出がつながらなくなりました。

=> CREATE TABLE 名前シート_社員 AS SELECT 氏名, 部署 FROM 社員;
SELECT 3
=> CREATE TABLE 名前シート_貸出 AS SELECT k.貸出ID, s.氏名 AS 借りた人 FROM 貸出 k JOIN 社員 s USING (社員ID);
SELECT 4
=> UPDATE 名前シート_社員 SET 氏名 = '青木 はな子' WHERE 氏名 = '青木 花子';
UPDATE 1
=> SELECT k.貸出ID, k.借りた人, s.部署 FROM 名前シート_貸出 k
   LEFT JOIN 名前シート_社員 s ON s.氏名 = k.借りた人 ORDER BY 1;
  貸出id  | 借りた人  | 部署 
----------+-----------+------
 k1f0a2b3 | 青木 花子 | 
 k2c9d8e7 | 佐藤 健   | 営業
 k3e5f6a1 | 青木 花子 | 
 k4b2c3d4 | 鈴木 一郎 | 総務
(4 rows)

ヘルプの例でも、Customer Name の列が Customers の Name キーと一致するときに Ref が自動で推定されます。手早く作れますが、名前は変わることがあるので、変わらない ID をキーにします。

5. 親を消したら子も消したい(Is a part of)

点検記録のように、親(備品)が無ければ意味の無い行は、Ref 列で Is a part of をオンにします。ヘルプによると、フォームの中で子の行を続けて追加でき、親の行を消すと子の行も消えます。1つの表で Is a part of にできる Ref 列は1つだけです。SQL では ON DELETE CASCADE に当たります。

=> CREATE TABLE 点検記録 (
     点検ID text PRIMARY KEY,
     備品ID text NOT NULL REFERENCES 備品(備品ID) ON DELETE CASCADE,
     点検日 date, 結果 text);
CREATE TABLE
=> INSERT INTO 備品 VALUES ('77c1e0b9','ノートPC A-03','PC');
INSERT 0 1
=> INSERT INTO 点検記録 VALUES ('t01a9c2e','77c1e0b9','2026-10-01','OK'),('t02b7d4f','77c1e0b9','2026-10-15','バッテリー劣化');
INSERT 0 2
=> DELETE FROM 備品 WHERE 備品ID = '77c1e0b9';
DELETE 1
=> SELECT count(*) AS 残った点検記録 FROM 点検記録 WHERE 備品ID = '77c1e0b9';
 残った点検記録 
----------------
              0
(1 row)

多対多は中間の表に Ref を2つ置く

1つの備品に複数のタグ、1つのタグに複数の備品が付く「多対多」は、中間の表(備品タグ)を作り、備品とタグへの Ref を1つずつ置きます。同じ組み合わせを2回入れないように、SQL では UNIQUE を付けました。AppSheet では、Valid if の式で同じ組み合わせを防ぐ形になります。

CREATE TABLE タグ (タグID text PRIMARY KEY, タグ名 text NOT NULL);
CREATE TABLE 備品タグ (
  備品タグID text PRIMARY KEY,
  備品ID text NOT NULL REFERENCES 備品(備品ID),   -- Ref(備品)
  タグID text NOT NULL REFERENCES タグ(タグID),   -- Ref(タグ)
  UNIQUE (備品ID, タグID));
INSERT INTO タグ VALUES ('g1','持ち出し可'),('g2','要充電'),('g3','会議室');
INSERT INTO 備品タグ VALUES ('bt1','9f2c4e81','g1'),('bt2','9f2c4e81','g2'),('bt3','0a7f39e2','g3'),('bt4','51ab7d03','g1');
=> SELECT b.備品名, string_agg(t.タグ名, ' , ' ORDER BY t.タグID) AS タグ
   FROM 備品 b JOIN 備品タグ bt USING (備品ID) JOIN タグ t USING (タグID)
   GROUP BY b.備品名 ORDER BY 1;
       備品名        |        タグ         
---------------------+---------------------
 ノートPC A-01       | 持ち出し可 , 要充電
 ノートPC A-02       | 持ち出し可
 プロジェクター P-01 | 会議室
(3 rows)

=> INSERT INTO 備品タグ VALUES ('bt5','9f2c4e81','g1');
ERROR:  duplicate key value violates unique constraint "備品タグ_備品id_タグid_key"
DETAIL:  Key ("備品id", "タグid")=(9f2c4e81, g1) already exists.

AppSheet につなぐ前にシートを点検する(Python)

シートの内容を CSV で書き出し、キーの空欄・重複と、切れた Ref を Python で調べるスクリプトです。表とキー、Ref の列は先頭の TABLES に書きます。

"""スプレッドシートを CSV で書き出したものを読み、AppSheet につなぐ前に キーと参照 を確かめる。"""
import csv, sys
from collections import Counter
from pathlib import Path

# 表ごとのキー列と、Ref にする列(列名 → 参照先の表)
TABLES = {
    "社員": {"key": "社員ID", "refs": {}},
    "備品": {"key": "備品ID", "refs": {}},
    "貸出": {"key": "貸出ID", "refs": {"備品ID": "備品", "社員ID": "社員"}},
}

def load(folder, name):
    with open(Path(folder) / f"{name}.csv", encoding="utf-8", newline="") as f:
        return list(csv.DictReader(f))

def main(folder):
    data = {t: load(folder, t) for t in TABLES}
    keys = {t: {r[c["key"]] for r in data[t]} for t, c in TABLES.items()}
    problems = 0
    for t, conf in TABLES.items():
        rows, k = data[t], conf["key"]
        print(f"[{t}] {len(rows)} 行  キー列={k}")
        for n, r in enumerate(rows, start=2):           # 1行目は見出し
            if not r[k].strip():
                print(f"  NG 行{n}: キーが空"); problems += 1
        for v, c in Counter(r[k] for r in rows if r[k]).items():
            if c > 1:
                print(f"  NG キー重複: {v} が {c} 行"); problems += 1
        for col, target in conf["refs"].items():
            for n, r in enumerate(rows, start=2):
                if r[col] and r[col] not in keys[target]:
                    print(f"  NG 行{n}: {col}={r[col]} が {target} に無い(Ref が切れる)"); problems += 1
    print(f"問題 {problems} 件")
    return 1 if problems else 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1]))

上の「1」「2」で崩した表に、ID を入れ忘れた貸出を1行足して、CSV に書き出してから実行しました。

$ python3 check_sheets.py csv
[社員] 3 行  キー列=社員ID
[備品] 4 行  キー列=備品ID
  NG キー重複: d8e06b5c が 2 行
[貸出] 5 行  キー列=貸出ID
  NG 行6: キーが空
  NG 行2: 備品ID=9f2c4e81 が 備品 に無い(Ref が切れる)
  NG 行3: 備品ID=9f2c4e81 が 備品 に無い(Ref が切れる)
問題 4 件
$ echo $?
1

行番号はシートの行番号(見出しが1行目)と同じにしてあるので、そのままシートで探せます。表の設計の考え方は、関連記事「ER図の書き方|記号の読み方からCREATE TABLEまで実行して確認」と関連記事「CREATE TABLEの書き方|主キー・外部キー・制約を例で解説」で、整合性が崩れる種類は関連記事「整合性とは|意味とデータ整合性の種類・崩れる例と守り方」で扱っています。

カラムの型(列の型)早見表

この節では、AppSheet の列に設定できる37の型と、それぞれをどこで使うかが分かります。

列の型は、入力欄の形・表示の仕方・使える関数を決めます。 ヘルプ「列のデータ型」に載っている型の全部です(型の名前は日本語版でも英語のままです)。

分類 型 何に使うか
テキスト Text・LongText・Name 1行の文字・複数行の文字・人や場所の名前
数値 Number・Decimal・Price・Percent 整数・小数・金額・割合
日時 Date・DateTime・Time・Duration 日付・日時・時刻・時間の長さ
選択 Enum・EnumList・Yes/No・Color・Progress 1つ選ぶ・複数選ぶ・はい/いいえ・色・進捗(5段階)
参照 Ref・List 別の表の行を指す・値の一覧(List は仮想列だけ)
連絡 Email・Phone タップでメール・電話・SMS
ファイル Image・File・Signature・Drawing・Thumbnail・Video 写真・PDF など・署名・手書き・小さな画像・動画
地図 Address・LatLong・XY 住所・緯度経度・画像の上の位置
変更の記録 ChangeTimestamp・ChangeCounter・ChangeLocation・Update row timestamp 最後に変えた日時・回数・場所
その他 URL・App・Show・Multi Column Key リンク・別のアプリやビューへ移動・表示の区切り・複合キー

列ごとの設定(列のプロパティ)

型のほかに、列ごとに次の設定があります。ヘルプ「列のプロパティを構成する」の項目です。

設定 意味 例
Key 行を一意に決める列 貸出ID
Label 一覧や Ref で、その行の代わりに表示する列 備品名
App formula 入力の代わりに式で値を決める [数量] * [単価]
Initial value 新しい行の初期値 UNIQUEID()、TODAY()
Valid if 入力できる値の条件、または選べる値の一覧 [返却予定日] >= [貸出日]
Show? 表示するかどうか(式も書ける) ISNOTBLANK([返却日])
Editable? 編集できるかどうか 返却済みなら編集させない
Require? 入力を必須にするか 備品ID・社員ID
Display name 画面に出す列名 返却日(空欄=貸出中)
Description フォームに出す説明文 「戻した日を入れる」
Searchable・Scannable・NFC Scannable 検索の対象・バーコード読み取り・NFC 読み取り 備品ID を Scannable に
Sensitive data (PII) 個人情報を含む列の印 メール

App formula と Initial value の違い

App formula Initial value
計算するとき フォームを開いたとき、行が変わったとき 新しい行を追加するときだけ
利用者が変えられるか 変えられない(読み取り専用に見える) 変えられる(初期値を上書きできる)
向いている例 合計・状態・名前の結合 ID・登録日・返却予定日(TODAY() + 7)

ヘルプは、スプレッドシートの関数(シート側の数式)は「データがシートに同期されたときにだけ動く」と説明しています。アプリの画面ですぐ値を見せたい計算は、シートの数式ではなく App formula か仮想列に書きます。

AppSheetの式と関数の早見表

この節では、AppSheet の式の書き方と、よく使う関数35個の書き方が分かります。

AppSheet の式は、列を [列名] で書き、関数とつないで1つの値を出します。 書き方はスプレッドシートの関数に似ていますが、セル番地(A1 など)は使わず、列名で書きます。文字列は "…" で囲みます。

分類 関数 書き方と例
条件 IF IF(ISBLANK([返却日]), "貸出中", "返却済")
条件 IFS IFS([点数] >= 80, "A", [点数] >= 60, "B")
条件 SWITCH SWITCH([種類], "PC", 7, "モニター", 14, 3)
論理 AND・OR・NOT AND(ISBLANK([返却日]), [返却予定日] < TODAY())
空欄 ISBLANK・ISNOTBLANK ISNOTBLANK([返却日])
含む CONTAINS CONTAINS([備品名], "PC")
一覧に有る IN IN(USEREMAIL(), 社員[メール])
文字 CONCATENATE CONCATENATE([備品名], "(", [種類], ")")
文字 TEXT TEXT([貸出日], "YYYY/MM/DD")
文字 LEFT・LEN LEFT([備品ID], 4)、LEN([備品名])
日付 TODAY・NOW TODAY() + 7(7日後)
日付 DATE・EOMONTH EOMONTH(TODAY(), 0)(今月の末日)
利用者 USEREMAIL・USERNAME [社員ID].[メール] = USEREMAIL()
利用者 USERSETTINGS USERSETTINGS("部署")
アプリ CONTEXT CONTEXT("View")(今のビューの名前)
ID UNIQUEID UNIQUEID()(8文字の英数字)
表 SELECT SELECT(貸出[貸出ID], ISBLANK([返却日]))
表 FILTER FILTER("貸出", ISBLANK([返却日]))
表 LOOKUP LOOKUP("aoki@example.com", "社員", "メール", "氏名")
表 REF_ROWS REF_ROWS("貸出", "備品ID")
表 MAXROW MAXROW("貸出", "貸出日", [備品ID] = [_THISROW].[備品ID])
一覧 COUNT・SUM COUNT([Related 貸出s])
一覧 ANY ANY(SELECT(社員[氏名], [メール] = USEREMAIL()))(ログインした人の氏名)
一覧 LIST・SORT LIST("開発", "営業")、SORT([Related 貸出s][貸出日], TRUE)(新しい順)
数 ROUND ROUND([金額] * 1.1)
場所 HERE HERE()(今いる位置。初期値に使う)

表の関数(SELECT・FILTER・LOOKUP・MAXROW)の中で、今見ている行の列を指すときは [_THISROW].[列名] と書きます。上の MAXROW の例は「この備品の、いちばん新しい貸出の行」です。

参照をたどる式(デリファレンス)

書き方 意味 例
[Ref 列].[列] 参照先の行の値 [備品ID].[備品名]
[Ref 列].[Ref 列].[列] 2段たどる 点検記録から [備品ID].[種類]、明細から [注文ID].[顧客ID].[メール]
[一覧の列][列] 一覧の各行の値を集めた一覧 [Related 貸出s][貸出日]

一覧から値を集める書き方は、[Related 貸出s][貸出日] のように 2つの角かっこの間に点を入れません。ヘルプ「デリファレンス式」の例と同じ形です。

ビューの種類と作り方

この節では、AppSheet の画面(ビュー)の種類と、表に合わせた選び方が分かります。

ビューは「どの表(またはスライス)を、どの形で見せるか」の設定です。 ヘルプ「ビューの種類」に載っている11種類です。

ビュー 見え方 合う表
Table 行を表の形で一覧 貸出・在庫など項目の多い表
Deck 画像つきのカードを縦に並べる 備品・商品
Gallery 画像を大きく並べる 写真の多い点検記録
Detail 1行の詳しい内容。前後の行へ移れる どの表にも自動で作られる
Form 入力画面 追加・編集
Calendar 日・週・月で予定を見る 貸出日・予約
Map 住所・緯度経度を地図に出す 顧客・設備の場所
Chart グラフ 部署ごとの貸出数
Dashboard 複数のビューを1画面に並べる 一覧+地図+グラフ
Card 内容とボタンを1つの部品にまとめる 承認待ちの申請
Onboarding 初めて使う人向けの案内画面 使い方の説明

スライス(Slice) は、表の一部の行や列だけを取り出した「見え方用の表」です。[Data]で貸出の表にスライスを作り、Row filter condition を ISBLANK([返却日]) にすると「貸出中」の行だけになり、そのスライスを元にビューを作ると「貸出中の一覧」の画面ができます。SQL のビュー(CREATE VIEW … WHERE 返却日 IS NULL)と同じ考え方です。

アクションとオートメーション(ボット)

この節では、ボタンで値を変える「アクション」と、自動で処理を動かす「オートメーション」の作り方が分かります。

アクション:「返却」ボタンを作る

アクションは、画面に出るボタンです。行の値を変える、別の画面へ移る、メールや電話、外部の URL を開く、などができます。貸出の表に「返却」ボタンを作る設定です。

項目 設定
Action name 返却する
For a record of this table 貸出
Do this Data: set the values of some columns in this row
Set these columns 返却日 = TODAY()
Only if this condition is true ISBLANK([返却日])

Only if の条件で、返却済みの行にはボタンが出なくなります。

オートメーション:ボット=イベント→プロセス→タスク

ヘルプ「AppSheet オートメーションの構成要素」では、オートメーションは次の部品でできています。

flowchart TD
    E[イベント 変更や時刻] --> B[ボット]
    B --> P[プロセス 手順の並び]
    P --> S[ステップ 条件分岐や待機]
    S --> T[タスク メール送信など]
部品 意味 延滞の通知での例
ボット(Bot) 自動化の単位 「延滞の通知」
イベント(Event) きっかけ スケジュール(毎朝9時)、アプリでのデータの変更
プロセス(Process) ボットが動いたときの手順 延滞している行ごとに処理する
ステップ(Step) タスク・データの変更・条件分岐・待機など [延滞] = TRUE で分岐
タスク(Task) 実際にすること メールを送る

イベントの種類は、アプリでの変更・AppSheet データベースの変更・スケジュール・チャットアプリの操作・Google フォームの回答・Gmail のラベルの変更が挙がっています。タスクの種類は次のとおりです。

タスク すること
Send an email メールを送る
Send a notification アプリの通知を送る
Send an SMS message SMS を送る
Call a webhook 外部の URL に HTTP で送る
Create and save a file PDF などのファイルを作って保存する
Send a chat message チャットにメッセージを送る
Use AI ファイルや写真から情報を取り出す・分類する

料金ページでは、Webhook と定期実行(スケジュール)は Core 以上の機能です。Webhook の受け側の作り方は、関連記事「Webhookとは?実装までわかる|署名検証・リトライ・冪等性を実行ログで解説」で扱っています。

共有・公開(デプロイ)とスマホでの使い方

この節では、作ったアプリを人に使ってもらうまでの手順と、使える端末が分かります。

  • 1キーは ID 列になっているか_RowNumber がキーのままなら、ID 列を作って UNIQUEID() を初期値に
  • 2ログインを必須にしたか[Security]でサインインを必須に。しないと端末ごとにゲストとして数えられる
  • 3見せる行を絞ったか他の人の行を見せないなら、セキュリティフィルター(Core 以上)を設定
  • 4テーブルの権限は合っているかマスタの表は追加・削除を禁止し、更新だけにするなど
  • 5使う人数分のライセンスがあるかWorkspace の Core が付いているか、プランの人数で確かめる
  • 6デプロイの点検を通したかManage → Deploy で Run deployment check を実行

デプロイの手順は、ヘルプ「デプロイ チェックを行う」によると次のとおりです。

  1. アプリエディタで[Manage]→[Deploy]を開く
  2. [Deployment Check]→[Run deployment check]を押す
  3. 点検の結果を見る。問題が無ければ[Move app to deployed state]、直すなら[Continue editing]

点検では、アプリの定義とデータの誤り・警告、起動アイコンと説明文の有無、セキュリティ、プランで使える機能かどうかが調べられます。

使える端末とブラウザ

使い方 条件(ヘルプ「モバイル デバイスとブラウザのサポート」)
Android の AppSheet アプリ Android 9 以上
iOS の AppSheet アプリ iOS 12.0 以上
アプリエディタ(作る側) Chrome 95・Firefox 131・Safari 18.4・Edge 95 以上
ブラウザで使う 新しいブラウザ。Chrome がいちばん合う。Internet Explorer は不可

料金ページでは、オフラインでの利用とバックグラウンドでの同期は全プランの機能です。ブラウザで使うときは、バーコードと NFC の読み取り、オフラインでの起動、画像のオフラインでのキャッシュ、プッシュ通知が使えません。外で使う点検・棚卸しのアプリは、スマホの AppSheet アプリで使います。

同期のしくみ(スプレッドシートを直接直したとき)

ヘルプ「同期: アプリとバックエンドの間」によると、同期(Sync)は、端末で変えた内容をバックエンド(スプレッドシートなど)に送る → アプリの定義を取る → 最新のデータを取る、の順に進みます。スプレッドシートを直接直した内容は、次の同期でアプリに届きます。 アプリの起動時に同期が走り、Delayed Sync(遅延同期)を切っていれば保存のたびに同期します。

日本語で使うときの設定

この節では、日本語の業務アプリにするときに触る設定が分かります。

やりたいこと 設定する場所
日付・数値の読み書きを日本の形式に スプレッドシートの[ファイル]→[設定]のロケールを日本に。AppSheet は表を足すときにこのロケールを読む
アプリの画面での日付の表示 端末やブラウザの言語・地域の設定で決まる
ボタンや案内文(Share・Sync・Log out など)を日本語に [Settings]のローカライズ(Localization)で文言を書き換える
列名を画面だけ日本語に 列の Display name
API での日付の形式 リクエストの Locale(例 ja-JP)

列名や表名は、最初から日本語で付けられます。この記事の例も、表名・列名をすべて日本語にしています。ローカライズで書き換えられるのは1つの言語だけで、ヘルプは「複数の言語を同時に使うアプリには、この方法は向かない」としています。

AppSheet APIでデータを読み書きする(Enterprise)

この節では、外部のプログラムから AppSheet のアプリの表に行を足したり読んだりするときに、送るリクエストの形が分かります。

AppSheet API は、表ごとの URL に JSON を POST して、行の追加(Add)・更新(Edit)・削除(Delete)・検索(Find)を行います。 ヘルプ「API を呼び出す」によると、Enterprise プランで使える機能です。URL は https://www.appsheet.com/api/v2/apps/{アプリID}/tables/{表名}/Action で、表名は URL エンコードします。アクセスキーは ApplicationAccessKey ヘッダーで送るのがいちばん安全とされています。

本物の AppSheet ではなく、届いたリクエストをそのまま表示する擬似サーバー(Python の http.server)を 31600 番で待たせ、Python の requests から送りました。

import requests
from urllib.parse import quote

BASE = "http://127.0.0.1:31600"        # 本物は https://www.appsheet.com
APP_ID = "0f1e2d3c-aaaa-bbbb-cccc-123456789abc"
KEY = "V2-dummy-0000"                  # アプリの API 設定で発行するアクセスキー(仮の値)

def call(table, body):
    url = f"{BASE}/api/v2/apps/{APP_ID}/tables/{quote(table)}/Action"
    r = requests.post(url, json=body, headers={"ApplicationAccessKey": KEY}, timeout=10)
    print(r.status_code)

# 追加:貸出ID は初期値 UNIQUEID() に任せて送らない。Ref の列には参照先の「キーの値」を入れる
call("貸出", {
    "Action": "Add",
    "Properties": {"Locale": "ja-JP", "Timezone": "Tokyo Standard Time"},
    "Rows": [{"備品ID": "51ab7d03", "社員ID": "3b9d0e12", "貸出日": "2026/10/22", "返却予定日": "2026/10/29"}],
})
# 検索:返却されていない貸出だけ
call("貸出", {
    "Action": "Find",
    "Properties": {"Locale": "ja-JP", "Selector": "Filter(貸出, ISBLANK([返却日]))"},
    "Rows": [],
})

擬似サーバーに届いた1件目です。表名「貸出」は %E8%B2%B8%E5%87%BA になって URL に入りました。

POST /api/v2/apps/0f1e2d3c-aaaa-bbbb-cccc-123456789abc/tables/%E8%B2%B8%E5%87%BA/Action
  Host: 127.0.0.1:31600
  Content-Type: application/json
  ApplicationAccessKey: V2-dummy-0000
  User-Agent: python-requests/2.34.2
{
  "Action": "Add",
  "Properties": {
    "Locale": "ja-JP",
    "Timezone": "Tokyo Standard Time"
  },
  "Rows": [
    {
      "備品ID": "51ab7d03",
      "社員ID": "3b9d0e12",
      "貸出日": "2026/10/22",
      "返却予定日": "2026/10/29"
    }
  ]
}

2件目の Find は、Rows が空の配列で、条件は Properties の Selector に入っています。

POST /api/v2/apps/0f1e2d3c-aaaa-bbbb-cccc-123456789abc/tables/%E8%B2%B8%E5%87%BA/Action
  Host: 127.0.0.1:31600
  Content-Type: application/json
  ApplicationAccessKey: V2-dummy-0000
  User-Agent: python-requests/2.34.2
{
  "Action": "Find",
  "Properties": {
    "Locale": "ja-JP",
    "Selector": "Filter(貸出, ISBLANK([返却日]))"
  },
  "Rows": []
}

curl で備品名を更新(Edit)するときの形です。Add 以外では、Rows の各行にキーの列(ここでは備品ID)を必ず入れます。

curl -X POST "https://www.appsheet.com/api/v2/apps/<アプリID>/tables/%E5%82%99%E5%93%81/Action" \
  -H "ApplicationAccessKey: <アクセスキー>" \
  -H "Content-Type: application/json" \
  -d '{"Action":"Edit","Rows":[{"備品ID":"51ab7d03","備品名":"ノートPC A-02(修理中)"}]}'

擬似サーバーに向けて送ると、次のとおり届きました。

POST /api/v2/apps/0f1e2d3c-aaaa-bbbb-cccc-123456789abc/tables/%E5%82%99%E5%93%81/Action
  Host: 127.0.0.1:31600
  Content-Type: application/json
  ApplicationAccessKey: V2-dummy-0000
  User-Agent: curl/8.5.0
{
  "Action": "Edit",
  "Rows": [
    {
      "備品ID": "51ab7d03",
      "備品名": "ノートPC A-02(修理中)"
    }
  ]
}
項目 ヘルプでの決まり
Action Add・Delete・Edit・Find、または表のデータ変更アクションの名前
キーの列 Add 以外は必須。Add で省けるのは、初期値の式(UNIQUEID() など)でキーが作られるときだけ
Locale 日付・時刻・数値の解釈。既定は en-US
Timezone 既定は UTC
RunAsUserEmail この利用者として実行する。既定はアプリの所有者
Yes/No の値 true・"Yes"・"Y"・"T" などを受け付ける
Find の戻り値 各行に _RowNumber と、仮想列を含むすべての列の値
旧ドメイン api.appsheet.com は使えるが非推奨

Power Apps・kintone・Bubbleとの違い

この節では、AppSheet とよく比べられるノーコード・ローコードの製品の違いを、事実で比べられます。

項目 AppSheet Power Apps kintone Bubble
提供 Google Microsoft サイボウズ Bubble Group
作り方 表からアプリを生成し、式で動きを足す キャンバスアプリ・モデル駆動型アプリ。式は Power Fx Web の画面でフォームとアプリを作る 画面とデータとワークフローを画面上で組む Web アプリ
主なデータの置き場所 スプレッドシート・AppSheet データベース・SQL など Dataverse・SharePoint・各種コネクタ kintone の中のアプリ Bubble の中のデータベース
料金(2026年10月22日時点) 1ユーザー月5ドル〜。Workspace の多くに Core Premium は1ユーザー月2,998円相当(年払い) 1ユーザー月1,000円〜(税抜・最低10ユーザー) 年払いで月59ドル〜。WU とエディター数で決まる
無料で試す 開発・テストは10人まで無料 開発者向けプラン(無料) 30日間のお試し Free プラン(開発中のアプリ向け)

各公式ページから、違いが出やすい点を挙げます。

  • Power Apps:Microsoft Learn によると、一部の Microsoft 365 のライセンスには、Microsoft 365 のデータと標準コネクタを使う範囲に限った Power Apps の使用権が含まれます。アプリごとのプランは、2026年1月2日から一部の購入経路で新規の販売が終わっています。
  • kintone:料金ページでは、ライト 1,000円・スタンダード 1,800円・ワイド 3,000円(1ユーザー月額・税抜)で、ライトとスタンダードは最低10ユーザーからです。
  • Bubble:料金は、サーバーの処理量を表すワークロードユニット(WU)と、アプリを編集する人の数で決まります。
  • AppSheet:使う人の数で数え、Google Workspace を使う組織では多くのエディションに Core が含まれます。
状況 候補になりやすいもの
Google Workspace を使っていて、データがスプレッドシートにある AppSheet
Microsoft 365 を使っていて、データが SharePoint や Dataverse にある Power Apps
部署ごとに台帳を Web で共有したい kintone
一般の利用者向けの Web サービスを作りたい Bubble

AppSheetのよくあるつまずきと直し方

この節では、AppSheet を使い始めたときによく起きる症状と、その原因・直し方を引けます。

症状 原因 直し方
シートに列を足したのに、アプリに出ない AppSheet の表の構造が変更前のまま [Data]で表を選び[Regenerate schema]→[Regenerate]→保存
列の数が合わない(mismatch)というエラーがプレビューに出る シートの列を足す・消す・並べ替えたあと、構造を作り直していない 同上。Google フォームから作ったアプリは、見出し行のメモの設定で上書きされることがある
キーの警告が出る、別の行が更新される 行番号(_RowNumber)がキーになっている、またはキーが重複している ID 列を作り、Initial value に UNIQUEID()。既存の重複は直す
Ref の欄に 8文字の英数字が出る 参照先の表で Label の列が決まっていない 参照先の表で、名前の列を Label にする
シートを直接直したのに、アプリに出ない アプリはまだ同期していない 同期のボタンを押す。起動時にも同期される
シートの数式の結果がアプリですぐ変わらない シートの数式は、シートに同期されたときに動く App formula か仮想列に書く
日付の月と日が入れ替わる スプレッドシートのロケールと入力の形式が合っていない スプレッドシートのロケールを日本にし、表の Data locale も合わせる
他の人にメールが届かない、定期実行が動かない 無料のまま(メールは自分あてだけ) サブスクリプションを買う。Webhook・定期実行は Core 以上
11人目に共有できない 無料のテストは作成者を含め10人まで デプロイし、人数分のライセンスを用意する
Workspace のアカウントで AppSheet を開けない 組織の管理者が AppSheet をオフにしている 管理者に AppSheet の有効化を頼む
ブラウザでバーコードを読めない ブラウザでは読み取りに対応していない スマホの AppSheet アプリで使う
アプリの読み込みが遅い・データが入らない 1アプリのデータが圧縮後5MBか10MBを超えそう、シートが10万行に近い スライス・セキュリティフィルターで端末に送る行を減らす。AppSheet データベースや SQL に移す

AppSheetが向いている・向いていない判断表

この節では、作りたいものに AppSheet が合うかどうかの目安が分かります。

作りたいもの・条件 目安
スプレッドシートの台帳を、スマホで入力・確認したい 向いている
写真・署名・位置情報・バーコードを使う点検や棚卸し 向いている
社内の数十人で使う申請・承認・通知 向いている(Workspace の Core の範囲で作れることが多い)
1アプリで数十万行を扱う AppSheet データベースの上限(Enterprise Plus で1データベース20万行)や SQL への移行を前提に設計する
画面の見た目を細かく作り込みたい ビューの種類と設定の範囲にとどまるので、要件と見比べる
ログインなしで一般に公開したい Publisher Pro(機密データなし・ログインなしが条件)
表と表が多対多でつながる、正確さが要る業務 表の設計(キー・Ref・中間の表)を先に決め、上の点検スクリプトのような確認を入れる

AppSheet データベースの上限は、ヘルプ「制限事項」によると、無料1,000行・Starter と Core 2,500行・Enterprise Plus 200,000行(いずれも1データベースあたり)、全プランで1データベース20表・1表100列です。表をどう分けるかの考え方は、関連記事「エンティティとは|意味・ER図・設計手順をDBとJavaで実例解説」で、業務の流れを図にして整理する方法は関連記事「業務フロー図の書き方|記号一覧・スイムレーン例とMermaidテンプレート」で扱っています。

よくある質問

Q. AppSheetの読み方は? A. 「アップシート」です。Google が提供するノーコードのアプリ開発サービスです。

Q. AppSheetとは何ですか?何ができますか? A. スプレッドシートなどの表から、コードを書かずに業務アプリを作るサービスです。入力フォーム・一覧・地図・グラフ、写真や署名の入力、通知や定期実行の自動化ができます。「AppSheetで作れるアプリの例」の節に例をまとめています。

Q. AppSheetは無料で使えますか? A. 開発中のプロトタイプとテスト、個人での利用は無料で、テストは作成者を含め10人まで、期間の制限はありません。業務で配る(デプロイする)と、使う人数分のライセンスが要ります(2026年10月22日時点)。

Q. AppSheetの料金はいくらですか? A. 1ユーザー月額で Starter 5ドル・Core 10ドル・Enterprise Plus 20ドル、ログインなしの公開アプリ向けの Publisher Pro は1アプリ月50ドルです(2026年10月22日時点)。

Q. Google Workspaceを使っていればAppSheetは追加料金なしですか? A. Business Starter・Standard・Plus、Enterprise、Education Standard・Plus、Frontline などの多くのエディションで、ドメイン確認済みのユーザーに AppSheet Core が含まれます。Enterprise Plus の機能は別に購入します。

Q. AppSheetは日本語で使えますか? A. 表名・列名・データは日本語で使えます。日付の形式はスプレッドシートのロケールで、ボタンなどの文言は[Settings]のローカライズで日本語にします。「日本語で使うときの設定」の節に表があります。

Q. AppSheetのRef型とは何ですか? A. 別の表の行を指す列の型です。参照先の表のキーの値が入り、[備品ID].[備品名] のように参照先の値を引けます。参照される側には REF_ROWS() の逆参照の列が自動で足されます。

Q. AppSheetのキーには何を使えばいいですか? A. 先頭に ID 列を作り、Initial value に UNIQUEID() を入れる形が、ヘルプでも勧められています。行番号は行の削除や並べ替えで変わるので、キーに向きません。

Q. スプレッドシートが無くてもAppSheetは使えますか? A. 使えます。AppSheet データベースで表を一から作るほか、MySQL・PostgreSQL などのデータベースや Salesforce などにもつなげます。データソースの一覧は「AppSheetで作れるアプリの例」の節にあります。

Q. AppSheetで作ったアプリを社外の人に使ってもらえますか? A. 使えます。ログインは Google・Microsoft・Dropbox・Box などのアカウントで行え、使う人数分のライセンスで数えます。ログインなしで誰でも開ける公開アプリは Publisher Pro(1アプリ月50ドル、機密データなし)です(2026年10月22日時点)。

Q. スプレッドシートを直接編集してもいいですか? A. 編集はできますが、アプリには次の同期で届きます。列の追加・削除・並べ替えをしたら[Regenerate schema]で構造を作り直します。キーの重複や切れた参照がシートに入らないよう、上の点検スクリプトのような確認が役立ちます。

Q. AppSheetとPower Appsの違いは? A. AppSheet は Google のサービスで、スプレッドシートなどの表からアプリを作り、Workspace の多くのエディションに Core が含まれます。Power Apps は Microsoft のサービスで、Power Fx の式を使い、Dataverse や SharePoint のデータとつなぎます。比較表は「Power Apps・kintone・Bubbleとの違い」の節にあります。

Q. AppSheetのデメリットは? A. 画面の見た目の自由度がビューの設定の範囲にとどまること、1アプリのデータが圧縮後5MBか10MBまでなこと、英語の情報が中心なことです。

Q. AppSheetで作ったアプリはスマホで使えますか? A. 使えます。Android 9 以上・iOS 12.0 以上の AppSheet アプリか、スマホのブラウザで開きます。バーコードの読み取りやオフラインでの起動は、AppSheet アプリでだけ使えます。

Q. AppSheetにAPIはありますか? A. あります。表ごとの URL に JSON を POST して、行の追加・更新・削除・検索をします。ヘルプによると Enterprise プランの機能です。「AppSheet APIでデータを読み書きする」の節に、実際に送ったリクエストを載せています。

まとめ

  • AppSheet(アップシート)は、スプレッドシートなどの表から、コードを書かずに業務アプリを作る Google のサービス。
  • 料金は1ユーザー月額で Starter 5ドル・Core 10ドル・Enterprise Plus 20ドル。開発とテストは10人まで無料で、Workspace の多くのエディションに Core が含まれる(2026年10月22日時点)。
  • アプリは、データ→テーブル→列の型→ビュー→アクション→オートメーションの順に組み上がる。土台は表の設計。
  • Ref 型の列には参照先のキーが入る。[備品ID].[備品名] は JOIN、Related 貸出s(REF_ROWS)は LEFT JOIN と集計、Is a part of は ON DELETE CASCADE に当たる。
  • キーは初期値 UNIQUEID() の ID 列にする。行番号や名前をキーにすると、行の削除や名前の変更で参照がずれる。
  • シートには制約が無いので、キーの重複や切れた参照は SQL や Python で点検できる。

参考・出典

確認日はいずれも 2026年10月22日です。

  • AppSheet「Pricing」:https://about.appsheet.com/pricing/
  • AppSheet ヘルプ「How to choose a subscription」:https://support.google.com/appsheet/answer/10105400
  • AppSheet ヘルプ「Use AppSheet for free」:https://support.google.com/appsheet/answer/10104499
  • Google Workspace 管理者ヘルプ「Manage AppSheet in your organization」:https://knowledge.workspace.google.com/admin/appsheet/manage-appsheet-in-your-organization
  • AppSheet ヘルプ「アプリを作成する: 必須事項」:https://support.google.com/appsheet/answer/11980957?hl=ja
  • AppSheet ヘルプ「アプリエディタを詳しく見る」:https://support.google.com/appsheet/answer/12290157?hl=ja
  • AppSheet ヘルプ「列のデータ型」:https://support.google.com/appsheet/answer/10106435?hl=ja
  • AppSheet ヘルプ「Configure column properties」:https://support.google.com/appsheet/answer/10106509
  • AppSheet ヘルプ「Define app formulas and initial values」:https://support.google.com/appsheet/answer/10106437
  • AppSheet ヘルプ「What is a key?」:https://support.google.com/appsheet/answer/10106672
  • AppSheet ヘルプ「References between tables」:https://support.google.com/appsheet/answer/10106510
  • AppSheet ヘルプ「Dereference expressions」:https://support.google.com/appsheet/answer/10107396
  • AppSheet ヘルプ「AppSheet function list」:https://support.google.com/appsheet/table/10104782
  • AppSheet ヘルプ「View types」:https://support.google.com/appsheet/answer/10106772
  • AppSheet ヘルプ「AppSheet automation: The Components」:https://support.google.com/appsheet/answer/11431791
  • AppSheet ヘルプ「Tasks: The Essentials」:https://support.google.com/appsheet/answer/11445301
  • AppSheet ヘルプ「Perform a deployment check」:https://support.google.com/appsheet/answer/10104389
  • AppSheet ヘルプ「Support for AppSheet apps on mobile devices and browsers」:https://support.google.com/appsheet/answer/10105385
  • AppSheet ヘルプ「Sync: Between the app and the backend」:https://support.google.com/appsheet/answer/10108301
  • AppSheet ヘルプ「Add, reorder, or delete columns」:https://support.google.com/appsheet/answer/10106675
  • AppSheet ヘルプ「Locale support in AppSheet」:https://support.google.com/appsheet/answer/10106525
  • AppSheet ヘルプ「Localize: The Essentials」:https://support.google.com/appsheet?p=localize
  • AppSheet ヘルプ「データソースの管理」:https://support.google.com/appsheet/answer/10106309?hl=ja
  • AppSheet ヘルプ「Limits on data size」:https://support.google.com/appsheet/answer/10104789
  • AppSheet ヘルプ「Restrictions, limits, and known issues」(AppSheet データベース):https://support.google.com/appsheet/answer/12653576
  • AppSheet ヘルプ「Invoke the API」:https://support.google.com/appsheet/answer/10105398
  • AppSheet ヘルプ「Read records from a table」:https://support.google.com/appsheet/answer/10105770
  • Wikipedia「AppSheet」(英語版。創業と買収の年):https://en.wikipedia.org/wiki/AppSheet
  • Microsoft「Power Apps の価格」:https://www.microsoft.com/ja-jp/power-platform/products/power-apps/pricing
  • Microsoft Learn「Power Platform のライセンス(価格と課金)」:https://learn.microsoft.com/ja-jp/power-platform/admin/pricing-billing-skus
  • サイボウズ「kintone 料金」:https://kintone.cybozu.co.jp/price/
  • Bubble「Pricing」:https://bubble.io/pricing

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「AppSheetとは|使い方・料金・関数とRef型の表設計を実例で解説」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?