Appearance
SQLite 表ファイル形式
外部ツールや AI で ShinMT 互換の SQLite 表ファイルを作成する開発者向けに、必要なスキーマ、ページの JSON、表示幅と検証手順を説明します。
1. 必須スキーマ
必須テーブルは tablenames と metas の 2 つです。次の DDL で作成してください。
sql
CREATE TABLE IF NOT EXISTS tablenames (
page INTEGER UNIQUE NOT NULL,
name TEXT NOT NULL,
createdAt TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updatedAt TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
meta JSON NOT NULL);
CREATE TABLE IF NOT EXISTS metas (name TEXT UNIQUE NOT NULL, data JSON NOT NULL);| テーブル | 必須カラム | 内容 |
|---|---|---|
tablenames | page / name / createdAt / updatedAt / meta | ページ番号、表名、作成日時、更新日時、ページの JSON |
metas | name / data | ファイルのメタ情報の名前と JSON |
meta と data には有効な JSON 文字列を格納します。metas.data は NOT NULL のため、SQL の NULL を入れると制約違反になります。createdAt と updatedAt は INSERT 時に省略すると CURRENT_TIMESTAMP で補われます。
ユーザーの表ファイルには drives / settings を含めません。table_rows も新規作成には不要です。既存ファイルにある場合の移行は ShinMT に任せてください(開く際、移行が済んで残る行がなくなった段階で撤去されます)。
2. metas の 4 エントリとページ番号
metas.name は次の 4 種のみです。4 行すべてを作成する必要はなく、通常の表だけを作る最小例では type のみを指定できます。
name | data の内容 |
|---|---|
type | 固定型は {"is":"F","pagemax":3}、可変型は {"is":"V"} |
programs | 登録プログラムの名前とページ番号の配列。例: [{"name":"集計","page":1}]。空の場合は [] |
fileinfo | ファイル情報。省略可能な remarks(文字列)と readonly(真偽値)を持つオブジェクト。空の場合は {} |
menu config | ファイルのメニュー設定を持つオブジェクト。設定がない場合は {} または行を省略 |
F 型・V 型の概要は ファイルとページ を参照してください。type 行がないファイルは V 型として扱われます。
ページ番号は 1 始まりの正の整数で作成してください。F 型の pagemax は最大ページ番号であり、ページ数でもあります。F 型は作成時に 1〜pagemax のすべてのページを事前に埋め、未使用ページには空ページの JSON を入れます。ShinMT は page > pagemax への書き込みを拒否します。
page には UNIQUE NOT NULL がありますが、1 始まり・正数であることや pagemax の上限は DB 制約では強制されません。page と pagemax は正の安全な整数(0 より大きい安全整数)で作成し、外部作成側で守ってください。
V 型には、ShinMT で書き込んだページより後ろのページを削除する書き込み動作があります。外部で末尾に追加したページも、後のアプリ操作で消える場合があります。
3. lines6 の JSON 構造
表ページは tablenames.meta に次のトップレベルキーを持つ JSON として格納します。
| キー | 内容 |
|---|---|
is | "lines6" |
digitnums | 列幅と位置揃えの配列。詳細は第 5 節を参照 |
prefix | 表名・フォーマット行など、項目行より前の行の配列 |
head | 項目行の配列 |
body | データ行の配列 |
suffix | データ行より後ろの行の配列 |
sticky / overlayImages / designMeta | 省略可能な表示設定。最小例では省略 |
使わない行配列も [] として指定します。表名は tablenames.name に保存します。表名・フォーマット行・項目行・データ行の概念は 表の構成 を参照してください。
基本的な行とセルの記法は次のとおりです。
| 記法 | 用途 |
|---|---|
{"is":"title"} | prefix に置く表名の行 |
{"is":"format"} | prefix に置くフォーマット行 |
{"is":"divider"} | 行配列に置く横罫線 |
{"is":"list","arr":[...],"meta":{}} | head / body に置くセル配列の行 |
{"is":"value","value":"120"} | arr 内の値セル |
{"is":"divider"} | arr 内の縦罫線セル。対応する digitnums 要素は null |
list 行には arr と meta: {} を付け、arr の各位置を digitnums の各位置に対応させます。セル値は数値も含め常に文字列です。たとえば数量は "value":"120" とし、"value":120 にはしません。空のセルは {"is":"value","value":""} です。
旧形式は読み込み互換がありますが、新規作成は lines6 を使用してください。
tablenames.meta の JSON が壊れていても、そのファイルはファイル一覧には残りますが、ファイルを開くとき(表の一覧やページの読み込み)に失敗します。 書き込み後には、第 7 節の json_valid(meta) による全行検証を必ず行ってください。
4. 空ページの 2 形式
読み込み時には次の両方を受け付けます。
| JSON | 使用される場面 |
|---|---|
{"isEmpty":true} | F 型作成時の空ページの事前充填 |
{"is":"empty"} | ページのクリア後、または表を持たない画面の書き込み |
外部から新規作成する場合は {"is":"empty"} を推奨します。isEmpty は旧形式扱いです。F 型の空ページの事前充填でも、外部からの新規作成では {"is":"empty"} を使って構いません(読み込みは両形式を受理します)。空ページも tablenames の 1 行として保存し、表名がなければ name に空文字列を指定します。
5. 表示・フォーマット仕様
digitnums と位置揃え
digitnums の各要素は {"size":12} のようなオブジェクト、または縦罫線列を表す null です。lines6 では数値だけの要素は解釈されません。
json
[{ "size": 12, "align": "start" }, null, { "size": 6 }]size の単位は 半角文字数です。半角 1 文字が 1、全角 1 文字が 2 に相当します。通常表示での列幅は概算で size × フォントサイズ ÷ 2 px です(簡易表示など一部の画面では別の式になります)。印刷設定によって文字送りを変更した場合は、印刷時の列幅も変わります。画面幅を超える表は横スクロールして確認してください。
align | 位置揃え |
|---|---|
"start" | 左寄せ |
"center" | 中央寄せ |
| 省略 | 右寄せ |
保存する align の正式値は start / center の 2 つだけで、右寄せを示す値はありません。数値列は align を省略してください。
ShinMT が不足する列を補うときの既定値は {"size":12} です。セル値の表示幅が size に満たない分は、描画時に位置揃えに応じて空白が補われます。外部作成側で余白文字を埋める必要はありません。
size の範囲と推奨値
| 項目 | 値 |
|---|---|
| 最小 | 1 |
| 最大 | 上限は設けていません |
| 推奨 | 後述の「外部作成時の自動幅算出」で求めた値。余裕を持たせる場合は 2 を加えた値 |
外部から作成するときは、size を 1 以上の整数にしてください。size の範囲は DB 制約では強制されないため、外部作成側で守ってください。1 以上の整数以外の値を書いた場合の表示は保証しません。
画面幅を超えるとき
ShinMT は、列幅を画面の幅に合わせて縮めたり、セルの中で文字を折り返したりしません。列幅の合計が画面の幅を超える表は、横スクロールして表示します。推奨は、列幅を上の「size の範囲と推奨値」の表の推奨値のまま、横スクロールで表示することです。 ファイルの size をセル値の表示幅より小さく書くことは推奨しません。ShinMT で開いたあとに表を画面内に収めたい場合は、列を減らすか、CF コマンドで幅を詰めてください。CF で幅を詰めると、セル値が切り詰められる場合があります(次の「CF コマンド」の注意を参照してください)。
CF コマンド
CF の基本操作は データを整形する を参照してください。構文は cf:対象列:新しい桁数 です。引数を省略すると対話入力に進みます。対象列の入力で空入力または a を指定すると全列が対象になります。
| 入力例 | 動作 |
|---|---|
cf:1:8 | 1 列目を幅 8 に変更 |
cf:1-3:8 | 1〜3 列目をそれぞれ幅 8 に変更 |
cf:a:+2 | 全列の現在の幅にそれぞれ 2 を加算 |
cf:1:-2 | 1 列目の現在の幅から 2 を減算 |
cf:a:p | 各列を項目行・データ行の最大表示幅に合わせる |
cf:1-3:p+2 | 各対象列の最大表示幅にそれぞれ 2 を加えた幅にする |
cf:1:p-1 | 1 列目の最大表示幅から 1 を引いた幅にする |
+N / -N / p / p+N / p-N の計算結果は最低 1 になります。縦罫線列の null は幅変更の対象になりません。変更は対象列の digitnums の size に反映され、位置揃えは維持されます。
CF は画面の表に適用されます。ファイルに保存するには W コマンドを実行してください。保存操作は データを保存・読み込む を参照してください。
CF による幅変更では、項目行・データ行のセル値も変更される場合があります。 対話操作で、幅に収まらない部分の切り詰めや位置揃えに応じた端の空白の除去が発生する場合は、実行前に確認が表示されます。たとえば、右寄せで幅 10 のセル "あいうえお" に cf:1:5 を適用し、確認して実行すると "えお" になります。
外部作成時の自動幅算出
CF の p と同じ基準で幅を決めるには、次の手順を使います。
- 各列について、
headとbodyのすべてのlist行から、その列のis: "value"のセルを集めます。罫線は対象外です。 - 各セルの文字列の表示幅を半角文字数で求め、列ごとの最大値を取ります。値がない列の最大値は 0 とします。
size = max(1, 最大表示幅)を設定します。余裕を 2 桁設ける場合はmax(1, 最大表示幅 + 2)とします。- 位置揃えを設定し、元のセル文字列を保存します。自動幅に合わせるための余白文字は追加しません。
表名、フォーマット行、prefix / suffix の付加行は、この自動幅算出には含めません。たとえば、項目名 "商品" と本文 "りんご" の列は最大表示幅が 6 なので size: 6、項目名 "数量" と本文 "120" の列は size: 4 です。
表示幅は文字列の長さとは異なります。確認できる例として、"A" は 1、"A"・"あ" は 2、絵文字 "😀"・"👨👩👧👦" はそれぞれ 2 です。すべての絵文字列を文字数だけで数えず、ShinMT での表示幅を確認してください。
6. 安全な取り扱い
ShinMT が当該ファイルを開いている間は、外部から書き込まないでください。 外部変更が反映されない読み取りやファイル破損を避けるため、ShinMT を終了してから作業用コピーを作り、そのコピーを更新することを原則にします。
ジャーナルは既定の DELETE モードを使用します。WAL モードには変更しないでください。通常、-wal / -shm ファイルは存在しません。-journal が残っている場合は、前回の異常終了などの痕跡として、外部で変更したり削除したりせず、まず ShinMT で開いて正常化し、正常終了してから作業してください。
書き込み後は tablenames 全行の json_valid(meta) を検証します。1 行でも不正な JSON があると、そのファイルはファイル一覧には残りますが、開くときに表の読み込みが失敗するため、修正と再検証を終えてから ShinMT で開いてください。
7. 検証方法・最小作成例
SQLite のコマンドラインツール sqlite3 を使い、V 型ファイルに 1 ページの表を作成する例です。既存ファイルと重ならない新しいファイル名を使用してください。
この節の手順で作成したファイルを、最小サンプル(sqlite-format-sample.sqlite)としてダウンロードできます。内容は架空のサンプルで、列幅は第 5 節の自動幅算出で求めた値です。ダウンロードしたファイルを検証するときは、作成後に実行する検証コマンド(sqlite3 -readonly で始まるコマンド)の sample.sqlite をこのファイル名に置き換えてください。ShinMT で開く手順は、この節の最後にあります。
第 1 節の DDL を create-sample.sql に保存し、続けて次の INSERT を同じファイルに追記します。表名と内容は架空のサンプルです。
sql
INSERT INTO metas (name, data) VALUES ('type', '{"is":"V"}');
INSERT INTO tablenames (page, name, meta) VALUES (
1,
'商品サンプル',
'{
"is": "lines6",
"digitnums": [{"size":6,"align":"start"},{"size":4}],
"prefix": [{"is":"title"},{"is":"format"}],
"head": [
{"is":"list","arr":[
{"is":"value","value":"商品"},
{"is":"value","value":"数量"}
],"meta":{}},
{"is":"divider"}
],
"body": [
{"is":"list","arr":[
{"is":"value","value":"りんご"},
{"is":"value","value":"120"}
],"meta":{}}
],
"suffix": []
}'
);"120" は JSON の文字列です。programs / fileinfo / menu config と省略可能な表示設定は、最小例では作成していません。
bash
sqlite3 -bail sample.sqlite < create-sample.sql作成後、または外部から更新した後に、次を実行します。
bash
sqlite3 -readonly -bail sample.sqlite <<'SQL'
PRAGMA integrity_check;
PRAGMA journal_mode;
SELECT count(*) AS invalid_pages FROM tablenames WHERE json_valid(meta) = 0;
SELECT count(*) AS invalid_file_metas FROM metas WHERE json_valid(data) = 0;
SELECT page, name FROM tablenames ORDER BY page;
SQL最小例での出力は次のとおりです。
text
ok
delete
0
0
1|商品サンプルinvalid_pages は特定のページに絞らず全行を調べています。必ず 0 であることを確認してください。integrity_check の ok と JSON の検証は別々に必要です。また、json_valid は JSON の構文を確認するもので、lines6 のキー、セル値の型、ページ番号まで保証するものではありません。
検証後、ファイルを ShinMT で開いて確認します。ファイル名は小文字の .sqlite 拡張子にしてください(._ で始まる名前のファイルは一覧に現れません)。ShinMT のファイル一覧には、登録済みの保存先フォルダ(ドライブ)の直下にあるファイルだけが表示されます。任意の場所に作成したファイルは一覧に現れないため、登録済みフォルダに置くか、未登録の場合は ドライブ登録 で保存先フォルダを登録してください。
ファイル一覧から作成したファイルを開き、R(読み込み) でページ 1 を表示して、表名が「商品サンプル」、項目が「商品」「数量」、データが「りんご」「120」と表示されることを確認してください。
8. 対象バージョンと更新日
- 対象 ShinMT バージョン: 4.6.14 以降
- 仕様更新日: 2026-09-24
PRAGMA user_version と application_id はアプリが管理する内部値です(user_version は形式バージョンの管理に使われ、現在の形式バージョンは 1 です)。外部から新規作成するときは 0 のままで構いません。既存値は変更しないでください。