前回記事で紹介の環境設定編 【非エンジニア向け】Python活用の業務効率化への第一歩!VSCode & Copilot環境構築マニュアル 【Windows編】 #copilot - Qiita を紹介しました。
今回は、その構築した環境の動作確認を兼ねて、実際にAIにプログラムを生成させて動かしてみるという実践です。
このテーマで学べる事
-
プロンプトのひな形が学べる: どのようなプロンプト(AIに対する指示)を出せばプログラムを作成できるのか、基本的な型が理解できます。これを雛形に様々な応用が可能です。
-
プログラミングの強力な概念を学べる: 「辞書(dictionary)」を使って対応表(マッピング)を作るという考え方は、あらゆるプログラミングで応用が効く非常に重要な概念です。これを実用的な形で学べます。
-
作る過程そのものが面白く、プログラムが動いた感動を味わえる: 実際に瞬時に処理が完了した時、ちょっとした感動が味わえます。是非、オリジナルの課題を自動化し、小さな成功体験を味わってほしいと思います。
想定の困りごと:こんなことありませんか?
部署や担当者、取引先によって微妙にフォーマットが違う報告書ファイル。
「『売上』『金額』『Sales』など、微妙に列名が違うせいで、結局一つひとつ手作業でコピペして集計している…」という、非常に根深く、多くの人が諦めているであろう課題に応える、という練習をしてみたいと思います。
例えば、以下のようなファイルがあったとします。
ヘッダーの名前が違う、列の並びが違う、こういうこと良くありますよね。
東京支店_売上.xlsx
| 日付 | 顧客名 | 担当 | 商品 | 数量 | 売上 |
|---|---|---|---|---|---|
| 2025-10-05 | 株式会社A | 佐藤 | PC-A | 5 | 500000 |
| 2025-10-08 | 株式会社B | 鈴木 | Monitor-C | 10 | 250000 |
sales_osaka_fy25.xlsx
| Date | Customer | Staff | Item | Qty | Price |
|---|---|---|---|---|---|
| 2025-10-03 | 合同会社C | 高橋 | Keyboard-D | 30 | 90000 |
| 2025-10-11 | 株式会社A | 田中 | PC-B | 3 | 390000 |
月次報告.xlsx
| 購入日 | クライアント | 合計 | アイテム | 購入数 |
|---|---|---|---|---|
| 2025-10-02 | 有限会社D | 120000 | Mouse-E | 20 |
| 2025-10-10 | 株式会社B | 450000 | PC-A | 3 |
この様なケースで自動化は諦めたりしてませんか?
この様なケースは、エイリアス(別名)辞書を作ることで対処可能なんです!
では実際に、この対処策のPythonコードを「AIを使って作成する」
――これを実践例としたいと思います。
Step1 事前準備
これからご説明するデータ統合プログラムをテストするために最適な、ヘッダーの表記ゆれやフォルダ構造が異なるサンプルExcelファイル3つを動的に生成し、それらを一つのZIPファイルにまとめて出力するPythonスクリプトをご用意しました。
以下のスクリプトを実行するだけで、すぐに使えるテストデータが手に入ります。
テストデータ生成用 Pythonスクリプト(動作確認済み)
import os
import datetime
import zipfile
from openpyxl import Workbook
# --- 設定 ---
# TrueにするとZIPファイルを作成し、Falseにするとフォルダを直接作成します
CREATE_ZIP_FILE = True
# --- ここからがスクリプト本体です ---
def create_excel_file(file_path, headers, data_rows):
"""指定されたパスに、ヘッダーとデータを持つExcelファイルを作成する関数"""
# フォルダが存在しない場合は作成
dir_name = os.path.dirname(file_path)
if dir_name:
os.makedirs(dir_name, exist_ok=True)
workbook = Workbook()
sheet = workbook.active
# ヘッダーを書き込み
sheet.append(headers)
# データを書き込み
for row in data_rows:
sheet.append(row)
workbook.save(file_path)
print(f" -> '{file_path}' を作成しました。")
def main():
"""メイン処理:サンプルExcelを作成し、ZIPファイルに圧縮する"""
print("--- テスト用のサンプルExcelファイル作成を開始します ---")
# --- 各ファイルの定義 ---
# ファイル1: 標準的な日本語ヘッダー
file1_name = "Monthly_Reports/東京支店_売上.xlsx"
file1_headers = ['日付', '顧客名', '担当', '商品', '数量', '売上']
file1_data = [
[datetime.date(2025, 10, 5), '株式会社A', '佐藤', 'PC-A', 5, 500000],
[datetime.date(2025, 10, 8), '株式会社B', '鈴木', 'Monitor-C', 10, 250000],
]
# ファイル2: 英語と日本語が混在したヘッダー
file2_name = "Monthly_Reports/sales_osaka_fy25.xlsx"
file2_headers = ['Date', 'Customer', 'Staff', 'Item', 'Qty', 'Price']
file2_data = [
[datetime.date(2025, 10, 3), '合同会社C', '高橋', 'Keyboard-D', 30, 90000],
[datetime.date(2025, 10, 11), '株式会社A', '田中', 'PC-B', 3, 390000],
]
# ファイル3: サブフォルダ内にあり、列の順序が異なり、一部の列が欠けている
file3_name = "Monthly_Reports/福岡営業所/月次報告.xlsx"
file3_headers = ['購入日', 'クライアント', '合計', 'アイテム', '購入数']
file3_data = [
[datetime.date(2025, 10, 2), '有限会社D', 120000, 'Mouse-E', 20],
[datetime.date(2025, 10, 10), '株式会社B', 450000, 'PC-A', 3],
]
files_to_create = [
(file1_name, file1_headers, file1_data),
(file2_name, file2_headers, file2_data),
(file3_name, file3_headers, file3_data),
]
# Excelファイルを実際に作成
for name, headers, data in files_to_create:
create_excel_file(name, headers, data)
# CREATE_ZIP_FILEがFalseなら、ここで処理を終了
if not CREATE_ZIP_FILE:
print("\n--- 処理完了 ---")
print("テスト用のExcelファイルとフォルダが作成されました。")
return
print("\n--- ZIPファイルへの圧縮を開始します ---")
zip_file_name = "sample_excel_files.zip"
with zipfile.ZipFile(zip_file_name, 'w') as zf:
for name, _, _ in files_to_create:
zf.write(name)
print(f" -> '{name}' をZIPファイルに追加しました。")
print("\n--- 後片付け(一時ファイルの削除)を開始します ---")
# 作成した一時ファイルとフォルダを削除
for name, _, _ in files_to_create:
os.remove(name)
print(f" -> '{name}' を削除しました。")
# サブフォルダも削除
try:
os.rmdir("Monthly_Reports/福岡営業所")
print(" -> 'Monthly_Reports/福岡営業所' フォルダを削除しました。")
os.rmdir("Monthly_Reports")
print(" -> 'Monthly_Reports' フォルダを削除しました。")
except OSError as e:
print(f"フォルダの削除中にエラーが発生しました: {e}")
print("\n--- 処理完了 ---")
print(f"テスト用のデータが入った '{zip_file_name}' が正常に作成されました。")
print("このZIPファイルを解凍し、「Monthly_Reports」フォルダをデータ統合プログラムのテストに使用してください。")
if __name__ == "__main__":
main()
使い方
-
作業フォルダ
C:\MyPythonProjects\excel-automationなどに、.pyファイルを新規作成 -
Pythonコードを記載し上書き保存
- 自身で生成、もしくは上記のPythonコード全体をコピー&ペースト
-
ctrl + sで上書き保存。- ファイル名のタブの右上角のアイコンが●から×に変わっていたらOK
-
Pythonコードを実行
-
ターミナルに実行状況が出力される
-
スクリプトと同じ階層に
sample_excel_files.zipというZIPファイルが作成されることを確認 -
この zipファイルは、同じフォルダ内の解凍しておきましょう。
※このスクリプトは、sample_excel_files.zipを作成した後に、元になったExcelファイルやフォルダを自動で削除して後片付けをしまが、先頭のCREATE_ZIP_FILE = TrueをFalseに切り替えることでzip化をせずに終了させることも可能です。
※ 環境設定の部分は、前回記事を前提に割愛しています。必要な場合は、前回記事を参照してください。
作成されるファイルの内容について
このスクリプトを実行すると、sample_excel_files.zip というファイルが生成されます。ZIPファイルを解凍すると、Monthly_Reportsというフォルダが現れ、その中には以下の3つのファイルが格納されています。
-
Monthly_Reports/東京支店_売上.xlsx- ヘッダーは標準的な日本語です。(例:
日付,顧客名,売上)
- ヘッダーは標準的な日本語です。(例:
-
Monthly_Reports/sales_osaka_fy25.xlsx- ヘッダーは英語と日本語が混在しています。(例:
Date,Customer,Price)
- ヘッダーは英語と日本語が混在しています。(例:
-
Monthly_Reports/福岡営業所/月次報告.xlsx- サブフォルダ内に格納されています。
- ヘッダーの列の順序が異なり、呼び方も違います。(例:
購入日,クライアント,合計) - 「担当者」の列が欠けているため、データがない場合のテストもできます。
これらのファイルは、データ統合プログラムを試すのに最適なテストケースとなります。
Step2:AIへの指示プロンプト(サンプル)
(ここから下をコピーして、ChatGPTやCopilotなどのAIに貼り付けて実行)
以下の要件に従って、Pythonコードを作成してください。
#### 基本要件
- 本日は2025年●●月●●日です。
- より短く、クリーンで、シンプルなコードを生成してください。
- 処理の進捗がわかるように、標準出力(print文)で処理の状況をこまめに出力してください。
- プログラミング初心者でも、コードの各処理の意図がわかるように、日本語でコメントを多く残してください。
- APIキー、IDやパスワード等はハードコード禁止。`.env` 優先し、必ず環境変数から取得してください。
#### 使用するライブラリ
| ライブラリ | 機能 | 備考 |
| ---------- | ------------------- | ----------------------------------------------------------------------------------- |
| `openpyxl` | Excelファイルの読み込みと書き出し | `pandas`はMS C++ Build Toolsが必要で、install未なので使わない。`os`や`datetime`など、必要に応じて標準ライブラリも使用。 |
> 【補足:ライブラリ選定の理由とpandasについて】
>通常、このような表形式のデータを扱う処理はpandasというライブラリが非常に強力で効率的です。何も指定しないとpandasを利用したコードが作成される確率は高く、その際「MS C++ Build Tools」のインストールが必要になる場合があります。より複雑なデータ集計や分析を行う場合はpandasが有効ですが、ここではopenpyxlを指定しました。
#### 処理対象のファイル
- 以下のフォルダパスに格納されている、すべてのExcelファイル(`.xlsx`)を処理対象とします。
- **サブフォルダ内にあるExcelファイルもすべて含めてください。**
| 通称名 | フォルダパス |
| --------- | --------------------------------------------- |
| 売上報告書フォルダ | `C:\Users\YourUser\Documents\Monthly_Reports` |
- 各ファイルには売上データが記載されていますが、作成者によってヘッダー(列名)がバラバラです。
- ヘッダーは各シートの1行目にあります。データは2行目以降です。
#### 処理のフロー
**1. 統一ヘッダーとエイリアス(別名)の定義:エイリアス辞書の作成**
- 最終的に作成したいExcelファイルの統一ヘッダーを、`['取引日', '顧客名', '担当者名', '商品名', '数量', '金額']` として定義します。
- 以下の**エイリアス対応表**をPythonの「辞書」に変換し、表記ゆれに対応できるようにしてください。
|統一ヘッダー名|このヘッダーに対応する別名(表記ゆれ)|
|---|---|
|取引日|Date, 日付, 購入日|
|顧客名|Customer, クライアント, 会社名|
|担当者名|担当, 営業, Staff|
|商品名|商品, アイテム, Item|
|数量|数, Qty|
|金額|売上, Price, 合計|
**2. 全データの集約**
- 「集約用のリスト」を新規作成します。
- 「売上報告書フォルダ」内のExcelファイル(サブフォルダ含む)を全てリストアップします。
- 特定したExcelファイルに対し、一つずつ順番に以下の処理をします。
1. openpyxlでExcelブックを読み込み、最初のアクティブなシートを選択します。
2. シートの1行目(ヘッダー行)を読み取り、そのファイルで「統一ヘッダーの何番目の列が、実際のファイルの何番目の列に対応するか」の対応関係を特定します。
3. シートの2行目以降のデータ行を一行ずつ読み込みます。
4. 読み込んだ行の各セルの値を、統一ヘッダーの正しい順序に並べ替えたリストとして新しい行データを作成します。統一ヘッダーに対応する列がファイルに存在しない場合は、空の値を入れてください。
5. 作成した新しい行データを、最初に準備した「集約用のリスト」に追加します。
**3. データの並べ替え(ソート)**
- すべてのファイルの読み込みが完了したら、集約したデータを以下の優先順位で並べ替えてください。
- **第1優先キー:** 「取引日」の昇順
- **第2優先キー:** 「金額」の降順
**4. 新しいExcelブックへの出力**
- `openpyxl`で新しいExcelブックを作成します。
- 1行目に、統一ヘッダーを書き込みます。
- 2行目以降に、ソート済みのデータを一行ずつ書き込みます。
**5. 最終的な書式設定**
- 書き込みが完了したシートに対して、以下の書式設定を行ってください。
- 1行目のヘッダー行に**オートフィルタ**を設定します。
- スクロールしてもヘッダーが見えるように、**1行目を固定表示(ウィンドウ枠の固定)**します。
**6. ファイルの保存**
- 以下の仕様で、作成したExcelブックを保存してください。
- **ファイルパス:** PCの「ダウンロード」フォルダ
- **ファイル名:** `統合レポート_` + `実行時のタイムスタップ(YYYYMMDD_HHMMSS形式)`
- **拡張子:** `.xlsx`
プロンプトの解説
-
マークダウン形式
- AIとマークダウン形式は非常に相性がいいです。
- 見出しや表などを使って、シンプルに、文脈を持って体系的な表現が可能です。
- Obsidianなどのエディタを使うと直感的に書くことができます。
- 基本条件
- 常に入れておくと安心な指示を入れておきます。
- プロンプトを使いまわす時には、多くの場合で流用ができます。
この様なことが基本的なノウハウです。
様々な方がプロンプトのコツを紹介していますので、目的にあった指示を足したりして、求めるコードが出る確率を高めていってください。
Step3 :生成されたプログラムを実行してみる
上記のプロンプトをAIが解釈して生成するPythonコードの例です。
この様なプログラムが作成されると思います。(動作確認済み)
作成されたコードを使って、実際に処理を実行してみましょう。
import os
import datetime
import openpyxl
from openpyxl.utils import get_column_letter
# --- 設定項目 ---
# 1. 処理対象のフォルダパス(環境に合わせて変更してください)
# 注意: パス内の `\` は `\\` と2つ重ねるか、文字列の前に r を付けます (例: r'C:\Users\...')
SOURCE_FOLDER_PATH = 'C:\\Users\\YourUser\\Documents\\Monthly_Reports'
# 2. 最終的に欲しい統一ヘッダーの定義
UNIFIED_HEADERS = ['取引日', '顧客名', '担当者名', '商品名', '数量', '金額']
# 3. ヘッダーのエイリアス(別名)対応表
# プロンプトの表をPythonの辞書に変換したもの
HEADER_ALIASES = {
'取引日': ['Date', '日付', '購入日'],
'顧客名': ['Customer', 'クライアント', '会社名'],
'担当者名': ['担当', '営業', 'Staff'],
'商品名': ['商品', 'アイテム', 'Item'],
'数量': ['数', 'Qty'],
'金額': ['売上', 'Price', '合計']
}
def find_excel_files(root_folder):
"""指定されたフォルダとそのサブフォルダ内のExcelファイルを探し出す"""
excel_files = []
print(f"--- ファイル検索開始: {root_folder} ---")
for dirpath, _, filenames in os.walk(root_folder):
for filename in filenames:
if filename.endswith('.xlsx'):
excel_files.append(os.path.join(dirpath, filename))
print(f"-> {len(excel_files)}個のExcelファイルが見つかりました。")
return excel_files
def main():
"""メイン処理を実行する関数"""
# 処理対象のExcelファイル一覧を取得
target_files = find_excel_files(SOURCE_FOLDER_PATH)
if not target_files:
print("処理対象のExcelファイルが見つかりませんでした。")
return
all_data = [] # 全てのデータを格納するリスト
print("\n--- データ集約開始 ---")
# 各ファイルをループしてデータを読み込む
for file_path in target_files:
try:
print(f"処理中ファイル: {file_path}")
workbook = openpyxl.load_workbook(file_path, read_only=True)
sheet = workbook.active
# ヘッダー行を読み込み、列の対応関係を作成
file_headers = [cell.value for cell in sheet[1]]
column_mapping = {}
for unified_header in UNIFIED_HEADERS:
found = False
for alias in HEADER_ALIASES[unified_header]:
if alias in file_headers:
# ファイル内の列インデックス(0から始まる)を保存
column_mapping[unified_header] = file_headers.index(alias)
found = True
break
if not found:
column_mapping[unified_header] = None # 対応する列が見つからない場合
# データ行を読み込み、統一フォーマットに変換
for row_index in range(2, sheet.max_row + 1):
new_row = []
for unified_header in UNIFIED_HEADERS:
col_idx = column_mapping[unified_header]
if col_idx is not None:
new_row.append(sheet.cell(row=row_index, column=col_idx + 1).value)
else:
new_row.append(None) # データがない場合は空にする
all_data.append(new_row)
except Exception as e:
print(f"エラー: {file_path} の処理中に問題が発生しました。詳細: {e}")
print("-> 全ファイルのデータ集約が完了しました。")
# データをソートする
print("\n--- データの並べ替え開始 ---")
# ソートキーのインデックスを取得
date_idx = UNIFIED_HEADERS.index('取引日')
amount_idx = UNIFIED_HEADERS.index('金額')
# 取引日(昇順)、金額(降順)でソート
# 日付がない行を考慮し、エラーを回避する
all_data.sort(key=lambda x: (x[date_idx] if x[date_idx] else datetime.date.min, -x[amount_idx] if x[amount_idx] else 0))
print("-> 並べ替えが完了しました。")
# 新しいExcelブックに出力
print("\n--- Excelファイル出力開始 ---")
output_workbook = openpyxl.Workbook()
output_sheet = output_workbook.active
# ヘッダーを書き込み
output_sheet.append(UNIFIED_HEADERS)
# データを書き込み
for row_data in all_data:
output_sheet.append(row_data)
# 書式設定
# オートフィルタを設定
output_sheet.auto_filter.ref = output_sheet.dimensions
# 1行目を固定
output_sheet.freeze_panes = 'A2'
# ファイルを保存
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
file_name = f"統合レポート_{timestamp}.xlsx"
# ダウンロードフォルダのパスを取得
download_folder = os.path.join(os.path.expanduser('~'), 'Downloads')
output_path = os.path.join(download_folder, file_name)
output_workbook.save(output_path)
print("\n--- 処理完了 ---")
print(f"統合レポートが以下の場所に出力されました:\n{output_path}")
if __name__ == "__main__":
main()
使い方(先ほど同様)
- 作業フォルダ
C:\MyPythonProjects\excel-automationなどに、.pyファイルを新規作成- VSCodeの左側の ファイルのアイコン(エクスプローラー) をクリック
- エクスプローラーの中の ファイル+のアイコン(新規ファイル作成) をクリック
-
sum_test.pyのような名前を付けてファイルを保存します。
- Pythonコードを記載し上書き保存
- 自身で生成、もしくは上記のPythonコード全体をコピー&ペースト
-
ctrl + sで上書き保存。- ファイル名のタブの右上角のアイコンが●から×に変わっていたらOK
- Pythonコードを実行
- 右上の ▷のアイコン をクリック(もしくはその横をクリックし、「新しいPythonファイル」をクリック)
- ターミナルに実行状況が出力される
- ダウンロードフォルダにファイルが作成されることを確認
※ 環境設定の部分は、前回記事を前提に割愛しています。必要な場合は、前回記事を参照してください。
エラーが出たときの対処法
AIは毎回少し違うコードを生成しますが、全体の処理の流れや機能は概ね同じはずです。もしサンプルと大きく違うコードが出てきたり、エラーが出たりした場合でも、慌てることはありません。
プロンプトをもう一度実行するか、以下の様にエラーをそのままコピーして、AIに解決させましょう。
こんなエラーがでました。原因と対策を教えてください。
コードに修正が必要な場合は、修正版を出力してください。
## エラー
(ここにエラーを張り付け)
プログラムの解説
このプログラムが何をしているのか、非エンジニアの方向けにステップごとに解説します。
1. 準備:基本設定
プログラムの冒頭では、これから行う作業の設定やルールを定義しています。
-
SOURCE_FOLDER_PATH: どのフォルダにあるExcelファイルを集めるかの設定です。 -
UNIFIED_HEADERS: 最終的に作りたいレポートの列名を決めています。これが完成形の「お手本」になります。 -
HEADER_ALIASES: このプログラムの一番賢い部分です。「『日付』や『Date』と書かれていたら、それは『取引日』のことですよ」という翻訳リスト(あだ名リスト) を定義しています。これにより、ヘッダー名がバラバラでもプログラムが意味を理解できるようになります。 - 最初に数個のファイルで試し、エラーが出たらエイリアス辞書に新しい別名を追加していく…というように、自分の手でプログラムを「賢く」育てていくことができます。
2. ファイルの探索:Excelファイルを探し出す
find_excel_files という部分が、指定されたフォルダの中を隅々まで(サブフォルダの中まで)パトロールし、「.xlsx」で終わるExcelファイルを探し出してリストアップする役割を担っています。
3. データの読み込みと名寄せ:データを集めて整形する
ここがメインの処理です。
- 見つけ出したExcelファイルを一つずつ順番に開きます。
- まずファイルの1行目(ヘッダー)を見て、先ほどの翻訳リスト(
HEADER_ALIASES) と照らし合わせ、「このファイルの『売上』列は、お手本の『金額』列だな」という対応関係を頭の中で整理します。 - 次に、2行目以降のデータを一行ずつ読み込み、整理した対応関係に基づいて、列の順番を「お手本(
UNIFIED_HEADERS)」通りに並べ替えます。 - 並べ替えた綺麗なデータを、
all_dataという大きな空っぽの箱にどんどん追加していきます。
4. 並べ替え:集めたデータを整列させる
すべてのファイルからデータを集め終わったら、all_dataという箱の中身をルールに従って並べ替えます。今回は「取引日が古い順、もし日付が同じなら金額が大きい順」に整列させています。
5. 仕上げと出力:レポートを作成して保存する
- まっさらな新しいExcelブックを作成します。
- 1行目にお手本のヘッダーを書き込み、2行目以降に綺麗に整列させたデータをすべて書き込みます。
- 最後に、使いやすいように「オートフィルタ」や「ウィンドウ枠の固定」といった書式設定を自動で行います。
- PCの「ダウンロード」フォルダに、「統合レポート_20251011_171604.xlsx」のような、実行した日時がわかる名前を付けて保存します。
これで、手作業なら何時間もかかっていたかもしれない「表記ゆれのあるExcelの統合」作業が、一瞬で完了します。
おつかれさまでした!いかがでしたでしたか?
この記事は、「こんな風にすればプログラムが作れて活用できるんだ!これなら自分でも出来る!!」と実感してもらうために書きました。
実際、私の職場の非エンジニアを対象に、前回記事と今回記事の2回の内容でPython活用生活をスタートさせた方が5名以上います。少々お手伝いはしましたが、半日も掛からずに使えるようになり、実績ありです。
自走して活用できる様になった皆さんの感想は、
「環境設定が難しく、そこが壁だと思う。そこを手伝ってもらえたから使えるようになった」
「一回でもプロンプトでAIにプログラムを書かせることをして、実際に動いたのを見たら、『こうやったらいいんだ』と理解できた。」
という様な意見でした。
この記事を見て、少しでも活用できる人が増えてくれれば嬉しいです。

