怎样实现打卡数据统计脚本

wen 实用脚本 29

本文目录导读:

怎样实现打卡数据统计脚本

  1. Excel VBA 实现(适合日常统计)
  2. Python 实现(功能更强大)
  3. 使用说明

我来介绍几种实现打卡数据统计脚本的方法,主要分为Excel VBA和Python两种方式。

Excel VBA 实现(适合日常统计)

VBA脚本示例

Sub 统计打卡数据()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim dict As Object
    Dim key As String
    ' 设置工作表
    Set ws = ThisWorkbook.Sheets("打卡记录")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    ' 创建字典用于统计
    Set dict = CreateObject("Scripting.Dictionary")
    ' 遍历数据(假设A列是姓名,B列是日期,C列是打卡时间)
    For i = 2 To lastRow
        key = ws.Cells(i, 1).Value & "|" & ws.Cells(i, 2).Value
        If Not dict.exists(key) Then
            dict.Add key, 1
        Else
            dict(key) = dict(key) + 1
        End If
    Next i
    ' 输出统计结果
    Dim outputRow As Long
    outputRow = 2
    ' 创建统计表头
    ws.Cells(1, 5).Value = "姓名"
    ws.Cells(1, 6).Value = "日期"
    ws.Cells(1, 7).Value = "打卡次数"
    ' 输出统计结果
    Dim keys As Variant
    keys = dict.keys
    For i = 0 To UBound(keys)
        Dim parts As Variant
        parts = Split(keys(i), "|")
        ws.Cells(outputRow, 5).Value = parts(0)
        ws.Cells(outputRow, 6).Value = parts(1)
        ws.Cells(outputRow, 7).Value = dict(keys(i))
        outputRow = outputRow + 1
    Next i
    MsgBox "统计完成!"
End Sub

Python 实现(功能更强大)

基础统计脚本

import pandas as pd
from datetime import datetime
import os
class AttendanceStats:
    def __init__(self, file_path):
        self.file_path = file_path
        self.df = None
    def load_data(self):
        """加载打卡数据"""
        if self.file_path.endswith('.xlsx'):
            self.df = pd.read_excel(self.file_path)
        elif self.file_path.endswith('.csv'):
            self.df = pd.read_csv(self.file_path)
        else:
            raise ValueError("不支持的文件格式")
        print(f"已加载 {len(self.df)} 条记录")
    def daily_stats(self):
        """每日打卡统计"""
        if self.df is None:
            return None
        # 假设数据包含:姓名、日期、打卡时间
        daily_count = self.df.groupby(['姓名', '日期']).size().reset_index(name='打卡次数')
        return daily_count
    def monthly_stats(self):
        """月度统计"""
        if self.df is None:
            return None
        # 提取月份
        self.df['月份'] = pd.to_datetime(self.df['日期']).dt.month
        monthly_count = self.df.groupby(['姓名', '月份']).size().reset_index(name='打卡次数')
        return monthly_count
    def abnormal_check(self, min_times=1, max_times=4):
        """异常打卡检测"""
        if self.df is None:
            return None
        daily_count = self.daily_stats()
        abnormal = daily_count[
            (daily_count['打卡次数'] < min_times) | 
            (daily_count['打卡次数'] > max_times)
        ]
        return abnormal
    def export_stats(self, output_path):
        """导出统计结果"""
        daily = self.daily_stats()
        monthly = self.monthly_stats()
        abnormal = self.abnormal_check()
        with pd.ExcelWriter(output_path) as writer:
            daily.to_excel(writer, sheet_name='每日统计', index=False)
            monthly.to_excel(writer, sheet_name='月度统计', index=False)
            abnormal.to_excel(writer, sheet_name='异常记录', index=False)
        print(f"统计结果已导出到: {output_path}")
# 使用示例
def main():
    # 初始化统计器
    stats = AttendanceStats("打卡记录.xlsx")
    # 加载数据
    stats.load_data()
    # 查看每日统计
    daily = stats.daily_stats()
    print("每日打卡统计:")
    print(daily.head())
    # 检查异常
    abnormal = stats.abnormal_check()
    if len(abnormal) > 0:
        print(f"\n发现 {len(abnormal)} 条异常记录")
    # 导出统计结果
    stats.export_stats("打卡统计结果.xlsx")
if __name__ == "__main__":
    main()

高级功能版本

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
class AdvancedAttendanceStats:
    def __init__(self, data_file):
        self.data_file = data_file
        self.load_data()
    def load_data(self):
        """加载数据并预处理"""
        # 读取数据
        if self.data_file.endswith('.csv'):
            self.df = pd.read_csv(self.data_file)
        else:
            self.df = pd.read_excel(self.data_file)
        # 确保时间列格式正确
        self.df['打卡时间'] = pd.to_datetime(self.df['打卡时间'])
        self.df['日期'] = self.df['打卡时间'].dt.date
        self.df['时间'] = self.df['打卡时间'].dt.time
        print(f"数据加载完成,共 {len(self.df)} 条记录")
    def analyze_punch_pattern(self):
        """分析打卡模式"""
        # 统计每人每天的打卡次数
        daily_pattern = self.df.groupby(['姓名', '日期']).size().unstack(fill_value=0)
        # 统计打卡时间分布
        self.df['小时'] = self.df['打卡时间'].dt.hour
        time_dist = self.df.groupby('小时').size()
        return daily_pattern, time_dist
    def calculate_working_hours(self):
        """计算工作时长(假设一天打卡两次)"""
        # 获取每天的第一次和最后一次打卡
        first_punch = self.df.groupby(['姓名', '日期'])['打卡时间'].min().reset_index()
        last_punch = self.df.groupby(['姓名', '日期'])['打卡时间'].max().reset_index()
        # 合并并计算时长
        working_hours = pd.merge(first_punch, last_punch, 
                                on=['姓名', '日期'], 
                                suffixes=('_开始', '_结束'))
        working_hours['工作时长(小时)'] = (
            working_hours['打卡时间_结束'] - working_hours['打卡时间_开始']
        ).dt.total_seconds() / 3600
        return working_hours
    def detect_late_arrival(self, late_time='09:30'):
        """检测迟到"""
        late_threshold = pd.to_datetime(late_time).time()
        # 找出每天的第一次打卡
        first_punch = self.df.groupby(['姓名', '日期'])['打卡时间'].min().reset_index()
        first_punch['首次打卡时间'] = first_punch['打卡时间'].dt.time
        # 标记迟到
        first_punch['是否迟到'] = first_punch['首次打卡时间'] > late_threshold
        late_records = first_punch[first_punch['是否迟到']]
        return late_records
    def generate_report(self):
        """生成统计报告"""
        # 基础统计
        daily_count = self.df.groupby(['姓名', '日期']).size().reset_index(name='打卡次数')
        # 异常检测
        abnormal = daily_count[daily_count['打卡次数'] != 2]
        # 工作时长
        working_hours = self.calculate_working_hours()
        # 迟到统计
        late_records = self.detect_late_arrival()
        # 创建报告
        report = {
            '总记录数': len(self.df),
            '统计人数': self.df['姓名'].nunique(),
            '统计天数': self.df['日期'].nunique(),
            '异常记录数': len(abnormal),
            '迟到次数': len(late_records)
        }
        return report, {
            '每日统计': daily_count,
            '异常记录': abnormal,
            '工作时长': working_hours,
            '迟到记录': late_records
        }
    def visualize_stats(self):
        """可视化统计结果"""
        fig, axes = plt.subplots(2, 2, figsize=(15, 10))
        # 1. 每日打卡人数趋势
        daily_people = self.df.groupby('日期')['姓名'].nunique()
        daily_people.plot(ax=axes[0, 0], title='每日打卡人数趋势')
        # 2. 打卡次数分布
        daily_count = self.df.groupby(['姓名', '日期']).size()
        daily_count.hist(ax=axes[0, 1], bins=10, title='每日打卡次数分布')
        # 3. 打卡时间分布
        hours = self.df['打卡时间'].dt.hour
        hours.hist(ax=axes[1, 0], bins=24, title='打卡时间分布')
        # 4. 个人打卡统计
        personal_stats = self.df.groupby('姓名').size().sort_values()
        personal_stats.plot(kind='barh', ax=axes[1, 1], title='个人总打卡次数')
        plt.tight_layout()
        plt.savefig('打卡统计图.png', dpi=300)
        plt.show()

使用说明

Excel VBA使用步骤:

  1. 打开Excel文件,按 Alt + F11 打开VBA编辑器
  2. 插入模块,粘贴代码
  3. F5 运行
  4. 确保数据格式与代码匹配

Python使用步骤:

# 1. 安装依赖
pip install pandas openpyxl matplotlib
# 2. 运行脚本
python attendance_stats.py

数据格式要求:

| 姓名 | 日期       | 打卡时间           |
|------|------------|-------------------|
| 张三 | 2024-01-01 | 2024-01-01 09:00 |
| 李四 | 2024-01-01 | 2024-01-01 09:15 |

这些脚本可以根据实际需求进行调整,如果需要特定功能,可以提供更详细的需求说明。

抱歉,评论功能暂时关闭!