ExcelデータをPythonで自動化【ChatGPT実践3】

Excelファイルで管理されているデータの確認を、PythonとChatGPTを使って自動化してみました。今回は予めチェックする項目が決まっていたため、対象項目を指定して確認するスクリプトになっています。

背景と目的

受領したExcelベースのリストがちゃんとルールに則って記載されているか確認する場面があり、ミスの温床になりやすいので、ここを自動化することを思いつきました。

目視確認はデータ量が増えると限界がありますし、別の作業と並行してやらなくてはいけない場面も多いため、フォルダ内の複数Excelファイルを対象にこれらのチェックを自動で行ってくれるスクリプトをChatGPTに書いてもらいました。

今回は試験的に文字数と重複のチェックだけしてもらおうかなと思ってプロンプトを考えていきました。

使用ツールなど

  • ChatGPT o3-mini-high
  • PythonとPythonの以下モジュール
    • openpyxl:Excelファイルの編集
    • glob:ファイル操作
  • Excel

スクリプトの概要

以下が、ChatGPTに相談してできあがったPythonスクリプトの一部です。
全文は長くなるので省略しますが、流れとしては次のようになっています。

  1. INPUTフォルダ内のExcelファイルをすべて読み込み
  2. 各シートの1行目から「製品型番」「製品名」の列を特定
  3. 2行目以降をチェックし、型番の重複と文字数超過を判定
  4. 該当するものがあれば、ファイル名・シート名・行番号と一緒にログ出力

出力例はこんな感じです。

製品型番,sample1.xlsx,Sheet1,3,重複あり: ABC-123
製品名,sample2.xlsx,一覧,7,15文字オーバー

また、何も該当しなかった場合には、「該当なし」と表示されるようになっています。

プロンプトの入力と生成スクリプト

最初はやりたいことを箇条書きにして伝えます。書き方は全然洗練されていないですが、こんな書き方でも整理して考えてくれるので助かります。

以下の制約条件でスクリプトを書いてもらえますか?
・製品型番の列をチェックします。重複する型番がないかチェックします。
・製品名の列をチェックします。文字数が80文字を超えていないかどうかチェックします。
・対象はINPUTに指定されたフォルダ内の全てのエクセルファイルです。
・超えていた場合は「該当箇所(製品型番または製品名)」、「エクセルファイル名」、「シート名」、「行」、「該当内容(重複ありまたは何文字オーバーしているか)」をTXT形式で出力した上でコンソールにも出力します。記載方法はお任せします。
・チェック対象のエクセルファイルフォーマットは添付の画像を確認してください。

今回は以下のように「前提」という欄が出力されました。ここでは、プロンプト上では指示されていない部分について想定される要件を書き出しているようです。ChatGPTの想定する前提と自分の考えている要件があっていなかったら、ここで修正依頼をすると良いでしょう。

前提

  • Excel の1行目にヘッダ(「製品型番」「製品名」等)があると想定しています。
  • ヘッダの列順が分かっている場合は、それを直接指定しても構いません(例: B列が「製品型番」、C列が「製品名」など)。
  • サンプルスクリプトでは、各シートの1行目を走査してヘッダの位置を動的に特定し、データを読み込むようにしています。
  • Excelファイルは *.xlsx のみを想定しています。

生成されたスクリプトは以下です。

import os
import glob
import openpyxl

def check_excel_files(input_folder):
    """
    指定フォルダ内の全ての xlsx ファイルについて
    - 製品型番の重複チェック
    - 製品名の文字数(80文字超過)チェック
    を行い、結果を check_result.txt に出力するとともにコンソールにも表示する。
    """

    output_file = "check_result.txt"
    results = []  # エラー情報を格納するリスト

    # INPUTフォルダ配下の .xlsx ファイルを全て取得
    file_list = glob.glob(os.path.join(input_folder, "*.xlsx"))

    for excel_path in file_list:
        # ファイル名だけ取り出し
        excel_name = os.path.basename(excel_path)
        # ブックを読み込み (read_only=False で編集可能)
        wb = openpyxl.load_workbook(excel_path, data_only=True)

        for sheet_name in wb.sheetnames:
            sheet = wb[sheet_name]

            # ヘッダ行(1行目)から「製品型番」「製品名」の列インデックスを探す
            product_number_col = None
            product_name_col = None

            # 1行目のセルを順にチェックして列を特定
            for col_idx, cell in enumerate(sheet[1], start=1):
                if cell.value == "製品型番":
                    product_number_col = col_idx
                elif cell.value == "製品名":
                    product_name_col = col_idx

            # 「製品型番」「製品名」列が見つからなければスキップ
            if product_number_col is None or product_name_col is None:
                continue

            # 製品型番の重複チェック用にセットを利用
            product_number_set = set()
            # 製品型番の重複行を記憶(何度もエラーが出ないように)
            duplicate_rows = []

            # 2行目以降にデータが入っている前提で読み込む
            for row_idx in range(2, sheet.max_row + 1):
                pn_cell = sheet.cell(row=row_idx, column=product_number_col)
                pm_cell = sheet.cell(row=row_idx, column=product_name_col)

                product_number_value = str(pn_cell.value).strip() if pn_cell.value else ""
                product_name_value   = str(pm_cell.value).strip() if pm_cell.value else ""

                # --- 製品型番の重複チェック ---
                if product_number_value:
                    if product_number_value in product_number_set:
                        # 重複あり
                        # (同じ行に複数回出力しないために、duplicate_rowsで制御する場合は必要に応じて)
                        if row_idx not in duplicate_rows:
                            duplicate_rows.append(row_idx)
                            error_info = (
                                "製品型番",                # 該当箇所
                                excel_name,               # ファイル名
                                sheet_name,               # シート名
                                row_idx,                  # 行
                                "重複あり: {}".format(product_number_value)  # 該当内容
                            )
                            results.append(error_info)
                    else:
                        product_number_set.add(product_number_value)

                # --- 製品名の文字数チェック ---
                if product_name_value:
                    name_len = len(product_name_value)
                    if name_len > 80:
                        over_len = name_len - 80
                        error_info = (
                            "製品名",                   # 該当箇所
                            excel_name,                 # ファイル名
                            sheet_name,                 # シート名
                            row_idx,                    # 行
                            "{}文字オーバー".format(over_len)  # 該当内容
                        )
                        results.append(error_info)

    # 結果を txt に書き込み & コンソール出力
    with open(output_file, mode="w", encoding="utf-8") as f:
        for error_info in results:
            # error_info はタプル("製品型番または製品名", ファイル名, シート名, 行, 詳細)
            line = ",".join([str(item) for item in error_info])
            print(line)       # コンソールに出力
            f.write(line + "\n")  # ファイルにも出力

if __name__ == "__main__":
    # 例: INPUT フォルダを指定してください
    input_folder_path = r"INPUT"  # 実際のパスに置き換えてください
    check_excel_files(input_folder_path)

スクリプトの使用方法

ChatGPTから使い方も教えてもらいました。

  1. 上記のコードを check_excel.py のようなファイル名で保存します。
  2. input_folder_path にチェック対象のエクセルファイルが格納されているフォルダパスを指定します。
  3. ターミナルやコマンドプロンプトで本スクリプトを実行します。
  4. 問題がある場合は check_result.txt に出力され、同時にコンソールにも表示されます。

「製品型番」と「製品名」の列がどこにあるかわかっていればproduct_number_colとproduct_name_colで指定してしまっても良いです。

まとめ

今回も自分が思い描いたとおりのスクリプトを作ってくれました。
複数ファイルを一括でチェックしたいときや、人の目では見落としがちなルールがある場合にはChatGPTに自動化できないか聞いてみると良いと思います。

タイトルとURLをコピーしました