月末になるたびに、勤怠表を1行ずつ目視でチェックしていませんか。
「この人、月曜日の退勤が入ってない」「この人また残業が多い、確認しないと」——社員数が増えるほど、この作業が地味に時間を食います。私がいた職場では30名分の勤怠チェックに毎月半日かかっていました。
しかも間違いは許されないから、二重三重に確認する。
それでも漏れが出る。
この記事は、そういう「月末の勤怠チェック地獄」をPythonで自動化した話です。
「自動打刻」の記事はネットにたくさんありますが、総務担当者が本当に必要なのはそっちじゃないと思っています。
「チェックする作業」を自動化するのが、
コンプライアンス的にも正しい使い方です。
その理由も含めてお伝えします。
結論|専用ツールは必要なし
PythonとExcelがあれば、打刻漏れ検知・残業アラートは今日から自動化できる。
特定の勤怠システムは不要。
- 使うもの: Python + pandas(Excel読み込み)+ openpyxl(Excel出力)
- できること①: 打刻漏れ(開始・終了どちらかが空白)を自動で一覧化
- できること②: 月次残業が45時間を超えた社員を自動抽出してメール通知
- やらない方がいいこと: Seleniumを使った「自動打刻」(理由は後述)
月末の勤怠チェックがしんどい総務担当者あるある
チェック作業の何が問題か
勤怠チェックの何が大変かというと、量と責任の組み合わせです。
- 量が多い:社員20〜50名分を毎月、1行ずつ目視チェック
- ミスが許されない:見落としが残業代の払い忘れ・労基署対応につながる
- 属人化している:「この担当者しかチェックできない」状態が多い
加えて、多くの中小企業でいまだにExcelベースの勤怠管理が続いています。
私の会社でもそうです。
Excelは柔軟で使いやすい反面、大量データのチェックは人の目に頼るしかない。そこをPythonで補うのが今回のテーマです。
「自動打刻」より「自動チェック」が正しい理由
自動打刻は労務リスクがある
ネット上の「勤怠 Python 自動化」記事のほとんどは、「Seleniumでブラウザを操作して自動的に出勤・退勤を打刻する」内容です。
つまり社員が楽をするツールな訳です。
ただ、これは総務担当者として推奨できません。
理由は2つあります。
理由①:実態と異なる勤怠記録になる可能性
「まだ仕事してるのに退勤打刻が入る」「出勤前に打刻される」という状態は、労働時間の正確な記録という法的義務に反する可能性があります。
理由②:残業の実態隠蔽リスク
自動で定時に退勤打刻されると、実際の残業が記録に残らない。
意図せず「残業代未払い」「労基違反」につながるリスクがあります。
使うなら、ツール「実行時間」も記録しておくことが無難です。
なので、私はタスクスケジューラで、時間になったら「打刻する」サイトを開く。程度で実施しています。(よく忘れてしまうので…。)
「チェックの自動化」は問題なし
一方、「Excelの勤怠データを読み込んで、打刻漏れや残業超過をチェックする」のは問題ありません。
人の判断を補助するツールとして動かすので、実際の記録を変えるわけではない。自動化の中でも、法的リスクが低い使い方です。
実装例①:Excelの勤怠表から打刻漏れを自動検知する
前提:Excelの勤怠表フォーマット
以下のような形式のExcelを想定します。
| 日付 | 氏名 | 出勤時刻 | 退勤時刻 |
|---|---|---|---|
| 2026/03/01 | 山田太郎 | 9:00 | 18:00 |
| 2026/03/02 | 山田太郎 | 9:15 | (空白) |
| 2026/03/01 | 鈴木花子 | (空白) | 18:30 |
出勤・退勤どちらかが空白の行=打刻漏れとして検知します。
コード(コピペOK)
import pandas as pd
from datetime import datetime
import os
from dotenv import load_dotenv
load_dotenv()
# Excelファイルを読み込む
df = pd.read_excel('勤怠表_2026年3月.xlsx', sheet_name='Sheet1')
# 列名を合わせる(実際のExcelに合わせて変更)
df.columns = ['日付', '氏名', '出勤時刻', '退勤時刻']
# 打刻漏れ(出勤または退勤が空白)を抽出
missing = df[df['出勤時刻'].isna() | df['退勤時刻'].isna()].copy()
if missing.empty:
print('打刻漏れはありませんでした')
else:
print(f'打刻漏れが {len(missing)} 件あります:')
print(missing[['日付', '氏名', '出勤時刻', '退勤時刻']].to_string(index=False))
# 結果をExcelに出力
output_file = f'打刻漏れ一覧_{datetime.now().strftime("%Y%m%d")}.xlsx'
missing.to_excel(output_file, index=False)
print(f'\n{output_file} に出力しました')
必要なライブラリのインストール:
pip install pandas openpyxl python-dotenv
これを実行すると、打刻漏れの一覧をExcelで出力します。あとは該当社員に連絡するだけ。目視チェックの時間がゼロになります。
実装例②:残業上限(36協定)超過者を自動抽出してメール通知
36協定の残業上限とは
労働基準法では、時間外労働の上限が定められています。
- 月45時間・年360時間(一般の協定)
- 月100時間未満(特別条項がある場合の上限)
毎月これを手動でチェックしている総務担当者は多いはず。
これもPythonで自動化できます。
コード(残業時間集計+超過者抽出)
import pandas as pd
import smtplib
from email.message import EmailMessage
import os
from dotenv import load_dotenv
load_dotenv()
# Excelを読み込む
df = pd.read_excel('勤怠表_2026年3月.xlsx', sheet_name='Sheet1')
df.columns = ['日付', '氏名', '出勤時刻', '退勤時刻']
# 勤務時間を計算(退勤 - 出勤)
df['出勤時刻'] = pd.to_datetime(df['出勤時刻'], format='%H:%M', errors='coerce')
df['退勤時刻'] = pd.to_datetime(df['退勤時刻'], format='%H:%M', errors='coerce')
df['勤務時間'] = (df['退勤時刻'] - df['出勤時刻']).dt.total_seconds() / 3600
# 所定労働時間(8時間)を超えた分を残業とする
df['残業時間'] = (df['勤務時間'] - 8).clip(lower=0)
# 社員ごとに月次残業を集計
monthly = df.groupby('氏名')['残業時間'].sum().reset_index()
monthly.columns = ['氏名', '月次残業時間']
# 45時間超過者を抽出
over_limit = monthly[monthly['月次残業時間'] > 45]
if over_limit.empty:
print('残業上限超過者はいません')
else:
print('【警告】残業上限(45時間)超過者:')
print(over_limit.to_string(index=False))
# 管理職にメール通知
body = '以下の社員が今月の残業時間が45時間を超えています。\n\n'
body += over_limit.to_string(index=False)
body += '\n\n確認と対応をお願いします。'
msg = EmailMessage()
msg['Subject'] = '【勤怠アラート】残業上限超過者のお知らせ'
msg['From'] = os.getenv('GMAIL_ADDRESS')
msg['To'] = os.getenv('MANAGER_EMAIL')
msg.set_content(body)
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(os.getenv('GMAIL_ADDRESS'), os.getenv('GMAIL_APP_PASSWORD'))
smtp.send_message(msg)
print('管理職にメール通知しました')
.envファイルの設定:
GMAIL_ADDRESS=あなたのgmail@gmail.com
GMAIL_APP_PASSWORD=アプリパスワード16桁
MANAGER_EMAIL=上司のメールアドレス@example.com
このスクリプトを月末に実行するだけで、残業上限超過者の一覧が自動で上司にメール通知されます。
ChatGPTで自社の勤怠フォーマットに合わせる方法
会社によって勤怠表のExcelフォーマットは違います。列名が「出勤」じゃなくて「start_time」だったり、シート名が違ったりする。
そういう場合は、上記のコードをChatGPTに貼り付けて以下のように伝えてください。
プロンプト例:
以下のPythonコードを修正してください。
【変更したいこと】
・Excelの列名が「日付」→「date」、「氏名」→「name」、「出勤時刻」→「start」、「退勤時刻」→「end」
・所定労働時間が7.5時間(休憩1時間含む)
・残業の上限を月40時間に変更
【現在のコード】
(コードをここに貼り付ける)
フォーマットの違いは全部ChatGPTに対応してもらえます。自分でコードを書く必要はありません。
よくある質問
Q. 会社の勤怠管理システムがExcelではなくクラウドサービスの場合は使えますか?
多くのクラウド勤怠システム(ジョブカン・freee・KING OF TIME等)はCSVエクスポート機能があります。エクスポートしたCSVをpandasで読み込めば同じように処理できます。pd.read_excel() を pd.read_csv() に変えるだけです。
Q. 残業の計算が複雑(フレックスタイム・みなし残業等)な場合は?
まずシンプルな「8時間超過分を残業とみなす」ロジックで動かしてみてください。複雑な計算ルールはChatGPTに追加要件として伝えれば対応できます。
Q. 動かすには毎回手動で実行しないといけませんか?
WindowsのタスクスケジューラまたはMacのcronで定期実行できます。「月末最終営業日に自動実行」という設定も可能です。
Q. パスワード(Gmailのアプリパスワード)の管理が不安です。
.envファイルを使う方法を実装例②で採用しています。コードにパスワードを書かず、.envファイルだけに保存してください。詳しくは「Pythonでメール自動送信」の記事を参照してください。
この経験はキャリアにも使える
「勤怠チェックを自動化した実績」は転職でも使える
「Pythonで勤怠チェックを自動化し、月8時間の作業を自動化した」という実績は、転職の自己PR・職務経歴書で確実に活きます。
「業務改善」「DX推進」「効率化」という実績は、特に総務・人事・バックオフィス職の転職市場でかなり希少です。
「データを扱える総務担当者」へのキャリアパス
Excelのデータをpandasで処理できるようになると、「人件費集計」「勤怠コスト分析」「採用効率レポート」など、数字で経営層に提案できる総務担当者に近づきます。
「言われたことをやる総務」から「データで提案できる総務」への転換点になります。
まとめ
- 「自動チェック」は合法・「自動打刻」はリスクあり:チェックを自動化するのがコンプライアンス的に正しい使い方
- 特定システム不要:ExcelまたはCSVエクスポートがあれば使える
- 打刻漏れ検知:出勤・退勤どちらかが空白の行をpandasで一発抽出
- 残業アラート:月45時間超過者を自動検知してメール通知
- カスタマイズ:フォーマットが違う場合はChatGPTに対応してもらえる
月末の勤怠チェックに半日かけていた作業が、スクリプト実行の数秒になります。最初の設定に1〜2時間かかりますが、それ以降は毎月の時間を取り戻せます。
関連記事
勤怠データをPythonで処理できるようになると、次は何に使えるか自然と広がっていきます。
→ 関連記事:Pythonでメール自動送信(アラートメール送信の実装)
→ 関連記事:情シスなしでやった総務の自動化事例
→ この自動化経験を転職でどう活かすか知りたい方はこちら
この記事は、総務部での実務経験をもとに執筆しています。勤怠管理・労務コンプライアンス・業務自動化の現場経験から書いています。