本文目录导读:

我来介绍几种实现打卡数据统计脚本的方法,主要分为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使用步骤:
- 打开Excel文件,按
Alt + F11打开VBA编辑器 - 插入模块,粘贴代码
- 按
F5运行 - 确保数据格式与代码匹配
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 |
这些脚本可以根据实际需求进行调整,如果需要特定功能,可以提供更详细的需求说明。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播