来年、2026 年──
Windows 環境から VBS(VBScript)が正式に消える。
そのニュースは、単なる「古い機能の削除」ではない。
長年、日本の社内業務を裏側で支えてきた “Access アプリ文化” が、
静かにひとつの節目を迎えるという意味でもある。
思えば、あの時代は平和だった。
Access のフォームにボタンを置き、
クエリを 3 つほど作って VBA を 20 行書けば、
見積もりだろうが、注文管理だろうが、在庫台帳だろうが、
明日から使える業務アプリが完成した。
- Excel では手に負えない
- 本格的な Web システムを作る予算もない
- エンジニアもいない
- でも現場は明日から動かなければならない
そんな“日本の現場”を、Access は長く救ってきた。
だが、その功績と引き換えに、
巨大で複雑すぎるローカル MDB、
クエリ地獄、
VBAの迷宮、
1台のPCが壊れただけで業務停止──
そんな 構造疲労が限界に達したアプリ も少なくない。
そして今日、
ブラウザは強くなり、
LAN アプリは姿を消し、
バックエンドは 1 バイナリで起動する時代になった。
Access の“次の場所”を探すなら、
それは Excel VBA の延命でも、巨大な web フレームワークでもない。
もっと 軽くて、単純で、現場が保守可能で、
しかもクラウドにも載せられる「中庸の技術」 が必要になる。
そこで名前が挙がるのが、
- PocketBase(軽量バックエンド)
- Svelte(素直な UI)
- XState(業務フローと状態管理)
という“3本柱”。
Access の便利さとスピード感を残しながら、
根本の構造疲労だけを取り除いた組み合わせだ。
ここから先は、 Access アプリを PB に移すときの具体的なスキーマ設計術 をまとめた。
特に「テーブルを増やしすぎる」「Enum を全部マスタ化する」など、
Access 時代の“悪癖”をいかにリハビリするかに焦点を当てた。
Access 文化を知っている人ほど、
この移行は驚くほどスムーズに進むはずだ。
- 導入
- 1. Accessおじさんの「なんでもマスタ病」とは何か
- 2. どうしてそうなったのか(Access時代の事情)
- 3. Web+PocketBase時代の設計原則
- 4. PocketBaseで「マスタ病」を矯正するルール
- 5. Svelte側での考え方:UIに正規化を引きずらない
- 6. 実際に移行するときのチェックリスト
- 7. まとめ
- 8. ケース別:AccessマスタをPocketBaseへ移行するとどう変わる?
- 9. クエリ(アクセスの保存クエリ)をどう移行するか
- 10. 一刀両断の総まとめ
- 11. ケーススタディ:Accessアプリを PocketBase+Svelte に移すとこうなる
- 12. PocketBase × Svelte × XState の“理想的な役割分担”
- 13. PocketBase + Svelte + XState の開発環境を10分で整える
- 参照
導入
古い業務システムのDBを覗くと、こんなテーブルが並んでいることがある。
- 性別マスタ
- 曜日マスタ
- はい・いいえマスタ
- フラグ値マスタ(0:無効、1:有効)
初めて見たときは「気でもふれたのか?」と思うが、当時のAccess文化ではわりと普通だった。
正規化とJOINこそ正義、という時代の産物だ。
ただ、このノリをそのままPocketBase+Svelteの世界に持ち込むと、設計が一気に重くなる。
この記事では、Access時代の「なんでもマスタ病」をどう分解し、PocketBase+Svelteにきれいに移植するかを整理してみる。
1. Accessおじさんの「なんでもマスタ病」とは何か
典型的な症状はこんな感じ。
- 値が2〜3種類しかないのに、必ず別テーブルを作る
- 性別マスタ(男・女・不明)
- フラグマスタ(0/1)
- はい・いいえマスタ
- テーブル数がやたら多いのに、実データは数レコードしか入っていない
- クエリを開くと、INNER JOINが何重にも重なっている
彼らの頭の中にはだいたいこんなロジックがある。
- 「正規化されていない=悪」
- 「マスタテーブルを作る=設計がちゃんとしている」
- 「クエリでたくさんJOINする=仕事してる感」
その結果、
業務的には単なる enum でいいものまで全部別テーブル化され、
クエリとフォームがスパゲッティ化していく。
2. どうしてそうなったのか(Access時代の事情)
多少の擁護もしておく。
Access時代に「マスタ乱造」がそれなりに合理的だった理由はある。
- フォームのコンボボックスで「行ソースとしてマスタを指定する」と、UI実装がラクだった
- クエリにJOINすれば、人間が意味を読み取りやすかった(レポート設計上の都合)
- DB=Accessファイル一つ、の世界では、
「ちょっとしたマスタ」が増えても実害が少なかった
要するに、技術的・組織的制約の中では、それが「それなりの合理的解」だった時期がある。
問題は、この感覚をそのままWebアプリの世界に持ち込むことだ。
3. Web+PocketBase時代の設計原則
PocketBase+Svelteの世界では、次のように切り分けたほうがきれいになる。
- 変化しない小さな選択肢は enum(列挙)で十分
- 性別
- ステータスが数種類だけのフラグ
- 画面上の「はい/いいえ」
- 頻繁には変わらないが、業務的に意味があるものは 真のマスタ
- 都道府県
- 支店/部署
- 商品種別など
- 運用で増える可能性があり、管理画面から編集したいものは 設定テーブル
- 送料テーブル
- 単価テーブル
- 納期ランク
- ロジックで吸収すべきものは マスタではなくコードに書く
- 「2枚複写までは減感不可」
- 「4枚複写のときは特定用紙NG」
Accessおじさんの世界では、おおむね 1〜4 を全部「マスタテーブル」でやろうとした。
Web時代はここをちゃんと分けてあげるだけで、設計がかなりスッキリする。
4. PocketBaseで「マスタ病」を矯正するルール
PocketBase+SvelteでAccessアプリを移行する前提で、
次のようなマイルールを決めておくと地獄を避けられる。
4-1. 3件しかないものは enum にする
例:性別
- Access時代
M_GenderテーブルGenderID1/2/3- フォームやクエリで毎回JOIN
- PocketBase時代
genderフィールド(type: select)- values:
"male" | "female" | "other"
ビジネス的に「ユーザーがマスタを編集する必要がない」ものは、
基本 select型フィールドの固定値 で十分。
4-2. 真のマスタだけコレクションにする
例:都道府県、支店、担当者など。
- 他のレコードから多数参照される
- 将来増えたり統合されたりする可能性がある
- 管理画面から編集したい
こういうものは PocketBase のコレクションとして作り、
relationフィールドで参照する。
「性別マスタ」や「はい/いいえマスタ」はここには入れない。
4-3. 「運用で調整したい値」は設定コレクションへ
例:複写伝票の単価テーブル
- 用紙×色数×複写枚数×部数で単価が変わる
- あとから単価改定することがある
これは pricing_rules のようなコレクションとして分離しておく。
Accessだと「単価マスタ」「用紙マスタ」「色マスタ」「複写区分マスタ」などが乱立していたが、
PocketBaseでは
- 本当に意味のある軸だけをテーブルにする
- それ以外は enum or code で表現する
くらいに削ったほうが、シンプルで保守しやすい。
5. Svelte側での考え方:UIに正規化を引きずらない
Access時代は、
「正規化されたテーブル構造」=「フォーム設計」の元ネタだった。
- サブフォームで子テーブルをそのまま出す
- JOIN済みクエリをフォームのレコードソースにする
Web+Svelteでは、ここを一度断ち切ってしまっていい。
5-1. APIで“素直な形”を取って、UI用の構造はフロントで組む
- PocketBaseからは
orderslayersoptions
を別々に取得
- Svelte側で
ordersごとにlayersを紐づけて配列にまとめる- 表示や入力に向いた形のオブジェクトを組み立てる
つまり、
DBはあくまで整った保存形式
UIにとって都合の良い形はフロント側で組む
という設計に切り替える。
Accessの感覚で「UIとDB構造を1:1に合わせる」発想をやると、
Svelteでも結局スパゲッティになる。
5-2. 小さなenumはSvelte側でも“直書きでいい”
性別・ステータスなどの小さなenumは、
PocketBaseのフィールド定義と同じ定数をSvelte側に持っていても構わない。
- どうせ数が少ない
- ビジネス的にもそう簡単には増えない
- 変わるときはコード改修でよい
「マスタを編集したい」わけではなく、
「ただ値を統一しておきたい」だけなら、
enum+共通定数で十分だ。
6. 実際に移行するときのチェックリスト
AccessアプリをPocketBase+Svelteに持っていく前に、
テーブルを一覧して次のように仕分けするといい。
- 性別・フラグ・はい/いいえ系:
→ enum(selectフィールド)に変換 - 都道府県・部署・担当者など:
→ 真のマスタとしてコレクション化 - 単価・ランク・種別マスタ:
→ 設定テーブル(pricing_rules, settingsなど)に集約
→ 不要な分割マスタは統合 - クエリ(保存クエリ・View的なもの):
→- まず必要な集計/一覧機能を洗い出す
- PocketBaseのAPI(+必要ならBun/NodeのAPI)で実現可能な形に組み直す
- UI側では「整形済みデータ」を受け取る
- フォーム・サブフォーム:
→- 画面単位でSvelteコンポーネントに分割
- 状態遷移や依存関係が複雑なものはXStateなどに逃がす
この仕分けだけでも、「マスタ病」がかなり落ちるはず。
7. まとめ
- Access時代の「なんでもマスタ」は、当時の事情もあってそれなりに合理性があった
- しかしそのままWeb世界に持ち込むと、設計が重くなり、保守性も落ちる
- PocketBase+Svelteでは
- 小さな固定値 → enum
- 意味のある軸 → 真のマスタ
- 運用で変わるもの → 設定テーブル
- 条件分岐だらけのロジック → コード(できれば状態マシン)
にきれいに分解したほうがいい
Accessおじさんの資産をそのまま移植するのではなく、
「思想だけ引き継いで、実装は現代のやり方にする」のが正解だと思う。
8. ケース別:AccessマスタをPocketBaseへ移行するとどう変わる?
Access時代の“お決まりマスタ”を例にして、
PocketBase+Svelteでどう整理されるのか、
実際のテーブル定義レベルで比較していく。
8-1. 性別マスタ(GenderMaster)の場合
■ Access側(狂気の例)
M_Gender
----------------
GenderID | Name
1 | 男
2 | 女
3 | 不明
フォームでは毎回これとJOIN。
クエリも必ず JOIN。
■ PocketBase側(健全な世界)
users
- gender: select ["male", "female", "other"]
終了。
- マスタテーブル → 廃止
- JOIN → 不要
- 管理画面 → 値は固定なので編集不要
性別のように「世界観として増えない(頻繁に更新しない)」ものは
enum(select型)で持つのが最適解。
8-2. 都道府県マスタ(PrefectureMaster)
■ Access側(よくあるやつ)
M_Prefecture
--------------
PrefID | Name
1 | 北海道
2 | 青森
…
47 | 沖縄
顧客マスタ・住所マスタとJOINしまくる。
■ PocketBase側(これは“真のマスタ”なので残す)
prefectures(コレクション)
- name: text
- code: number
顧客のテーブルはこう:
clients
- name: text
- prefecture: relation(prefectures)
ここは 正当なマスタ として残すのが正解。
- 将来増えない
- UIの選択肢として必要
- 他のレコードから何十回も参照される
- PocketBase管理画面で簡単に編集できる
Accessの正規化思想が正しく生きる場所は“ここだけ”。
8-3. 単価マスタ(PricingMaster)
印刷・卸・製造系に頻出の地獄。
Access時代は:
M_Paper
M_Color
M_CopyCount
M_UnitPrice
M_CalcRule
…
気付いたら 10マスタ と 20のクエリ がぶら下がる。
■ PocketBase側:ぜんぶ「設定コレクション」に集約
pricing_rules
- paper: select ["N40", "N30", "ケント紙"]
- color: select ["black", "fullcolor"]
- copies: number
- unit_price: number
- note: text
こうすることで:
- マスタ乱立 → 1コレクションに統合
- Accessのクエリ → PocketBaseのfilterで代用 or フロント整形
- 複雑な計算 → Svelte or XStateで実行
Accessのように
マスタ単位で分割しすぎる弊害を完全除去できる。
9. クエリ(アクセスの保存クエリ)をどう移行するか
Accessの世界では最重要だった「クエリ」。
SQLを書く場所でもあり、実質的なビジネスロジックの核心部分。
問題はこれをそのままPocketBaseに移せないこと。
PBにはJOINもVIEWもない。
でも焦る必要はない。
9-1. PBで置き換えられる部分は意外と多い
- 単純なフィルター(WHERE相当)
- ソート(ORDER BY)
- ページング
- 特定フィールド条件の絞り込み
PocketBaseのRESTは「filter」で結構強いことができる。
例:
?filter=(copies=2 && size='A4')
簡単なクエリなら十分代替可能。
9-2. JOINが必要な一覧は“フロントJOIN”でOK
Accessおじさんは言う:
「JOINはDBでやるべきだ!」
Web開発者は言う:
「JOINはフロントでやっていい(データ量少ないなら)」
PocketBase+Svelteでは後者の考えでいい。
流れ
- PBから
ordersをフェッチ - relationを
expand=clientで展開 layersは order_id で追加フェッチ- 入力や表示に必要な形に整形して配列化
例:
[
{
id: "abc123",
title: "複写伝票A",
client: { name: "○○商事" },
layers: [
{ paper: "N40", color: "black" },
{ paper: "N30", color: "black" }
]
}
]
これでAccessの「主テーブル+子テーブル+JOIN済みクエリ」UIを
完全にSvelte側で再現できる。
9-3. どうしても多重JOINが必要なら「ミニAPI層」を足す
Bun・Deno・Nodeのどれでもいい。
軽量APIを1枚かませて、
- PB RESTを複数叩く
- 結果をJOIN
- JSONで返す
これでAccess時代のVIEW相当を再現できる。
PocketBaseの得意領域:
- 単純なCRUD
- 認証
- Realtime
- コレクション管理
苦手領域:
- 多段JOIN
- 複雑集計
- 業務ルールの実行
だから、
PBは“データレイク”
JOINや集計は“別レイヤー”
UIは“Svelteで組む”
という三段構成が一番しっくり来る。
10. 一刀両断の総まとめ
- Accessおじさんの“何でもマスタ病”はWebに持ち込んではいけない
- PocketBaseはシンプルなDB設計とenumが相性抜群
- 複雑ロジックはSvelte(+必要ならXState)に持ち込む
- JOINが必要ならフロントJOIN
- さらに複雑ならBun/NodeでミニAPI層を足す
- 結果、Access時代よりシンプルで綺麗な設計に収束する
11. ケーススタディ:Accessアプリを PocketBase+Svelte に移すとこうなる
ここでは、実在しそうで、あなたも触ったことがありそうな
“典型的Accessアプリ” を 1つモデルにする。
題材はこれ:
複写伝票の受注管理アプリ(Access97〜2003時代の遺産)
- 画面1枚に全部詰まってる
- サブフォームに子テーブルが大量
- クエリが17個くらい保存されてる
- 何でもマスタ化
- 複写枚数×紙×色の単価ルールが複雑
- 印刷現場のおじさんが長年使ってる
あなたの業界にガッツリ刺さるやつ。
11-1. Access版のテーブル構造(ありがちなやつ)
T_Orders
T_OrderDetails
M_Client
M_Paper
M_Color
M_CopyCount
M_Series
M_Binding
M_DeductionFlag ←地獄
M_PrintOption
M_Status
M_User
テーブル12個。
クエリ17個。
フォーム6枚。
レポート4枚。
ザ・Access遺産。
11-2. PocketBase版にするとこうなる(激スッキリ)
PocketBaseで作ると、
テーブル(コレクション)はたった6個で終わる。
orders
order_layers
clients
pricing_rules
users
settings(任意)
ポイント:
- “紙マスタ”“色マスタ”“複写枚数マスタ”などは 消滅
order_layersには複写枚数ぶんの行が入る- pricing_rules に単価ロジックを全部集約
- settings には「伝票サイズ」「ミシンオプション対応表」などを入れても良い
Access版の12テーブルが
PocketBase版の6コレクションに統合される。
理由は単純:
- enum(固定値)はテーブル不要
- 正規化しすぎるとPB側のAPIに合わない
- 現代Webは「フロントでJOIN」する方が早い
11-3. UI(Svelte)側の画面構造も変わる
Access版は:
- メインフォーム
- サブフォーム
- その中にさらにサブフォーム
- タブコントロールで詳細を切り替え
- JOINクエリが裏で暴れまわる
Svelte版はもっとシンプルになる:
OrderForm.svelte
├ BasicFields.svelte(ヘッダ)
├ LayerRepeater.svelte(複写枚数のレイヤーUI)
├ Options.svelte(ミシン・減感など)
└ Summary.svelte(自動見積り)
フロントがUIロジックを受け持つので、
バックエンド側に不必要な正規化がいらなくなる。
11-4. クエリ(Access時代の地獄)をどう移す?
Access時代:
- “受注一覧(今月分)”クエリ
- “印刷待ち一覧”クエリ
- “納品済み一覧”クエリ
- “請求書発行待ち一覧”クエリ
- “伝票合計単価”クエリ
- “レイヤー別単価算出”クエリ
これらをぜんぶSQLで定義していた。
PocketBase版はこうする:
① 単純一覧はPBの filter で代用
?filter=status='pending'
② “レイヤー付き一覧”は expand
?expand=client
(子テーブルは別フェッチ)
③ “単価算出”はSvelte側で計算する
PBにはJOINも計算機能もないので、
pricing_rules を全部取得してフロントで条件分岐する。
XStateを使えば:
- copies が変わった
- 標準紙→特殊紙に変えた
- 減感ON→OFFにした
- ミシンの有無が変わった
こういう「Access VBAじゃないと無理だった処理」が
状態遷移図として整理され、きれいに実装できる。
11-5. 実際のデータ構造比較
● Accessの注文データ(例)
Orders
OrderID: 102
ClientID: 3
Title: "A社 2枚複写 注文"
Paper1ID: 1
Paper2ID: 2
Color1ID: 1
Color2ID: 1
Copies: 2
DeductionFlagID: 1
BindingID: 2
PaperID、ColorID、FlagID、BindingID…
ID地獄。
● PocketBaseの注文データ(例)
orders:
{
id: "abcd1234",
title: "A社 2枚複写 注文",
client: "client_record_id",
copies: 2,
note: ""
}
order_layers:
[
{
order: "abcd1234",
layer_index: 1,
paper: "N40",
color: "black"
},
{
order: "abcd1234",
layer_index: 2,
paper: "N30",
color: "black"
}
]
Accessのように「テーブルを横に広げる」感覚ではなく、
縦方向(レコード追加)で複写レイヤーを表現する。
この方が:
- UIで制御しやすい
- XStateで扱いやすい
- 子テーブル管理がシンプル
とにかく 綺麗に収まる。
11-6. Access時代より、はるかに保守しやすい理由
- 画面はSvelteが受け持つ
- 個別ロジックはXStateに追い出せる
- PBのコレクションは最小限
- enumで済むものはenumにする
- Realtimeで自動反映もできる
- デプロイがEXE1個で終わる
- DBはSQLite(WAL)で十分すぎる性能
Access時代の「マスタ乱造」「VBAスパゲッティ」「フォーム肥大化」から解放される。
12. PocketBase × Svelte × XState の“理想的な役割分担”
PocketBase(以下 PB)、Svelte、XState──
この3つは「小規模〜中規模の社内業務アプリ」「Access脱却」「ローコード代替」の文脈で、異常なほど相性が良い。
なぜここまで綺麗にハマるのか?
その理由は、役割の“ズレ”が一切ないからだ。
PB:データと認証を“正しく”担当する
PBはバックエンドを抱え込む。
- スキーマ定義
- 認証
- CRUD
- リアルタイム更新
- ファイルストレージ
これを 単一バイナリで完結させてしまう。
Accessのような“なんでもかんでも1ファイル”のノリを、
正しい形でインターネット時代に翻訳した存在と言っていい。
DBのことを一切考えず、テーブル作る・API叩く・トークン管理する
──全部 PB に押し付けられるのが最高。
Svelte:PBを“薄く・高速に”使うUI
Svelte は“リアルフロントエンド”。
React のようにフレームワークそのものが巨大ではなく、
コンパイル後は「ただの JS」になる。
つまり、PBの API を叩く UI も軽い。
- PB の ListView をサクッと表に
- レコードの編集フォームをその場で作成
- リアルタイム購読で一覧が勝手に更新
「Accessのサブフォームを web に置き換える」と考えれば完全一致。
XState:人間の“業務手順”をコード化する
Accessで一番悲惨なのはここ。
UI に業務ロジックをベタ書きするから地獄が始まる。
- ボタン押したらMsgBox
- 入力チェックを複数箇所でコピペ
- フォームの開閉で状態がバグる
- レコード移動で意図せぬイベント発火
業務アプリの8割は「状態管理(この画面は今どういう段階?)」で決まる。
そこに XState が“公式の答え” を提示する。
- 入力中
- 検証中
- 保存中
- 保存完了
- エラー
- 再編集
これらを 状態遷移図で表現する → そのままコードになる。
人間の業務手順を、手続きではなく“状態”で定義する。
Access 時代に一番欠けていたレイヤーだ。
なぜこの3つを組み合わせると“Access超え”が成立するのか?
結論:
Accessでグチャグチャになっていた“責務”がキレイに分断されるから。
| 役割 | Access | PB + Svelte + XState |
|---|---|---|
| データ | フォームに直刺し | PocketBase(API + 認証 + DB) |
| UI | コントロール地獄 | Svelte(軽量・分離) |
| 業務ロジック | VBA・マクロ混在 | XState(状態モデル化) |
| 配布 | MDBコピー問題 | 1つのWebアプリで全員使える |
Accessが“悪いんじゃない”。
現代の業務要件を満たす設計になっていないだけだ。
PB/Svelte/XState の三位一体で構成すると、
Accessの“便利さ”は維持したまま、
地獄ポイントだけ全部取り除ける。
今回のまとめ:この3つは「役割破綻しない」奇跡の組み合わせ
- PB が データと API を一元管理する
- Svelte が UI を軽量・高速に描画する
- XState が 業務フローをコードで再現する
三者が互いに食い合わない。
この組み合わせは、「社内アプリ開発の理想形」にかなり近い。
13. PocketBase + Svelte + XState の開発環境を10分で整える
開発環境を10分で準備するステップ
最速で「Accessアプリの代替 Web 環境」を動かすための、
PocketBase + Svelte + XState の最小構成を 10分以内 で整える手順。
この章は「余計な説明ゼロ」「最短ルート」に徹する。
1. PocketBase を置く(30秒)
- https://pocketbase.io/ から最新バージョンをダウンロード
- ZIP を解凍して、任意のフォルダに置くだけ
- 実行:
./pocketbase serve
これで以下が一気に起動:
- APIサーバー
- SQLite
- 認証
- 管理UI(Admin Panel)
- Realtime(WebSocket)
アクセス先:
http://127.0.0.1:8090/_/
この瞬間、バックエンド全完備。
2. Svelte プロジェクトを作る(1分)
Node が入っている前提で(14以降推奨):
npm create vite@latest pb-app -- --template svelte
cd pb-app
npm install
npm run dev
これだけで Svelte の開発サーバーが立つ。
URL:
http://localhost:5173
UI実装の土台が完了。
3. PocketBase JS SDK を追加(30秒)
Svelte で PB を扱いやすくするために SDK を入れる:
npm install pocketbase
あとはコンポーネントで:
import PocketBase from "pocketbase";
const pb = new PocketBase("http://127.0.0.1:8090");
これで CRUD / Auth / Realtime の全部が使える。
4. XState を追加(30秒)
状態管理(Access VBAの代替核)を入れる:
npm install xstate
Svelte とは相性が良いので、後段でそのまま使える。
5. とりあえず “orders” コレクションを作る(1〜2分)
PocketBase Admin UI で:
- 「New collection」
- 名前:
orders - 型:Base
- フィールドを追加:
| Field | Type |
|---|---|
title | text |
copies | number |
size | select(A4縦 / A4横 / B5縦) |
note | text(任意) |
これで Access の“注文テーブル”が完成。
権限は開発用に:
- List / View / Create / Update / Delete →
true
でいい(本番では閉じる)。
6. Svelte 側で “注文を保存するミニフォーム” を追加(3分)
src/App.svelte に貼るだけで動く最小サンプル:
<script>
import PocketBase from "pocketbase";
const pb = new PocketBase("http://127.0.0.1:8090");
let title = "";
let size = "A4縦";
let copies = 2;
async function submit() {
await pb.collection("orders").create({
title,
size,
copies,
});
alert("保存しました!");
title = "";
copies = 2;
}
</script>
<form on:submit|preventDefault={submit}>
<input bind:value={title} placeholder="案件名" />
<select bind:value={size}>
<option>A4縦</option>
<option>A4横</option>
<option>B5縦</option>
</select>
<input type="number" bind:value={copies} min="1" max="4" />
<button>保存</button>
</form>
これだけで PB → DB保存 → Svelte反映 の一連が動く。
Accessならテーブル直編集・フォーム直結で済んでた部分を、
PB+Svelteでも最短で再現した状態。
7. リアルタイム一覧も1行で動く(追加1分)
PocketBaseの強みその1。
SvelteはJSがそのまま描画されるので、Realtime購読も簡単。
pb.collection("orders").subscribe("*", (e) => {
console.log("変化あり:", e);
});
Accessの「リスト再クエリ」のために
RefreshやMe.Requeryしてた暴力を、PBが自動で解決してくれる。
8. これで“開発に入れる状態”が100%整う(合計10分)
- PB → サーバー/DB/認証
- Svelte → UI
- XState → 業務ロジック
- PB SDK → 実質的にローコード環境
あとは機能を追加していくだけで、
Accessアプリの置き換えが着々と進む。
XState の最小サンプル
本当に最小の動くマシン:
import { createMachine } from "xstate";
const orderMachine = createMachine({
id: "order",
initial: "editing",
states: {
editing: {
on: { SUBMIT: "saving" }
},
saving: {
on: { SUCCESS: "done", FAIL: "editing" }
},
done: {}
}
});
Access VBAの“BeforeUpdate/AfterUpdateイベント地獄”を
状態遷移で一刀両断できる未来がここにある。



