データベースやCSVファイルを扱う際、大量のカラム名を管理するのは非常に手間がかかります。カラム数が多いと、どのカラムがどのデータを指しているのか分からなくなりがちです。この記事では、PythonとTkinterを使って、カラム名を効率的に管理・検索できるツールを作ってみたので紹介します。
1. 基本のサンプルコード
まずは、カラム名を検索できる基本的なツールを作成してみましょう。以下のコードでは、カラム名、GUI表示名、CSV名を表示し、それぞれを検索できる機能を備えたTkinterアプリケーションを作成します。
コード例:カラム名検索ツール
import tkinter as tk
from tkinter import ttk
class ColumnSearcherApp(tk.Tk):
    def __init__(self, columns):
        super().__init__()
        self.title("カラム名検索ツール")
        self.geometry("600x400")
        self.columns = columns
        # 検索フレーム
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)
        # 検索ラベルとエントリ
        tk.Label(self.search_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_var.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.grid(row=0, column=1, padx=5)
        tk.Label(self.search_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.search_var_gui = tk.StringVar()
        self.search_var_gui.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_gui = tk.Entry(self.search_frame, textvariable=self.search_var_gui)
        self.search_entry_gui.grid(row=1, column=1, padx=5)
        tk.Label(self.search_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.search_var_csv = tk.StringVar()
        self.search_var_csv.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_csv = tk.Entry(self.search_frame, textvariable=self.search_var_csv)
        self.search_entry_csv.grid(row=2, column=1, padx=5)
        # 一覧表示用ツリービュー
        self.tree = ttk.Treeview(self, columns=("column_name", "gui_name", "csv_name"), show='headings')
        self.tree.heading("column_name", text="カラム名")
        self.tree.heading("gui_name", text="項目名")
        self.tree.heading("csv_name", text="CSV名")
        self.tree.pack(fill=tk.BOTH, expand=True)
        self.populate_tree()
    def populate_tree(self):
        for col in self.columns:
            self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))
    def search_columns(self):
        query_col = self.search_var.get().lower()
        query_gui = self.search_var_gui.get().lower()
        query_csv = self.search_var_csv.get().lower()
        # 一覧をクリア
        for i in self.tree.get_children():
            self.tree.delete(i)
        # フィルタされた結果を表示
        for col in self.columns:
            if query_col in col["column_name"].lower() and query_gui in col["gui_name"].lower() and query_csv in col["csv_name"].lower():
                self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))
if __name__ == "__main__":
    # サンプルデータの作成
    columns = [
        {"column_name": "user_id", "gui_name": "ユーザーID", "csv_name": "user_id"},
        {"column_name": "order_date", "gui_name": "注文日", "csv_name": "order_date"},
        {"column_name": "total_price", "gui_name": "合計金額", "csv_name": "total_price"},
        # 他のカラムをここに追加
    ]
    
    app = ColumnSearcherApp(columns)
    app.mainloop()
解説
このコードでは、サンプルデータを使ってカラム名、GUI表示名、CSVでの項目名を一覧表示し、ユーザーが各項目で検索できるツールを提供します。これにより、基本的なカラム管理ツールが動作することが確認できます。
2. では実際に使うとしたら…
このサンプルコードを試した後、実際に使う場合には、以下のようにExcelやSQLite3データベースを利用してカラム情報を管理し、ツールで使用することができます。
Excelで管理するなら
Excelファイルにカラム情報を保存し、Pandasを使って読み込む方法です。この方法を使うと、Excelファイルの内容を変更するだけで、ツールの表示内容も簡単に更新できます。
Excelファイルの準備
まず、カラム情報を管理するためのExcelファイルを作成します。以下のリンクから、サンプルのExcelファイルをダウンロードできます。
Excelファイルからデータを読み込んでツールを起動
次に、Excelファイルからデータを読み込んで表示するためのコードを以下に示します。
import pandas as pd
import tkinter as tk
from tkinter import ttk
class ColumnSearcherApp(tk.Tk):
    def __init__(self, columns):
        super().__init__()
        self.title("カラム名検索ツール")
        self.geometry("600x400")
        self.columns = columns
        # 検索フレーム
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)
        # 検索ラベルとエントリ
        tk.Label(self.search_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_var.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.grid(row=0, column=1, padx=5)
        tk.Label(self.search_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.search_var_gui = tk.StringVar()
        self.search_var_gui.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_gui = tk.Entry(self.search_frame, textvariable=self.search_var_gui)
        self.search_entry_gui.grid(row=1, column=1, padx=5)
        tk.Label(self.search_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.search_var_csv = tk.StringVar()
        self.search_var_csv.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_csv = tk.Entry(self.search_frame, textvariable=self.search_var_csv)
        self.search_entry_csv.grid(row=2, column=1, padx=5)
        # 一覧表示用ツリービュー
        self.tree = ttk.Treeview(self, columns=("column_name", "gui_name", "csv_name"), show='headings')
        self.tree.heading("column_name", text="カラム名")
        self.tree.heading("gui_name", text="項目名")
        self.tree.heading("csv_name", text="CSV名")
        self.tree.pack(fill=tk.BOTH, expand=True)
        self.populate_tree()
    def populate_tree(self):
        for col in self.columns:
            self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))
    def search_columns(self):
        query_col = self.search_var.get().lower()
        query_gui = self.search_var_gui.get().lower()
        query_csv = self.search_var_csv.get().lower()
        # 一覧をクリア
        for i in self.tree.get_children():
            self.tree.delete(i)
        # フィルタされた結果を表示
        for col in self.columns:
            if query_col in col["column_name"].lower() and query_gui in col["gui_name"].lower() and query_csv in col["csv_name"].lower():
                self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))
if __name__ == "__main__":
    # Excelファイルからデータを読み込む
    df = pd.read_excel('columns.xlsx')
    columns = df.to_dict(orient='records')
    app = ColumnSearcherApp(columns)
    app.mainloop()
データベースで管理するなら
次に、SQLite3データベースにカラム情報を保存し、それを読み込んで表示する方法です。この方法では、データベースを使用することで、より多くのデータを扱うことができます。
Excelファイルからデータベースに保存
まず、Excelファイルからカラム情報を読み込み、それをSQLite3データベースに保存するコードを示します。
import pandas as pd
import sqlite3
# Excelファイルからデータを読み込む
df = pd.read_excel('columns.xlsx')
# SQLite3データベースに接続
conn = sqlite3.connect('columns.db')
cursor = conn.cursor()
# テーブルを作成
cursor.execute('''
CREATE TABLE IF NOT EXISTS column_table (
    id INTEGER PRIMARY KEY,
    column_name TEXT,
    gui_name TEXT,
    csv_name TEXT
)
''')
# データを挿入
for _, row in df.iterrows():
    cursor.execute('''
    INSERT INTO column_table (column_name, gui_name, csv_name)
    VALUES (?, ?, ?)
    ''', (row['column_name'], row['gui_name'], row['csv_name']))
# コミットしてデータベースを閉じる
conn.commit()
conn.close()
データベースから読み込んで表示
次に、データベースに保存されたカラム情報を読み込み、表示するためのコードです。
import sqlite3
import tkinter as tk
from tkinter import ttk, messagebox
class ColumnSearcherApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("カラム名管理ツール")
        self.geometry("700x500")
        # データベースに接続
        self.conn = sqlite3.connect('columns.db')
        self.cursor = self.conn.cursor()
        # UIセットアップ
        self.create_widgets()
        self.populate_tree()
    def create_widgets(self):
        # 検索フレーム
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)
        tk.Label(self.search_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_var.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.grid(row=0, column=1, padx=5)
        tk.Label(self.search_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.search_var_gui = tk.StringVar()
        self.search_var_gui.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_gui = tk.Entry(self.search_frame, textvariable=self.search_var_gui)
        self.search_entry_gui.grid(row=1, column=1, padx=5)
        tk.Label(self.search_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.search_var_csv = tk.StringVar()
        self.search_var_csv.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_csv = tk.Entry(self.search_frame, textvariable=self.search_var_csv)
        self.search_entry_csv.grid(row=2, column=1, padx=5)
        # 一覧表示用ツリービュー
        self.tree = ttk.Treeview(self, columns=("column_name", "gui_name", "csv_name"), show='headings')
        self.tree.heading("column_name", text="カラム名")
        self.tree.heading("gui_name", text="項目名")
        self.tree.heading("csv_name", text="CSV名")
        self.tree.pack(fill=tk.BOTH, expand=True)
        self.populate_tree()
        # 手動入力フレーム
        self.entry_frame = tk.Frame(self)
        self.entry_frame.pack(pady=10)
        tk.Label(self.entry_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.entry_col = tk.Entry(self.entry_frame)
        self.entry_col.grid(row=0, column=1, padx=5)
        tk.Label(self.entry_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.entry_gui = tk.Entry(self.entry_frame)
        self.entry_gui.grid(row=1, column=1, padx=5)
        tk.Label(self.entry_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.entry_csv = tk.Entry(self.entry_frame)
        self.entry_csv.grid(row=2, column=1, padx=5)
        self.add_button = tk.Button(self.entry_frame, text="追加", command=self.add_column)
        self.add_button.grid(row=3, columnspan=2, pady=10)
    def populate_tree(self):
        # 現在のツリービューをクリア
        for i in self.tree.get_children():
            self.tree.delete(i)
        # データベースからデータを取得して表示
        self.cursor.execute("SELECT column_name, gui_name, csv_name FROM column_table")
        for row in self.cursor.fetchall():
            self.tree.insert("", tk.END, values=row)
    def search_columns(self):
        query_col = self.search_var.get().lower()
        query_gui = self.search_var_gui.get().lower()
        query_csv = self.search_var_csv.get().lower()
        # 一覧をクリア
        for i in self.tree.get_children():
            self.tree.delete(i)
        # フィルタされた結果を表示
        self.cursor.execute("SELECT column_name, gui_name, csv_name FROM column_table")
        for row in self.cursor.fetchall():
            if query_col in row[0].lower() and query_gui in row[1].lower() and query_csv in row[2].lower():
                self.tree.insert("", tk.END, values=row)
    def add_column(self):
        col_name = self.entry_col.get()
        gui_name = self.entry_gui.get()
        csv_name = self.entry_csv.get()
        if col_name and gui_name and csv_name:
            self.cursor.execute('''
            INSERT INTO column_table (column_name, gui_name, csv_name)
            VALUES (?, ?, ?)
            ''', (col_name, gui_name, csv_name))
            self.conn.commit()
            messagebox.showinfo("追加完了", "カラム情報を追加しました。")
            self.populate_tree()
        else:
            messagebox.showwarning("入力エラー", "すべてのフィールドに入力してください。")
    def __del__(self):
        self.conn.close()
if __name__ == "__main__":
    app = ColumnSearcherApp()
    app.mainloop()
まとめ
これで、Excelファイルからの読み込み、データベースへの保存、手動での追加を備えた完全なツールが完成しました。このツールを使用することで、大量のカラム名を効率的に管理できるだけでなく、実際の業務に即した柔軟な対応が可能になります。
一度このツールを使ってデータ管理を効率化してみてください!

  
  
  
  

コメント