ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 1431|回复: 8

[求助] 如何高效率查找匹配汇总

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-2-2 13:54 | 显示全部楼层 |阅读模式
要整理考勤记录,自己写了一半的if判断,发现效率非常非常慢,请教高手怎样提高效率,并写完整需求。多谢希望要达成的效果
1、提取“打卡记录”里的 人名及对应考勤号码到“考勤汇总”中
1.jpg

2、根据考勤号码再将“打卡记录”对应日期的第一次打卡记录和当天最后一次打卡记录写入“考勤汇总”
2.jpg
111考勤记录.zip (85.5 KB, 下载次数: 15)

TA的精华主题

TA的得分主题

发表于 2019-2-2 14:48 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
'当前如果有多次打卡,首次出现按首次打卡来处理,最后一次出现按最后打卡来处理。如果当天刷卡多于一次的计算工时

'试了一下才知道你很多数据都不全,输出单元格格式我就不作处理了,,,

Option Explicit

Sub test()
  Dim arr, i, j, k, kk, m, pos
  arr = Sheets("打卡记录").[a1].CurrentRegion.Offset(1)
  ReDim brr(UBound(arr, 1) / 30 * 3, 1 To 3 + 31)
  brr(0, 1) = "考勤号码": brr(0, 2) = "姓名": brr(0, 3) = "日期"
  For i = 1 To 31: brr(0, i + 3) = i: Next
  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 + 3
        brr(m - 2, 1) = arr(i, 3): brr(m - 2, 2) = arr(i, 2)
        brr(m - 2, 3) = "首次打卡": brr(m - 1, 3) = "最后打卡": brr(m, 3) = "工时"
        For k = i To j
          pos = Val(Format(arr(k, 4), "d"))
          brr(m - 2, pos + 3) = arr(k, 5)
          For kk = k To UBound(arr, 1) - 1
            If arr(kk, 4) <> arr(kk + 1, 4) Then
              If kk > k Then
                brr(m - 1, pos + 3) = arr(kk, 5)
                brr(m, pos + 3) = brr(m - 1, pos + 3) - brr(m - 2, pos + 3)
              End If
              k = kk: Exit For
            End If
        Next kk, k
        i = j: Exit For
      End If
  Next j, i
  Sheets("考勤汇总").[a2].Resize(m + 1, UBound(brr, 2)) = brr
End Sub

TA的精华主题

TA的得分主题

发表于 2019-2-2 14:56 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
'可能是这样,最后打卡跟工时不作处理,给你凑成示例结果,,,

Option Explicit

Sub test()
  Dim arr, i, j, k, kk, m, pos
  arr = Sheets("打卡记录").[a1].CurrentRegion.Offset(1)
  ReDim brr(UBound(arr, 1) / 30 * 3, 1 To 3 + 31)
  brr(0, 1) = "考勤号码": brr(0, 2) = "姓名": brr(0, 3) = "日期"
  For i = 1 To 31: brr(0, i + 3) = i: Next
  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 + 3
        brr(m - 2, 1) = arr(i, 3): brr(m - 2, 2) = arr(i, 2)
        brr(m - 2, 3) = "首次打卡": brr(m - 1, 3) = "最后打卡": brr(m, 3) = "工时"
        For k = i To j
          pos = Val(Format(arr(k, 4), "d"))
          For kk = k To UBound(arr, 1) - 1
            If arr(kk, 4) <> arr(kk + 1, 4) Then brr(m - 2, pos + 3) = arr(kk, 5): k = kk: Exit For
        Next kk, k
        i = j: Exit For
      End If
  Next j, i
  Sheets("考勤汇总").[a2].Resize(m + 1, UBound(brr, 2)) = brr
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-2-2 14:58 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
一把小刀闯天下 发表于 2019-2-2 14:48
'当前如果有多次打卡,首次出现按首次打卡来处理,最后一次出现按最后打卡来处理。如果当天刷卡多于一次的 ...

感谢,果然是大神。看来我还得仔细学一下字典的用法

TA的精华主题

TA的得分主题

发表于 2019-2-2 15:01 | 显示全部楼层
joejinx 发表于 2019-2-2 14:58
感谢,果然是大神。看来我还得仔细学一下字典的用法

哈哈哈,你哪只眼睛看到我用了字典,笑死!

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2019-2-2 20:23 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
  1. Sub zzz()
  2. Sheet2.Activate
  3. Application.ScreenUpdating = False
  4. ActiveSheet.UsedRange.ClearContents
  5. Dim d, ds, dz, arr, i&, j&, k&, m&, n&
  6. Set d = CreateObject("Scripting.Dictionary")
  7. Set ds = CreateObject("Scripting.Dictionary")
  8. Set dz = CreateObject("Scripting.Dictionary")
  9. arr = Sheet1.[a1].CurrentRegion.Value
  10. n = UBound(arr) * 2
  11. ReDim brr(1 To n * 2, 1 To 34)
  12. brr(1, 1) = "考勤号码": brr(1, 2) = "姓名": brr(1, 3) = "项目\日期"
  13. For j = 1 To 31
  14.   brr(1, j + 3) = j
  15. Next
  16. m = 1
  17. For i = 2 To UBound(arr)
  18.   n = Day(arr(i, 4))
  19.   s = arr(i, 2) & arr(i, 3)
  20.   s2 = arr(i, 2) & arr(i, 3) & n
  21.   dz(s2) = arr(i, 5)
  22.   If Not d.exists(s) Then
  23.     m = m + 1
  24.     d(s) = m
  25.     brr(m, 1) = arr(i, 3)
  26.     brr(m, 2) = arr(i, 2)
  27.     brr(m, 3) = "首次打卡"
  28.     brr(m + 1, 3) = "末次打卡"
  29.     brr(m + 2, 3) = "工时"
  30.     m = m + 2
  31.   End If
  32. Next
  33. For i = UBound(arr) To 2 Step -1
  34.   n = Day(arr(i, 4))
  35.   s2 = arr(i, 2) & arr(i, 3) & n
  36.   ds(s2) = arr(i, 5)
  37. Next
  38. For i = 2 To m Step 3
  39.   For j = 4 To 34
  40.     s = brr(i, 2) & brr(i, 1) & brr(1, j)
  41.     brr(i, j) = ds(s)
  42.     brr(i + 1, j) = dz(s)
  43.     If brr(i + 1, j) >= brr(i, j) Then
  44.       brr(i + 2, j) = brr(i + 1, j) - brr(i, j)
  45.     Else
  46.       brr(i + 2, j) = 0
  47.     End If
  48.   Next
  49. Next
  50. [a2].Resize(m, 34) = brr
  51. Application.ScreenUpdating = True
  52. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2019-2-2 20:27 | 显示全部楼层
参考附件。。。。。。

190202-考勤记录.rar

99.41 KB, 下载次数: 8

TA的精华主题

TA的得分主题

发表于 2019-2-2 22:00 | 显示全部楼层
打卡很麻烦的,如果一个人同一天打卡多次,但都是上班打卡,没有一次下班打卡。首次打卡后最后一次打卡记录下来也和实际应用不搭边。而且工时总得有个计算规则,总不能最后打卡-首次打卡吧,那可能两次打卡间隔几秒钟,因为没有下班打卡嘛,没有规则那只能空着了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-3-17 09:54 | 显示全部楼层
一把小刀闯天下 发表于 2019-2-2 15:01
哈哈哈,你哪只眼睛看到我用了字典,笑死!

哈哈,我是小白啊,感觉你写的这个跟字典很像 就以为是字典咯
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-27 11:18 , Processed in 0.037140 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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