🤖
【業務効率化】Pythonを使った勤怠表自動転記ツールの作り方
① Pythonのインストール
- 公式サイト から最新のPythonをダウンロード
- インストーラーを実行し、「Add Python to PATH」にチェックを入れる
- インストール完了後、ターミナル(またはコマンドプロンプト)で以下を実行して確認正しくバージョンが表示されればOK
python --version
② VS Codeのインストール(まだの場合)
- 公式サイト からVS Codeをダウンロード&インストール
③ Python拡張機能のインストール
- VS Codeを開く
- 拡張機能(Ctrl + Shift + X) を開く
- 「Python」を検索し、MicrosoftのPython拡張機能をインストール
④ 仮想環境の作成(推奨)
プロジェクトごとにパッケージ管理を分けたい場合、仮想環境を作ると便利です。
- VS Codeのターミナルを開く(Ctrl + `)
- 以下のコマンドを実行
python -m venv venv
- 仮想環境を有効化(Windows)Macの場合:
venv\Scripts\activate
source venv/bin/activate
- ターミナルに
(venv)
が表示されたら成功
⑤ 必要なライブラリをインストール
このプロジェクトで使う pandas
や openpyxl
をインストール
pip install pandas openpyxl
以下のディレクトリ構造でファイルを作成する
kintai_tool/
│── main.py # メインスクリプト(実行ファイル)
│── gui.py # GUIでmain.pyを実行するため
│── config.py # 設定ファイル(従業員名などの設定管理)
│── utils.py # 補助関数(Excel操作・データ処理)
│── templates/ # ひな型フォルダ
│ └── 勤怠表雛形.xlsx # 勤怠表のテンプレートファイル
│── input/ # 入力ファイル(CSVの格納場所)
│ ├── 勤怠詳細_YYYYMM_〇〇.csv # ダウンロードしたCSVデータ
│── output/ # 出力ファイル(生成されたExcelの格納場所)
│ ├── 勤怠表_YYYYMM_〇〇.xlsx # 生成されたExcelファイル
│── logs/ # ログファイル(エラー管理用)
│── requirements.txt # 必要なPythonライブラリ
│── README.md # 使い方の説明
エクスプローラーで見るとこのようになります。
VScodeで見るとこのようになります。
⑥ main.py、config.py、utils.py、gui.py をそれぞれ作成する
main.py
import os
import argparse
import pandas as pd
from datetime import datetime
from utils import read_csv, process_data, write_to_excel
from config import DEFAULT_EMPLOYEE_NAME, INPUT_DIR, OUTPUT_DIR
# 必要なフォルダが存在しない場合は作成
os.makedirs(INPUT_DIR, exist_ok=True)
os.makedirs(OUTPUT_DIR, exist_ok=True)
# コマンドライン引数の処理
parser = argparse.ArgumentParser(description="勤怠データをExcelに変換するツール")
parser.add_argument("--name", type=str, default=DEFAULT_EMPLOYEE_NAME, help="従業員名を指定")
parser.add_argument("--file", type=str, required=True, help="処理するCSVファイルのパス")
parser.add_argument("--template", type=str, required=True, help="テンプレートExcelファイルのパス")
args = parser.parse_args()
# CSVデータを読み込み
df = read_csv(args.file)
# CSVから月情報を取得
first_date = df["日付"].min()
year_month = first_date.to_pydatetime().strftime("%Y%m")
# データの整形
df_processed = process_data(df)
# 出力ファイル名を作成
output_filename = f"勤怠表_{year_month}_{args.name}.xlsx"
output_path = os.path.join(OUTPUT_DIR, output_filename)
# Excelに書き込み(不足していた csv_filename を追加)
write_to_excel(args.template, output_path, df_processed, args.file)
print(f"✅ 勤怠表を作成しました: {output_path}")
config.py
import os
import sys
import configparser
from pathlib import Path
def get_config_path():
"""実行ファイルと同じディレクトリのconfig.iniのパスを返す"""
if getattr(sys, 'frozen', False):
# exe実行時
base_path = Path(sys.executable).parent
else:
# 通常実行時
base_path = Path(__file__).parent
return base_path / 'config.ini'
def create_default_config():
"""デフォルトの設定ファイルを作成する"""
config = configparser.ConfigParser(interpolation=None) # 補間を無効化
# デフォルト設定
config['DEFAULT'] = {
'employee_name': '小島知将',
'template_path': 'templates/勤怠表雛形_2025年版.xlsx'
}
config['PATHS'] = {
'input_dir': 'input',
'output_dir': 'output'
}
config['CSV'] = {
'encoding': 'utf-8',
'date_format': '%Y-%m-%d'
}
# 設定ファイルを保存
with open(get_config_path(), 'w', encoding='utf-8') as f:
config.write(f)
def load_config():
"""設定を読み込む。ない場合は作成する"""
config = configparser.ConfigParser(interpolation=None) # 補間を無効化
config_path = get_config_path()
# config.iniが存在しない場合、デフォルト設定で作成
if not config_path.exists():
create_default_config()
config.read(config_path, encoding='utf-8')
return config
def save_config(config):
"""設定を保存する"""
with open(get_config_path(), 'w', encoding='utf-8') as f:
config.write(f)
def get_default_employee_name():
return load_config()['DEFAULT']['employee_name']
def get_template_path():
return load_config()['DEFAULT']['template_path']
def get_input_dir():
return load_config()['PATHS']['input_dir']
def get_output_dir():
return load_config()['PATHS']['output_dir']
def get_csv_encoding():
return load_config()['CSV']['encoding']
def get_date_format():
return load_config()['CSV']['date_format']
def update_config(name, template):
"""config.iniに氏名とテンプレートファイルのパスを保存"""
config = load_config()
config['DEFAULT']['employee_name'] = name
config['DEFAULT']['template_path'] = template
save_config(config)
def ensure_directories():
"""必要なディレクトリを作成"""
dirs = ['input', 'output', 'templates']
for dir_name in dirs:
os.makedirs(dir_name, exist_ok=True)
# プログラム起動時に実行
ensure_directories()
utils.py
import os
import pandas as pd
import openpyxl
from openpyxl.utils import get_column_letter
from config import get_csv_encoding, get_date_format
def read_csv(csv_path):
"""
CSVファイルを読み込み、DataFrameとして返す
"""
df = pd.read_csv(csv_path, encoding=get_csv_encoding())
df["日付"] = pd.to_datetime(df["日付"], format=get_date_format())
return df
def process_data(df):
"""
勤怠データを整形する
"""
# 必要なカラムの選択
columns_to_keep = ["日付", "始業時刻", "終業時刻", "総勤務時間", "法定内残業", "時間外労働", "深夜労働", "勤怠種別"]
df_filtered = df[columns_to_keep].copy()
# 不要データの削除(未入力、休日)
# 未入力・休日データも残すように変更
# df_filtered = df_filtered[~df_filtered["勤怠種別"].isin(["未入力", "所定休日", "法定休日"])]
# 時間を小数時間に変換
def time_to_hours(time_str):
if isinstance(time_str, str) and ":" in time_str:
h, m = map(int, time_str.split(":"))
return h + m / 60 # 分を時間に変換
return 0
df_filtered["総勤務時間"] = df_filtered["総勤務時間"].apply(time_to_hours)
return df_filtered
def write_to_excel(template_path, output_path, df, csv_filename):
"""
ひな型Excelに勤怠データを書き込む
"""
import openpyxl
wb = openpyxl.load_workbook(template_path)
sheet = wb["勤務表"]
# G1セルにCSVファイル名から取得した従業員名を記載
import re
name_match = re.search(r'勤怠詳細_(.+?)_\d{4}_\d{2}', os.path.basename(csv_filename))
employee_name = name_match.group(1) if name_match else "不明"
sheet["G1"] = employee_name
# H5セルの月を取得し、それに基づいてA列の日付を設定
month_value = df["日付"].dt.month.iloc[0]
year_value = df["日付"].dt.year.iloc[0]
sheet["H5"] = month_value
sheet["F5"] = year_value
for index, row in enumerate(df.itertuples(), start=11): # C列から開始
day_value = index - 10 # A11に1日から入力
sheet[f"A{index}"] = f"=DATE({year_value},{month_value},{day_value})"
sheet[f"C{index}"] = row.始業時刻
sheet[f"D{index}"] = row.終業時刻
sheet[f"E{index}"] = "1:00" if row.勤怠種別 not in ["未入力", "所定休日", "法定休日"] else "" # 休憩時間
sheet[f"F{index}"] = row.総勤務時間
wb.save(output_path)
print(f"✅ Excelファイルを保存しました: {output_path}")
gui.py
import os
import tkinter as tk
from tkinter import filedialog, messagebox
import subprocess
from config import INPUT_DIR, TEMPLATE_PATH, DEFAULT_EMPLOYEE_NAME, update_config # config.ini ではなく config.py から取得
def select_csv():
"""CSVファイルを選択する"""
file_path = filedialog.askopenfilename(initialdir=INPUT_DIR, title="CSVファイルを選択", filetypes=[("CSV files", "*.csv")])
if file_path:
csv_entry.delete(0, tk.END)
csv_entry.insert(0, file_path)
def select_template():
"""テンプレートファイルを選択する"""
file_path = filedialog.askopenfilename(initialdir=os.path.dirname(TEMPLATE_PATH), title="テンプレートファイルを選択", filetypes=[("Excel files", "*.xlsx")])
if file_path:
template_entry.delete(0, tk.END)
template_entry.insert(0, file_path)
def open_output_folder():
"""出力フォルダを開く"""
output_dir = os.path.abspath("output")
if os.path.exists(output_dir):
os.startfile(output_dir) # Windows
else:
messagebox.showerror("エラー", "出力フォルダが見つかりません。")
def run_main():
csv_file = csv_entry.get()
template_file = template_entry.get()
employee_name = name_entry.get().strip()
if not csv_file:
messagebox.showerror("エラー", "CSVファイルを選択してください。")
return
if not template_file:
messagebox.showerror("エラー", "テンプレートファイルを選択してください。")
return
if not employee_name:
messagebox.showerror("エラー", "氏名を入力してください。")
return
# config.py を更新
update_config(employee_name, template_file)
try:
subprocess.run(["python", "main.py", "--name", employee_name, "--file", csv_file, "--template", template_file], check=True)
messagebox.showinfo("完了", "勤怠表の作成が完了しました!")
open_output_folder()
except subprocess.CalledProcessError:
messagebox.showerror("エラー", "処理中にエラーが発生しました。")
# GUIウィンドウの作成
root = tk.Tk()
root.title("勤怠表作成ツール")
root.geometry("500x400")
root.configure(bg="#f5f5f5")
font_style = ("Arial", 12)
button_style = {"font": font_style, "bg": "#4CAF50", "fg": "white", "activebackground": "#45a049", "padx": 10, "pady": 5}
tk.Label(root, text="CSVファイル:", font=font_style, bg="#f5f5f5").pack(pady=(10, 0))
csv_entry = tk.Entry(root, width=50, font=font_style)
csv_entry.pack()
tk.Button(root, text="参照", command=select_csv, **button_style).pack(pady=5)
tk.Label(root, text="テンプレートファイル:", font=font_style, bg="#f5f5f5").pack(pady=(10, 0))
template_entry = tk.Entry(root, width=50, font=font_style)
template_entry.insert(0, TEMPLATE_PATH) # config.py から取得
template_entry.pack()
tk.Button(root, text="参照", command=select_template, **button_style).pack(pady=5)
tk.Label(root, text="氏名:", font=font_style, bg="#f5f5f5").pack(pady=(10, 0))
name_entry = tk.Entry(root, width=50, font=font_style)
name_entry.insert(0, DEFAULT_EMPLOYEE_NAME) # config.py から取得
name_entry.pack()
tk.Button(root, text="実行", command=run_main, **button_style).pack(pady=15)
root.mainloop()
⑦ 動作テストを実行する
1️⃣ 必要なフォルダの作成
以下のコマンドを実行して、フォルダを作成してください。
※すでに作成済であれば不要
mkdir -p input output templates logs
templates/
に雛形を配置
2️⃣ -
勤怠表雛形_yyyy年版.xlsx
をtemplates/
に移動
input/
にテスト用CSVを配置
3️⃣ - freeeからダウンロードしたCSVを
input/
に配置(例:勤怠詳細_202502_氏名.csv
)
gui.py
を実行
4️⃣ - 以下のように、GUIが起動するか確認
input/
に配置したcsvファイルを選択する
5️⃣ 「参照」から6️⃣ 「実行」をクリックして、出力されたExcelを確認
- 自動で開くoutputフォルダから
(例)勤怠表_202502_氏名.xlsx
を開いて、データが正しく記入されているかチェック
⑧ 「gui.py」を.exeファイルに変換する
pyinstaller
のインストール
1️⃣ pip install pyinstaller
は コマンドプロンプト (Windows) または ターミナル (Mac/Linux) で実行します。
-
kintai_tool/
ディレクトリに移動(例)dev/内にkintai_toolフォルダがある場合cd C:\Users\my-pc\dev\kintai_tool
-
pyinstaller
をインストールpip install pyinstaller
.exe
を作成
2️⃣ 次に、以下のコマンドを実行し、exe
ファイルを作成します。
pyinstaller --onefile --windowed --name "勤怠表自動作成ツールver.1.0" gui.py
🔹 オプションの意味
-
--onefile
→.exe
を 1つのファイルにまとめる -
--windowed
→ GUIアプリとして実行(tkinter
用) -
--name "勤怠表自動作成ツールver.1.0"
→ 出力する.exe
の名前を指定
.exe
の保存場所を確認
3️⃣ コマンド実行後、以下のようなディレクトリが作成されます。
kintai_tool/
│── dist/
│ ├── 勤怠表自動作成ツールver.1.0.exe # ここに実行ファイルが作成される
│── build/ # ビルド時に作成される一時フォルダ(削除可)
│── gui.spec # PyInstaller の設定ファイル
│── gui.py
│── main.py
│── config.py
│── utils.py
│── templates/
│── input/
│── output/
│── logs/
│── README.md
.exe
の動作確認
4️⃣ -
dist/
フォルダに移動 -
勤怠表自動作成ツールver.1.0.exe
をダブルクリック - GUI が正しく開くか確認
-
実行
ボタンを押して 勤怠表が正常に作成されるかチェック -
output
フォルダが 自動で開くか確認
5️⃣ 不要なファイル・フォルダの削除
.exe
作成後、以下のファイル・フォルダは 削除しても問題ありません:
rm -r build/
rm gui.spec
✅ Python をインストールしていない環境で実行できるか?
✔ pyinstaller
で作成した .exe
は Python 環境がないPCでも実行可能
✔ .exe
に 必要な Python ライブラリがすべて含まれる
✔ .exe
をそのまま配布するだけでOK 🎉
⑨ GitHubリポジトリを作成し、ローカルリポジトリと連携する
- GitHubで新しいリポジトリを作成
- GitHubにログインし、「New Repository」ボタンをクリック。
- Description: 「勤怠表自動作成ツール」など
- Private/Public を選択
- リポジトリ名を
kintai_tool
に設定し、「Create repository」をクリック。
- ローカルリポジトリを作成または移動
cd C:\Users\my-pc\dev\kintai_tool
git init
- .gitignore ファイルの作成:
# PowerShellの場合
New-Item -Path .gitignore -ItemType File
# または、メモ帳等で.gitignoreファイルを作成
- .gitignore の内容:
gitignore
# Python
__pycache__/
*.py[cod]
*$py.class
.Python
build/
dist/
*.egg-info/
# PyInstaller
*.manifest
*.spec
# Folders
input/*
output/*
!input/.gitkeep
!output/.gitkeep
# Config
config.ini
# Logs
*.log
# IDE
.idea/
.vscode/
*.swp
# Virtual Environment
venv/
env/
- .gitkeep ファイルの作成 (空のフォルダを維持するため):
# PowerShellの場合
New-Item -Path "input\.gitkeep" -ItemType File
New-Item -Path "output\.gitkeep" -ItemType File
- .gitattributes の作成:
# PowerShellの場合
New-Item -Path .gitattributes -ItemType File
- GitHubリポジトリとローカルリポジトリを接続
git remote add origin https://github.com/your-username/kintai_tool.git
- ファイルをステージングしてコミット
git add .
git commit -m "勤怠表自動作成ツール v1.0 初回コミット"
- リポジトリにpush
git branch -M main
git push -u origin main
⑩ GitHubのReleasesセクションで配布用ZIPを提供する
-
GitHubのリポジトリを開く
-
GitHubにログインし、リポジトリ(
kintai_tool
)を開く。
-
GitHubにログインし、リポジトリ(
-
新しいリリースを作成
- 「Releases」タブを開く。
- 「Create a new release」をクリック。
-
リリース情報を入力
-
Tag version
にv1.0
と入力。
-
-
Release title
に勤怠表自動作成ツール v1.0
と入力。 -
Description
にバージョンの変更点や説明を記入。
-
ZIPファイルをアップロード
-
勤怠表自動作成ツール_v1.0.zip
をドラッグ&ドロップ。
-
-
リリースを公開
- 「Publish release」ボタンを押して完了。
Discussion