ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
123
返回列表 发新帖
楼主: jhjxy

[求助] 考勤数据分析

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-7-20 12:25 | 显示全部楼层
jhjxy 发表于 2018-7-20 10:53
是这三行数据吗

'因为IT在夜晚机器上刷的卡,看上下班时间应该归类于科室

'仅转换成考勤表,对多次刷卡进行了处理。看上去好像差不多,自己好好测试一下,看上去晕

'6095173100004的为车间晚班专用打卡机,如果这个条件不成立代码的执行结果是不确定的,可以说是无解,这问题也就算结束了(因为有漏刷、迟到或早退,所以很难根据其它条件也确定夜班)

'其他的计算等可能公式就能搞得定的吧,一步步来

Option Explicit

Sub test()
  Dim arr, i, j, k, dic, t, brr, cnt, id, m, td, tm, flag, wk
  Set dic = CreateObject("scripting.dictionary")
  id = 6095173100004#
  ReDim mark(1 To 3)
  mark(1) = Array(#7:45:00 AM#, #5:05:00 PM#) '科室
  mark(2) = Array(#7:45:00 AM#, #8:05:00 PM#) '车间白班
  mark(3) = Array(#7:45:00 PM#, #8:05:00 AM#) '车间夜班
  With Sheets("3")
    arr = .Range("a2:e" & .Cells(Rows.Count, "a").End(xlUp).Row + 1)
  End With
  For i = 1 To UBound(arr, 1) - 1
    For j = i To UBound(arr, 1) - 1
      If arr(j, 2) <> arr(j + 1, 2) Then
        For k = i To j
          dic(CDate(Split(arr(k, 4))(0))) = vbNullString
        Next
        cnt = cnt + 1: i = j: Exit For
      End If
  Next j, i
  brr = dic.keys: dic.RemoveAll
  For i = 0 To UBound(brr) - 1
    For j = i + 1 To UBound(brr)
      If brr(i) > brr(j) Then
        t = brr(i): brr(i) = brr(j): brr(j) = t
      End If
  Next j, i
  For i = 0 To UBound(brr): dic(brr(i)) = i + 4: Next
  ReDim brr(1 To cnt * 3, 1 To dic.Count + 3)
  flag = brr
  For i = 1 To UBound(arr, 1) - 1
    For j = i To UBound(arr, 1) - 1
      If arr(j, 2) <> arr(j + 1, 2) Then
        m = m + 1
        brr(3 * m, 1) = arr(i, 2): brr(3 * m - 2, 2) = "工作"
        brr(3 * m - 1, 2) = "天数": brr(3 * m - 2, 3) = "签到"
        brr(3 * m - 1, 3) = "离开": brr(3 * m, 3) = "工时"
        For k = i To j
          t = Split(arr(k, 4))
          td = CDate(t(0))
          tm = CDate(t(UBound(t)))
          If InStr(arr(i, 1), "车间") > 0 Then '车间
            If arr(i, 5) <> id Then '早班
              If tm <= #12:00:00 PM# Then '早班签到
                If Len(brr(3 * (m - 1) + 1, dic(td))) > 0 Then '重复刷卡
                  If CDate(brr(3 * (m - 1) + 1, dic(td))) > tm Then brr(3 * (m - 1) + 1, dic(td)) = tm
                Else
                  brr(3 * (m - 1) + 1, dic(td)) = tm
                End If
                brr(3 * (m - 1) + 1, dic(td)) = Format(brr(3 * (m - 1) + 1, dic(td)), "hh:mm")
'                If tm > mark(2)(0) Then flag(3 * (m - 1) + 1, dic(td)) = 1 '早班迟到
              Else '早班离开
                If Len(brr(3 * (m - 1) + 2, dic(td))) > 0 Then '重复刷卡
                  If CDate(brr(3 * (m - 1) + 2, dic(td))) < tm Then brr(3 * (m - 1) + 2, dic(td)) = tm
                Else
                  brr(3 * (m - 1) + 2, dic(td)) = tm
                End If
                brr(3 * (m - 1) + 2, dic(td)) = Format(brr(3 * (m - 1) + 2, dic(td)), "hh:mm")
'                If tm < mark(2)(1) Then flag(3 * (m - 1) + 2, dic(td)) = 1 '早班早退
              End If
              '工时计算
            Else '晚班
              If tm > #12:00:00 PM# Then '晚班签到
                If Len(brr(3 * (m - 1) + 1, dic(td))) > 0 Then '重复刷卡
                  If CDate(brr(3 * (m - 1) + 1, dic(td))) > tm Then brr(3 * (m - 1) + 1, dic(td)) = tm
                Else
                  brr(3 * (m - 1) + 1, dic(td)) = tm
                End If
                brr(3 * (m - 1) + 1, dic(td)) = Format(brr(3 * (m - 1) + 1, dic(td)), "hh:mm")
'                If tm > mark(3)(0) Then flag(3 * (m - 1) + 1, dic(td)) = 1 '晚班迟到
              Else
                If Len(brr(3 * (m - 1) + 2, dic(td))) > 0 Then '重复刷卡
                  If CDate(brr(3 * (m - 1) + 2, dic(td))) < tm Then brr(3 * (m - 1) + 2, dic(td)) = tm
                Else
                  brr(3 * (m - 1) + 2, dic(td)) = tm
                End If
                brr(3 * (m - 1) + 2, dic(td)) = Format(brr(3 * (m - 1) + 2, dic(td)), "hh:mm")
'                If tm < mark(3)(1) Then flag(3 * (m - 1) + 2, dic(td)) = 1 '晚班早退
              End If
              '工时计算
            End If
          Else '科室
            If arr(i, 5) <> id Then
              If tm <= #12:00:00 PM# Then '白班签到
                If Len(brr(3 * (m - 1) + 1, dic(td))) > 0 Then '重复刷卡
                  If CDate(brr(3 * (m - 1) + 1, dic(td))) > tm Then brr(3 * (m - 1) + 1, dic(td)) = tm
                Else
                  brr(3 * (m - 1) + 1, dic(td)) = tm
                End If
                brr(3 * (m - 1) + 1, dic(td)) = Format(brr(3 * (m - 1) + 1, dic(td)), "hh:mm")
'                If tm > mark(1)(0) Then flag(3 * (m - 1) + 1, dic(td)) = 1 '白班迟到
              Else '白班离开
                If Len(brr(3 * (m - 1) + 2, dic(td))) > 0 Then '重复刷卡
                  If CDate(brr(3 * (m - 1) + 2, dic(td))) < tm Then brr(3 * (m - 1) + 2, dic(td)) = tm
                Else
                  brr(3 * (m - 1) + 2, dic(td)) = tm
                End If
                brr(3 * (m - 1) + 2, dic(td)) = Format(brr(3 * (m - 1) + 2, dic(td)), "hh:mm")
'                If tm < mark(1)(1) Then flag(3 * (m - 1) + 2, dic(td)) = 1 '白班早退
              End If
              '工时计算
            End If
          End If
        Next
        i = j: Exit For
      End If
  Next j, i
  ReDim arr(1 To 2, 1 To UBound(brr, 2))
  wk = "日一二三四五六"
  arr(2, 1) = "姓名": arr(1, 3) = "星期": arr(2, 3) = "日起"
  For Each t In dic.keys
    arr(1, dic(t)) = Mid(wk, Weekday(t), 1)
    arr(2, dic(t)) = Format(t, "dd")
  Next
  With Sheets("考勤表").[a7]
    .Resize(Rows.Count - 6, UBound(brr, 2)).ClearContents
'    .Offset(, 3).Resize(UBound(brr, 1), UBound(brr, 2)).NumberFormatLocal = "@"
    .Resize(UBound(brr, 1), UBound(brr, 2)) = brr
    .Offset(-2).Resize(2, UBound(arr, 2)) = arr
  End With
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-20 16:20 | 显示全部楼层
一把小刀闯天下 发表于 2018-7-20 12:25
'因为IT在夜晚机器上刷的卡,看上下班时间应该归类于科室

'仅转换成考勤表,对多次刷卡进行了处理。看 ...

这个问题无需考虑,这是测试的。以后不会出现这种问题

TA的精华主题

TA的得分主题

发表于 2018-7-20 20:37 | 显示全部楼层
jhjxy 发表于 2018-7-20 16:20
这个问题无需考虑,这是测试的。以后不会出现这种问题

只是在提醒你,可以确定的一件事就是这问题跟我没半毛关系。感觉你顶多算是一个旁观者而不是一个求助者

另外一点夜班你的计算也是错误的,如果1日下夜班就缺少上月的上夜班的记录。一样的道理本月最后一天的夜班也无法计算。

到此为止吧,纯体力活但有些条件并不确定,挺费劲的一件事。这论坛高手不少你还是找找他们或许会得到一些帮助的

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-21 08:14 | 显示全部楼层
一把小刀闯天下 发表于 2018-7-20 20:37
只是在提醒你,可以确定的一件事就是这问题跟我没半毛关系。感觉你顶多算是一个旁观者而不是一个求助者
...

是的,我有这个需求,但我又是菜鸟,不太懂。刚学的VBA。不知从哪里开始。不管怎么样,感谢!!!

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-7-21 08:14 | 显示全部楼层
一把小刀闯天下 发表于 2018-7-20 20:37
只是在提醒你,可以确定的一件事就是这问题跟我没半毛关系。感觉你顶多算是一个旁观者而不是一个求助者
...

是的,我有这个需求,但我又是菜鸟,不太懂。刚学的VBA。不知从哪里开始。不管怎么样,感谢!!!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-1-10 17:14 , Processed in 0.019438 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表