ファイルメーカー(FileMaker)って、病院や教育現場でもよく使われる「あったら便利」を形にできるツールだと思います
しかし、
– 値段が高い
– もっと自分好みにカスタマイズしたい
という要望もあるかも知れません
院内にあるけど、自分のパソコンでできひんで、という声もあるかもしれません
個人的に買う気は全く起こらないのだが、確かにデータをまとめるのは便利とおもう
手術記録と紐づけて、検索できたりするし、研究の際に役立つ
新しく買うのは嫌なので、簡易でもいいからそれっぽいのを作ってみたい
ChatGPTに、記録用のファイルメーカーっぽいアプリをお願いしてみる
作ったアプリの機能概要
1. 患者ごとの情報を管理
– 「名前」「性別」「誕生日」「診断名」を入力、患者ごとに保存
2. 検査データも表形式で記録
– 日付 / 検査種別 / 項目 / 値 / 単位 / コメント
– 1人の患者に複数行記録可
3. 「次の患者へ」「前の患者へ」ボタンで切り替え
– No.1 → No.2 → No.3…
– 患者のデータは画面切り替えで保存
4. CSVの保存と読み込みに完全対応
– 起動時に既存CSVを読むか確認
– 「保存」ボタンで全患者データをエクスポート
実際の画像

まずcsvファイルの読み取りするかどうか確認します

これは前回保存したcsvファイルを読み込んだものです。
新規作成もできます。
次に行けばno2になり、その後戻れば内容が保存されたno1に行くことができます。
csvファイルはこんな感じ

思っていたのとはちょっと違ったのですが、もう少し改変したら、普通に使えそうな気がします
実装したコード
import tkinter as tk
from tkinter import filedialog, messagebox
import csv
import os
class MultiPatientApp:
def __init__(self, root):
self.root = root
self.root.title(“患者ごとのデータ管理アプリ”)
self.root.geometry(“1000×600”)
self.patients = {}
self.current_patient_no = 1
self.ask_to_load_csv()
self.build_patient_form()
self.build_data_table()
self.build_buttons()
self.load_patient_data()
def ask_to_load_csv(self):
if messagebox.askyesno(“読み込み確認”, “既存のCSVファイルを読み込みますか?”):
file_path = filedialog.askopenfilename(filetypes=[(“CSV files”, “*.csv”)])
if file_path:
self.load_csv(file_path)
def load_csv(self, file_path):
with open(file_path, newline=”) as f:
reader = csv.DictReader(f)
for row in reader:
pid = row[“Patient ID”]
if pid not in self.patients:
self.patients[pid] = {
“info”: {
“名前”: row[“名前”],
“性別”: row[“性別”],
“誕生日”: row[“誕生日”],
“診断名”: row[“診断名”]
},
“data”: []
}
self.patients[pid][“data”].append([
row[“日付”], row[“検査種別”], row[“項目”], row[“値”], row[“単位”], row[“コメント”]
])
def build_patient_form(self):
frame = tk.LabelFrame(self.root, text=”患者情報”)
frame.pack(fill=”x”, padx=10, pady=5)
self.patient_entries = {}
labels = [“名前”, “性別”, “誕生日”, “診断名”]
for i, label in enumerate(labels):
tk.Label(frame, text=label, width=10).grid(row=i, column=0, sticky=”w”, padx=5, pady=2)
entry = tk.Entry(frame, width=30)
entry.grid(row=i, column=1, sticky=”w”, pady=2)
self.patient_entries[label] = entry
self.patient_id_label = tk.Label(frame, text=””)
self.patient_id_label.grid(row=0, column=2, padx=20, sticky=”e”)
def build_data_table(self):
self.data_frame = tk.LabelFrame(self.root, text=”研究データ(検査)”)
self.data_frame.pack(fill=”x”, padx=10, pady=5)
headers = [“日付”, “検査種別”, “項目”, “値”, “単位”, “コメント”]
for i, header in enumerate(headers):
tk.Label(self.data_frame, text=header, width=12, bg=”#d0d0d0″).grid(row=0, column=i, padx=2)
self.data_rows = []
for _ in range(3):
self.add_data_row()
def add_data_row(self):
row_index = len(self.data_rows) + 1
row = []
for i in range(6):
entry = tk.Entry(self.data_frame, width=14, bg=”#f0f8ff”)
entry.grid(row=row_index, column=i, padx=2, pady=2)
row.append(entry)
self.data_rows.append(row)
def build_buttons(self):
btn_frame = tk.Frame(self.root)
btn_frame.pack(pady=10)
tk.Button(btn_frame, text=”← 前の患者へ”, command=self.prev_patient).grid(row=0, column=0, padx=10)
tk.Button(btn_frame, text=”→ 次の患者へ”, command=self.next_patient).grid(row=0, column=1, padx=10)
tk.Button(btn_frame, text=”CSVに保存”, command=self.export_to_csv).grid(row=0, column=2, padx=10)
def save_current_patient(self):
key = f”No.{self.current_patient_no}”
patient_info = {label: entry.get() for label, entry in self.patient_entries.items()}
data_entries = [[e.get() for e in row] for row in self.data_rows if any(e.get() for e in row)]
self.patients[key] = {“info”: patient_info, “data”: data_entries}
def load_patient_data(self):
self.patient_id_label.config(text=f”Patient ID: No.{self.current_patient_no}”)
key = f”No.{self.current_patient_no}”
for entry in self.patient_entries.values():
entry.delete(0, tk.END)
for row in self.data_rows:
for entry in row:
entry.delete(0, tk.END)
if key in self.patients:
for label, entry in self.patient_entries.items():
entry.insert(0, self.patients[key][“info”].get(label, “”))
for i, row_data in enumerate(self.patients[key][“data”]):
if i >= len(self.data_rows):
self.add_data_row()
for j, value in enumerate(row_data):
self.data_rows[i][j].insert(0, value)
def next_patient(self):
self.save_current_patient()
self.current_patient_no += 1
self.load_patient_data()
def prev_patient(self):
if self.current_patient_no > 1:
self.save_current_patient()
self.current_patient_no -= 1
self.load_patient_data()
def export_to_csv(self):
file_path = filedialog.asksaveasfilename(defaultextension=”.csv”, filetypes=[(“CSV files”, “*.csv”)])
if not file_path:
return
with open(file_path, “w”, newline=”) as f:
writer = csv.writer(f)
writer.writerow([“Patient ID”, “名前”, “性別”, “誕生日”, “診断名”,
“日付”, “検査種別”, “項目”, “値”, “単位”, “コメント”])
for pid, content in self.patients.items():
info = content[“info”]
for row in content[“data”]:
writer.writerow([pid, info[“名前”], info[“性別”], info[“誕生日”], info[“診断名”]] + row)
messagebox.showinfo(“保存完了”, “CSVファイルに保存しました。”)
if __name__ == “__main__”:
root = tk.Tk()
app = MultiPatientApp(root)
root.mainloop()
実装したコードの解説
Tkinterを使用したPythonのコードで、患者ごとのデータを保持しつつ、画面を切り替える機能を実装しています。
– クラス `MultiPatientApp`
– `self.patients` に患者ごとの情報を保存
– 「前へ」「次へ」ボタンで `self.current_patient_no` を動かして切り替え
– CSVの読み替え、保存も完備
まとめ
ファイルメーカーとは言えないが、情報を残す雛形のアプリはできた気がする
データの検索機能をつけて、ソートする機能もあればそこそこ使えるのではと思う
後編で追加したい機能は下記です
– 診療歴やメモ機能
– データの検索、並び替え
– PDF出力
自分でコードは全くいじっていない、何回か修正はしたが言語のみで修正する
Chat GPTのcode出力のスピードは初期より圧倒的に速い・・・
自分だけが使うデスクトップアプリで小回りの効いたものなら、もしかするとchatGPTを使えば作れるかも知れません
以上参考になれば幸いです
コメント