【体験版支援価格】「マルチマルチ」SQLITEを多対多リレーションとマルチビューで扱えるローカルDBCRUD
- Digital300 JPY


このアプリは、個人制作として作っているWindowsデスクトップ向けビューア兼・簡易エディタの体験版です。Next.js と Electron を使い、ローカルの SQLite データベースを直接扱えるのが大きな特徴です。 アプリは JSON プロファイルを読み込むことで、扱いたいデータ構造にあわせてビューやエンティティを自動的に切り替えます。テーブル・カード・カレンダーの3種類のビューを備えており、データを直感的に眺められる構成です。検索・フィルター・タグ絞り込み・グループ化など、個人利用の整理用途にも便利な機能をそろえています。 行をクリックすると詳細ダイアログが開き、テキスト・セレクト・タグ編集、画像やPDF、Markdownなどのプレビューにも対応しています。ファイルパスから外部アプリを開いたり、フォルダを表示したりと、ローカル作業との相性も良くしています。新規レコードを作るときはスキーマを自動解釈し、必要な初期値を入れてくれるので、ちょっとしたメモ管理や資料整理にも使えます。 モーダルウィンドウは外側クリックで閉じる、適用・閉じるボタンはスクロール外にはみでずに常にフッターに表示など、細かなUIにもこだわっています。 ……との以上は設計であり、現バージョンは全体的に「まず触れる状態まで作った」段階ですが、ローカルデータを手軽に整理したい人や、視覚的に物事を管理したい人には、制作中のワクワクも含めて体験してもらえる内容になっています。 【重大】データ消失は作者の実際の利用の範囲では起きていませんが、大量データでどうなるかは未確認です。 【注意】開発中の体験版です。一部機能が未実装です。 【注意】現在、設定JSONを手打ちしていただく必要があります。そのため、JSONを書ける方向けです。 【注意】個別の使い方サポートは行っておりません。 【情報】販売が増えれば、ノーコードで使えるように拡張できます。 展開後ファイルサイズ:約700MB 動作テスト:win11マシン2台で確認 体験版支援価格:300円 正式版予定価格:未定(支援者が増えれば機能拡張します) このアプリが気に入ったら #マルチマルチ でシェアしてくださると励みになります。また、開発の参考にさせていただきます。 姫草栞
アップデート履歴
[2025-12-01: v1.0.0] リリース
~同梱の「使い方.txt」本文~
# 初回起動 DLし、解凍してください。 解凍したファイルを開くと、 「マルチマルチ.exe」のアイコンが見えます。 起動はここから行います。 「resources」フォルダの中にサンプルデータと使い方が入っています。 初回起動ではサンプルデータが表示されます。 # 自分のデータを使う 自分のデータを使うための準備をします。 「resources」フォルダの中にconfig.sample.jsonがあります。 それをコピーし、ファイル名を変更してconfig.jsonを作ってください。 config.jsonを開き、自分で作る設定JSONの絶対パスを打ち込んでください。このとき、「\」ではなく「/」を使ってください。 # 設定JSONの書き方 「使い方2.txt」へ(執筆中) # アンインストールしたいとき アプリフォルダを丸ごと削除します。(ポータブルアプリです。) あなたのDBファイルを誤って消さないよう、注意してください。 2025/12/1 姫草栞:ダウンロードありがとうございました。
~同梱の「使い方2.txt」本文~
# 設定JSONの書き方ガイド このアプリでは、`config.json` に「メニューファイル(profiles-menu.json)の場所」を指定し、そのメニューファイルから各プロファイルJSONを読み込む流れになっています。ここでは `config.json` と `profiles-menu.json` の書き方、そしてメニューが参照する各プロファイルJSONの基本形をまとめます。 ## 1. config.json を作る 1. `electron/config.sample.json` をコピーして `config.json` を作成します。 2. `menu_json_path` に 絶対パスでメニューJSONへのパスを書きます。 - Windowsでもスラッシュ(`/`)で指定してください。 3. `config.json` はアプリフォルダの「resourses」フォルダにいれます。 ```json { "menu_json_path": "C:/data/profiles-menu.json" } ``` - パスが空の場合は、同梱の `./resourses/sample-data/profiles-menu.json` を読み込みにいきます。 ## 2. profiles-menu.json(メニュー設定)の書き方 メニューファイルは複数のプロファイルJSONをまとめるリストです。最低限 `buttons` 配列が必要です。 | キー | 型 | 説明 | | --- | --- | --- | | `menu_title` | 文字列 | メニュー上部に出すタイトル(省略可) | | `auto_load_first` | 真偽値 | true のとき最初のボタンを自動で読み込む | | `buttons` | 配列 | プロファイルを表すボタンの一覧 | | `buttons[].label` | 文字列 | ボタンに表示する名前 | | `buttons[].icon` | 文字列 | 絵文字などのアイコン(省略可) | | `buttons[].profile_json_path` | 文字列 | プロファイルJSONへのパス | | `buttons[].sqlite_path_override` | 文字列 | SQLiteファイルのパスを強制指定する場合に使用(省略可) | | `buttons[].default_view_id` | 文字列 | 起動時に開くビューID(省略可) | サンプル: ```json { "menu_title": "プロファイル切替", "auto_load_first": true, "buttons": [ { "label": "持ち物リスト", "icon": "🎒", "profile_json_path": "./sample-data/belongings.json", "sqlite_path_override": "./sample-data/belongings.db", "default_view_id": "items_table" }, { "label": "かんしゃ帳", "icon": "👐", "profile_json_path": "./sample-data/syaki.json", "sqlite_path_override": "./sample-data/syaki.db", "default_view_id": "event_table" } ] } ``` ### 3. プロファイルJSON(アプリの表示定義)の基本形 各ボタンが指すプロファイルJSONには「使用するDBテーブル」「表示するビュー」などを定義します。主なキーは以下のとおりです。 | キー | 必須 | 説明 | | --- | --- | --- | | `profile_name` | ○ | プロファイルの識別名 | | `storage.sqlite_path` | △ | 利用するSQLiteファイルへのパス。`sqlite_path_override` があればそちらが優先されます | | `entities` | ○ | 取り扱うテーブルとカラムを定義する配列 | | `entities[].fields[].type` | | `text` / `long_text` / `binary` / `pk` などフィールド型 | | `views` | ○ | 一覧表示(table/card/calendarなど)の設定 | 説明付きサンプルは使い方3を御覧ください。 ## 4. 動作確認のポイント - `config.json` → `profiles-menu.json` → 各プロファイルJSON の順で参照されます。 - パスはすべて正しい場所を指しているかを確認してください。 - JSONの構文エラーがあると読み込みに失敗します。オンラインのJSONバリデータを使うと安全です。
対応中の不具合
単一選択フィールドのUIで値を空白にできない
~同梱の「使い方3」本文~
JSONの書き方の説明 { "profile_name": "event_v1", ↑好きな名前をつけます。 "storage": { "sqlite_path": "D:/原本/A/実データ/nt.db", }, ↑DBの絶対パスを""で囲んで、いれます。 "entities": [ { "entity_id": "event", "label": "イベント", "source": { "table": "event" }, ↑DBのテーブルをエンティティとして読み取れるようにします。ソースにDBのテーブル名をいれてください。他2つは任意です。後で使うので使いやすいように名付けます。 "fields": [ { "field_id": "id", "label": "ID", "type": "pk", "source": { "column": "id" } }, ↑ソースのところにDBの列名をいれます。IDとラベルは任意です。タイプはデータ型で、マルチマルチで使いたいデータ型にします。マルチマルチはこのタイプをもとに入力UIを表示します。pkは主キーなので編集できません。 { "field_id": "path", "label": "ファイルパス", "type": "file_path", "source": { "column": "path" } }, ↑タイプ "file_path" は、エクスプローラ参照でファイルパスを入力することができるようになります。 { "field_id": "title", "label": "タイトル", "type": "text", "source": { "column": "title" } }, ↑タイプテキストは、テキスト入力ができます。 { "field_id": "date", "label": "日付", "type": "date", "source": { "column": "date" } }, ↑タイプdateは、yyyy-mm-ddの形式で打ち込むとソートができます。カレンダー入力UIを実装予定です。今はテキストと同じです。 { "field_id": "rank", "label": "ランク", "type": "select", "options_json": ["ルーキー","ブロンズ","失格"], "source": { "column": "rank" } }, ↑タイプselectは単一選択です。"options_json"に選択肢を書くことが出来ます。 { "field_id": "platform", "label": "プラットフォーム", "type": "select_multi", "options_json": ["現実","X","A"], "source": { "column": "platform" } } ↑タイプ"select_multi"は複数選択です。 ] }, { "entity_id": "tags", "label": "タグ", "source": { "table": "tags" }, "fields": [ { "field_id": "id", "label": "ID", "type": "pk", "source": { "column": "id" } }, { "field_id": "name", "label": "タグ名", "type": "text", "source": { "column": "name" } } ] } ], "relations": [ ↑多対多リレーションをここで示すことができます。 { "relation_id": "eve_tag", "label": "イベントのタグ", "type": "many_to_many", "left_entity": "event", "right_entity": "tags", "through": { "table": "eve_tag", "left_key": "eve_id", "right_key": "tag_id" }, ↑DB側でのリレーションテーブルを指定してください。現在の仕様では、DBスキーマを読み込むのみです。マルチマルチからリレーションテーブルを作成できません。 "lookups": [ { "into_field_id": "tag_list", "from": "tags.name", "display": "comma_join" }, { "into_field_id": "eve_list", "from": "event.title", "display": "comma_join" } ↑ルックアップができます。"into_field_id"で指定したIDのカラムを生成し、値はカンマ区切りとなります。マルチマルチでは各アイテムがチップとして表示され、チップクリックでアイテムに遷移できます。 ] } ], "views": [ { "view_id": "event_table", "entity_id": "event", "type": "table", ↑ビュー設定です。まずどのエンティティを表示するかを指定してください。typeは現在、table、card、calenderがあります。 "columns": ["title","date","rank","snd_list","platform","tag_list"], ↑表示したいカラムを指定してください。 "filters": { "logic": "AND", "clauses": [] }, "sort": [ { "field": "date", "dir": "DESC" } ], ↑デフォルトのソートです。 "display_props": { "preview": { "field": "path", "column_index": 10, "width": 300, "text_chars": 240 }, ↑サムネイルカラムの設定です。file_pathタイプのフィールドを指定し、何番目に表示するか、幅、テキストの場合の文字数を指定してください。 "column_widths": { "title": 200, "date": 220, "rank": 140, "platform": 200, "labelA": 200, "labelB": 200, "keyword": 400, "snd_list": 300, "tag_list": 300, "tagN_list": 300, "minTableWidthPct": 160 ↑カラムの幅を指定できます。"minTableWidthPct"を変更することでテーブルの横スクロールが変わります。 } } }, { "view_id": "event_cards", "entity_id": "event", "type": "card", "card": { "title_field": "title", "subtitle_field": "date", "media_field": "path", "chips": ["tag_list","snd_list"] } }, ] } } ] }

