DelphiとSQLiteで作る軽量タスク管理アプリ
DelphiとSQLiteを活用して、軽量な業務用タスク管理アプリを構築したい方へ。
このページでは、FireDACによるDB接続、VCLコンポーネントの配置、トリガー管理などを、ソースコード不要の手法で丁寧に紹介します。
Delphiのプロパティ設定だけで完結する、実務に役立つ開発スタイルを提案します。(ソースコードは1行も記述しません)
Delphiは、コンポーネントとプロパティ設定だけで簡潔なデータベースアプリケーションを構築できる開発環境です。
データベースの作成
SQLiteのデータベースとテーブル作成には「DB Browser for SQLite(無料)」が便利です。
下記ページからダウンロードできます:
▶ https://sqlitebrowser.org/dl/
「DB Browser for SQLite」を起動して「新しいデータベース(N)」をクリックして、
ファイル名を task.db として保存します。
「SQL実行」タブに切り替えて以下のSQLを実行してテーブルとインデックスとトリガーを作成します。
「変更を書き込み」を押して「DB Browser for SQLite」を終了します。
-- ステータス マスタ テーブルの作成
CREATE TABLE IF NOT EXISTS tm_status(
status_id INTEGER,
status_name VARCHAR
);
-- インデックス作成
CREATE INDEX IF NOT EXISTS idx_status_id ON tm_status(status_id);
-- レコード挿入
INSERT INTO tm_status(status_id, status_name) VALUES(1,'未完了'),(2,'進行中'),(3,'完了');
-- 優先度 マスタ テーブルの作成
CREATE TABLE IF NOT EXISTS tm_priority(
priority_id INTEGER,
priority_name VARCHAR
);
-- インデックス作成
CREATE INDEX IF NOT EXISTS idx_priority_id ON tm_priority(priority_id);
-- 優先度 マスタ テーブルへレコード挿入
INSERT INTO tm_priority(priority_id, priority_name) VALUES(1,'高'),(2,'中'),(3,'低');
-- タスク テーブルの作成
CREATE TABLE IF NOT EXISTS t_task(
task_id INTEGER PRIMARY KEY,
task_title VARCHAR NOT NULL,
task_text VARCHAR,
task_limit DATETIME,
task_status_id INTEGER NOT NULL DEFAULT 1,
task_priority_id INTEGER NOT NULL DEFAULT 1,
task_update DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
task_regdate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- インデックス作成
CREATE INDEX IF NOT EXISTS idx_task_limit ON t_task(task_limit);
-- トリガーの作成 トリガーで更新日時カラムを更新する
CREATE TRIGGER IF NOT EXISTS trg_update_t_task
AFTER UPDATE OF task_title, task_text, task_limit, task_status_id, task_priority_id ON t_task
FOR EACH ROW
BEGIN
UPDATE t_task SET task_update = CURRENT_TIMESTAMP WHERE task_id = OLD.task_id;
END;
データベース「task.db」
tm_status(ステータスマスタテーブル)
| status_id | INTEGER | ステータスID |
| status_name | VARCHAR | ステータス |
tm_priority(優先度 マスタテーブル)
| priority_id | INTEGER | 優先度ID |
| priority_name | VARCHAR | 優先度 |
t_task(タスク テーブル)
| task_id | INTEGER | タスクID |
| task_title | VARCHAR | タスク名 |
| task_text | VARCHAR | タスク詳細 |
| task_limit | DATETIME | タスク期限 |
| task_status_id | INTEGER | タスク ステータスID |
| task_priority_id | INTEGER | タスク 優先度ID |
| task_update | DATETIME | 更新日 |
| task_regdate | DATETIME | 登録日 |
ER図
t_task(タスク テーブル) task_id tm_status(ステータスマスタテーブル) task_status_id ─── status_id task_priority_id ─┐ │ tm_priority(優先度 マスタテーブル) └─ priority_id
JCL、JVCLのインストール
Delphiでデータベースアプリケーションを作成する場合、JCL及びJVCLをインストールしておくと便利です。
[GetItパッケージマネージャー]から 「JCL(JEDI Component Library)」と「JVCL(JEDI Visual Component Library)」をインストールすることが出来ます。
プロジェクトの作成と画面設計
プロジェクトを新規作成(VCLアプリケーション)します。
フォーム(Form1)上に以下のようにコンポーネントをドラッグ&ドロップで配置配置します。
「すべて保存」をクリックして、任意のディレクトリを作成し、ユニット(Unit1.pas)とプロジェクト(Project1.dproj)を保存します。
| TFDConnection | 1個 | Form1の上に配置 |
| TFDQuery | 1個 | Form1の上に配置 |
| TDataSource | 3個 | Form1の上に配置 |
| TFDTable | 2個 | Form1の上に配置 |
| TJvDBGrid | 1個 | Form1の上に配置 |
| TPanel | 1個 | Form1の上に配置 |
| TLabel | 6個 |
Panel1の上に配置し、Captionプロパティを以下6つに設定しておく
|
| TDBText | 1個 | Panel1の上に配置 |
| TDBEdit | 1個 | Panel1の上に配置 |
| TDBMemo | 1個 | Panel1の上に配置 |
| TJvDBDatePickerEdit | 1個 | Panel1の上に配置 |
| TJvDBLookupCombo | 2個 | Panel1の上に配置 |
| TDBNavigator | 1個 | Panel1の上に配置 |
ここで一旦、[プロジェクト] ⇒ [全てのプロジェクトをコンパイル] をクリックします。
プロジェクトフォルダ内に「\Win32\Debug」フォルダが生成されます。
上記で作成したデータベース task.db ファイルを
「プロジェクトフォルダ\Win32\Debug」に移動させましょう。
SQLiteのダウンロードと配置
SQLiteは1つのDLLファイルだけでローカルデータベースとして動作するのでとても便利です。
https://www.sqlite.org/download.html
から32Bit版「sqlite-dll-win32-x86-3430100.zip(580.14 KiB)」(最新バージョンでOKです)を
ダウンロードして解凍し「sqlite3.dll」ファイルを
上記で作成したプロジェクトディレクトリの「\Win32\Debug」と「\Win32\Release」に配置します。
64Bit版も必要な場合は「sqlite-dll-win64-x64-3430100.zip(1.18 MiB)」(最新バージョンでOKです)を
ダウンロードして解凍し「sqlite3.dll」ファイルを
上記で作成したプロジェクトディレクトリの「\Win64\Debug」と「\Win64\Release」に配置します。
画面設計の続き
FDConnection1 をダブルクリックします。
ドライバIDを「SQLite」に設定します。
[Database] を上記で移動したデータベース task.db(c:\users\・・・・・・・\プロジェクト名\Win32\Debug\task.db) に設定します。
[LockingMode] を Normal に設定します。
設定できたら「OK」ボタンを押して閉じます。
コンポーネントのプロパティを設定します。
| コンポーネント.プロパティ | 値 |
|---|---|
| FDConnection1.LoginPrompt | False |
| FDQuery1.Connection | FDConnection1 |
| DataSource1.Dataset | FDQuery1 |
| JvDBGrid1.DataSource | DataSource1 |
| JvDBGrid1.ReadOnly | True JvDBGrid1は一覧とレコード選択だけに使うので読み取り専用とする |
| FDTable1.Connection | FDConnection1 |
| FDTable1.TableName | tm_status |
| DataSource2.Dataset | FDTable1 |
| FDTable2.Connection | FDConnection1 |
| FDTable2.TableName | tm_priority |
| DataSource3.Dataset | FDTable2 |
| DBNavigator1.DataSource | DataSource1 |
FDQuery1 をダブルクリックします。
以下のSQLを入力します。「OK」を押して閉じます。
SELECT
task_id, task_title, task_text,
task_limit, task_status_id, status_name,
task_priority_id, priority_name
FROM t_task
LEFT OUTER JOIN tm_status
ON t_task.task_status_id=tm_status.status_id
LEFT OUTER JOIN tm_priority
ON t_task.task_priority_id=tm_priority.priority_id
FDQuery1、FDTable1、FDTable2コンポーネントのプロパティを設定します。
| コンポーネント.プロパティ | 値 |
|---|---|
| FDQuery1.Active | True |
| FDTable1.Active | True |
| FDTable2.Active | True |
JvDBGrid1をダブルクリックします。
表示されたウィンドウの上にある「全てのフィールドを追加」ボタンをクリックします。
JvDBGrid1のフィールドのプロパティを設定します。
| コンポーネント.プロパティ | 値 |
|---|---|
| JvDBGrid1.Columns[0].Width (task_id) | 40 |
| JvDBGrid1.Columns[0].Title.Caption (task_id) | タスクID |
| JvDBGrid1.Columns[1].Width (task_title) | 160 |
| JvDBGrid1.Columns[1].Title.Caption (task_title) | タスク名 |
| JvDBGrid1.Columns[2].Width (task_text) | 160 |
| JvDBGrid1.Columns[2].Title.Caption (task_text) | タスク詳細 |
| JvDBGrid1.Columns[3].Width (task_limit) | 112 |
| JvDBGrid1.Columns[3].Title.Caption (task_limit) | 期限 |
| JvDBGrid1.Columns[4].Width (task_status_id) | 0 |
| JvDBGrid1.Columns[5].Title.Caption (status_name) | 80 |
| JvDBGrid1.Columns[5].Width (status_name) | 状態 |
| JvDBGrid1.Columns[6].Title.Caption (task_priority_id) | 0 |
| JvDBGrid1.Columns[7].Width (priority_name) | 80 |
| JvDBGrid1.Columns[7].Title.Caption (priority_name) | 優先度 |
入力用コンポーネントのプロパティを設定します。
| DBText1.DataSource | DataSource1 |
| DBText1.DataField | task_id |
| DBEdit1.DataSource | DataSource1 |
| DBEdit1.DataField | task_title |
| DBMemo1.DataSource | DataSource1 |
| DBMemo1.DataField | task_text |
| JvDBDatePickerEdit1.DataSource | DataSource1 |
| JvDBDatePickerEdit1.DataField | task_limit |
ルックアップフィールド(TJvDBLookupCombo1) コンポーネントの設定
ルックアップフィールドを使うと、別のデータセット(マスタテーブル)の一覧を表示しながらレコードにキー値を設定することが出来ます。
| JvDBLookupCombo1.DataSource | DataSource1 (このデータソースに値を設定する) |
| JvDBLookupCombo1.DataField | task_status_id (このカラムに値を設定する) |
| JvDBLookupCombo1.LookupSource | DataSource2 (一覧として表示するデータソースを指定する) |
| JvDBLookupCombo1.LookupField | status_id (このカラムの値を設定する) |
| JvDBLookupCombo1.LookupDisplay | status_name (このカラムの値を一覧表示する) |
| JvDBLookupCombo2.DataSource | DataSource1 |
| JvDBLookupCombo2.DataField | task_priority_id |
| JvDBLookupCombo2.LookupSource | DataSource3 |
| JvDBLookupCombo2.LookupField | priority_id |
| JvDBLookupCombo2.LookupDisplay | priority_name |
実行する
実行ボタンを押して実行します。(デバッグ実行でもOK)
JvDBGridでデータを選択でき、DBNavigator1でレコードの移動などレコード操作が可能です。
下側のPanel1上のコンポーネントでレコードの編集が可能です。
TJvDBLookupCombo(JvDBLookupCombo1やJvDBLookupCombo2)でルックアップフィールドの編集が可能です。
