Pythonで勤怠チェックを自動化した話|打刻漏れ検知・残業アラートをExcelから自動生成


月末になるたびに、勤怠表を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:0018: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でメール自動送信(アラートメール送信の実装)
関連記事:情シスなしでやった総務の自動化事例
この自動化経験を転職でどう活かすか知りたい方はこちら


この記事は、総務部での実務経験をもとに執筆しています。勤怠管理・労務コンプライアンス・業務自動化の現場経験から書いています。