パイソンメイカー -業務用プログラム作成-

今回はパイソンメイカーの講座をうけて、すぐに使えるプログラムを作れたのでシェアをしたいと思います。

denki
denki

こういうのを作るのが夢だったんだよ~✨

パイソンメイカーのkumazawaさんがChatGPTを使ったプログラムコードを作っていたので、そのやり方をまねして今業務に緊急に必要なプログラムを作ってみました。

denki
denki

ノーコード(コード書かないで)アプリが作れるkintoneではちょくちょくアプリは作っていたけど、今回のは社内の共有ファイルも関わるのでkintoneでは作ることができないものでした

コードも読んだことがないので、パイソンメイカーの講座うけるまでは何か数字の羅列って感じで全く頭に入っていなかったのですが、半分まで受けるとChatGPTの助けを借りながらこのコードが何を意味しているのかなどがわかるようになってきます。

ということで、今会社で困っていること やりたいこと↓

denki
denki

ということで、ChatGPTに聞いてみました✨

漢字打ち間違えている💦 県s無→検索
denki
denki

うぉ~~いきなりコード書きだした!

ちゃんと何のライブラリを使うのかなど教えてくれています
denki
denki

pythonの入門講座も同時に受講しているので、withとかifとか ライブラリの取り扱いなどがわかるので、理解できました✨感動! 早速jupyter labを開いてコードをコピペ

excelの内容が書き換えられたらやばいので、検索するファイルは読み取り専用にしてもらいました
denki
denki

エラーがでたらその都度、エラー文をそのまんま ChatGPTに貼り付けると、修正したコードをその都度書き出してくれます。

そうこうして、数時間ほどで、私のやりたい作業をしてくれるプログラムを完成させてくれたのです!✨ ボタンの配置などGUIも付け足してくれました。これも、ボタン配置してというだけで作ってくれる!

denki
denki

すごく簡単なのだけど、最初の試作品はサクッとできたのです。

さて、これからが大変でした💦 これをpython環境がないほかの社員が使用できるようにするためにexe化というものをします。

ここはChatGPTとパイソンメイカーの講師さんに聞きながら、おすすめのツールなどを教えてもらいました😉

講師さんがサポートしてくれました

ここの環境構築は時間がかかりましたが、1つ1つエラーをChatGPTさんに聞いて解決していきました。

そしてそして最初のプログラム完成~✨

はじめて自分?(ほとんどChatGPT)で
作ったプログラム
denki
denki

最初1人の人に使わせて、いろいろと意見を聞いてもらい、ChatGPTに改良してもらったものをもう1度作ってもらいました。結構欲がでて、ステータスバーつけさせたり、クリックしたらファイルが開くようにしてもらいました✨

完成版!!検索したい場所を指定して 探したいキーワードを入力すると、指定された場所からexcelファイルのありかを下の欄に羅列しれくれます。そして、文字列をクリックすると自動でEXCELファイルも開いてくれます。

(共有ファイルでもok!)

denki
denki

これで、見積部隊の作業効率が格段に上がるのです!!感動(´;ω;`)

ChatGPTが無ければ完成しなかったプログラムです。

今回作ったコード貼り付けておきます。使うなら自己責任で試してみて下さい(笑)

import os
import openpyxl
import PySimpleGUI as sg
import warnings
from openpyxl.utils.exceptions import InvalidFileException
import subprocess

def search_excel_files(directory_list, keyword, progress_bar):
    matched_files = []

    total_files = 0
    for directory in directory_list:
        for root, dirs, files in os.walk(directory):
            for file in files:
                if file.endswith('.xlsx') or file.endswith('.xls'):
                    total_files += 1

    progress_bar.UpdateBar(0, total_files)

    file_count = 0
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        for directory in directory_list:
            for root, dirs, files in os.walk(directory):
                for file in files:
                    if file.endswith('.xlsx') or file.endswith('.xls'):
                        file_path = os.path.join(root, file)
                        try:
                            workbook = openpyxl.load_workbook(file_path, read_only=True, data_only=True)
                        except InvalidFileException:
                            # Skip files that are not valid Excel files
                            continue
                        except:
                            # Skip files with password protection or other exceptions
                            continue

                        keyword_count = 0
                        for sheet_name in workbook.sheetnames:
                            sheet = workbook[sheet_name]
                            if isinstance(sheet, openpyxl.chartsheet.Chartsheet):
                                continue  # Skip Chartsheet
                            for row_num, row in enumerate(sheet.iter_rows(values_only=True), start=1):
                                for col_num, cell_value in enumerate(row, start=1):
                                    if keyword in str(cell_value):
                                        keyword_count += 1
                                        matched_files.append((file_path, sheet_name, (row_num, col_num), keyword_count))
                                        break

                        file_count += 1
                        progress_bar.UpdateBar(file_count)

    progress_bar.UpdateBar(total_files, total_files)

    # キーワードの個数が多い順にソート
    matched_files = sorted(matched_files, key=lambda x: x[1], reverse=True)

    return matched_files

# GUIのレイアウト
layout = [
    [sg.Text('検索するキーワードを入力してください:')],
    [sg.Input(key='-KEYWORD-')],
    [sg.Text('検索するフォルダーパスを選択してください:')],
    [sg.Input(key='-FOLDER-', enable_events=True), sg.FolderBrowse()],
    [sg.Listbox(values=[], size=(60, 6), key='-SELECTED_FOLDERS-', enable_events=True)],
    [sg.Button('削除')],
    [sg.Button('検索'), sg.Button('クリア'), sg.Button('キャンセル')],
    [sg.ProgressBar(100, orientation='h', size=(50, 20), key='-PROGRESS-')],
    [sg.Output(size=(120, 20), key='-OUTPUT-')],
    [sg.Table(values=[], headings=["File Path", "Keyword Count", "Cell Positions"], display_row_numbers=False,
              auto_size_columns=True, col_widths=[60, 20, 100], num_rows=10, key='-TABLE-', enable_events=True)]
]

window = sg.Window('Excelファイル検索ツール', layout)

selected_folders = []

while True:
    event, values = window.read()

    if event ==

 sg.WINDOW_CLOSED or event == 'キャンセル':
        break
    elif event == '-FOLDER-':
        folder_path = values['-FOLDER-']
        if folder_path not in selected_folders:
            selected_folders.append(folder_path)
        window['-SELECTED_FOLDERS-'].update(selected_folders)
    elif event == '削除':
        selected = values['-SELECTED_FOLDERS-']
        if selected:
            selected_folder = selected[0]
            selected_folders.remove(selected_folder)
            window['-SELECTED_FOLDERS-'].update(selected_folders)
    elif event == 'クリア':
        window['-KEYWORD-'].update('')
        window['-FOLDER-'].update('')
        window['-SELECTED_FOLDERS-'].update([])
        window['-PROGRESS-'].update(0, 0)
        window['-PROGRESS-'].update_bar(0)
        window['-OUTPUT-'].update('')  # 出力エリアをクリア
        print('--- 検索結果クリア ---')
    elif event == '検索':
        keyword = values['-KEYWORD-']
        directory_list = selected_folders

        if keyword and directory_list:
            progress_bar = window['-PROGRESS-']
            matched_files = search_excel_files(directory_list, keyword, progress_bar)

            print(f"キーワード「{keyword}」に一致するファイル数: {len(matched_files)}")
            print("詳細:")
            for file_path, sheet_name, cell_position, keyword_count in matched_files:
                row_num, col_num = cell_position
                print(f"ファイルパス: {file_path}")
                print(f"シート名: {sheet_name}")
                print(f"セルの位置: 行 {row_num}, 列 {col_num} ({keyword_count}個のキーワード)")
                print()

            # キーワードごとにファイルパスとセルの位置をまとめる
            grouped_files = {}
            for file_path, sheet_name, cell_position, keyword_count in matched_files:
                if file_path not in grouped_files:
                    grouped_files[file_path] = {
                        'Sheet': sheet_name,
                        'Cell Positions': []
                    }
                grouped_files[file_path]['Cell Positions'].append(cell_position)

            # テーブルを更新
            table_values = []
            for file_path, file_data in grouped_files.items():
                sheet_name = file_data['Sheet']
                cell_positions = ', '.join([f'行 {row}, 列 {col}' for row, col in file_data['Cell Positions']])
                table_values.append([file_path, keyword_count, cell_positions])

            window['-TABLE-'].update(values=table_values)
    elif event == '-TABLE-':
        try:
            # 選択された行のインデックスを取得
            selected_row_index = values['-TABLE-'][0]
            # 選択されたファイルパスを取得
            selected_file_path = matched_files[selected_row_index][0]
            # ファイルをエクスプローラーで開く
            subprocess.Popen(['explorer', '/select,', os.path.normpath(selected_file_path)])
        except IndexError:
            pass  # 選択された行がない場合は何もしない
        except Exception as e:
            print(f"ファイルを開く

ことができませんでした: {e}")

window.close()

コメントを残す