暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

VBA 字典 这样的考勤表该如何处理?

Excel VBA练习 2021-07-15
669

hello,小伙伴们,今天小编有收到小伙伴的留言,添加一些关于SQL+VBA的实操内容,这个等字典的写完会继续写一些关于SQL的例子


还是先刷下今天的例题吧

如下图所示



这是小编前段时间在群里捡到关于考勤的,由于小编并没做过人事相关的工作,也不知道这个是什么系统导出来的,看起来怪怪的..

整体来看,数据还是比较规范的,工号,名字,部门都固定在一个位置上,整理还算比较轻松的


先看整理效果吧



代码如下:


    Sub GetData(control As IRibbonControl)
    Dim aData
    Dim Dic As Object
    Dim intX&, intY&, intC&, x&
    Dim strTime$, strMaxTime$, strMinTime$, strID$, strName$, strGroup$, strDate
    Dim Sht As Worksheet, T
    On Error Resume Next
    T = Timer
    Set Dic = CreateObject("Scripting.Dictionary") '后期绑定字典
    aData = Worksheets("原始考勤").Range("A1").CurrentRegion '获取数据源
    Dic(0) = Array("姓名", "工号ID", "部门", "考勤日期", "上班时间", "下班时间") '字典的条目为一个6个元素的一维数组
    For intX = LBound(aData) To UBound(aData) '遍历数据源
    If aData(intX, 1) Like "工号*" Then '判断数据源中第1列是否包含工号
    strID = aData(intX, 3): strName = aData(intX, 11): strGroup = aData(intX, 18) '工号ID,姓名,部门赋值
    intX = intX + 2 '数据源行位置+2
    intC = intX '赋值
    Do '累加计算每个员工在数据源中占了多少行位置
    intC = intC + 1
    If intC > UBound(aData) Then Exit Do
    Loop Until aData(intC, 1) Like "工号*"
    intC = intC - 1
    For intY = 1 To UBound(aData, 2) '遍历数据源列
    strTime = "" '初始化
    For x = intX To intC '遍历循环每个员工在数据源中所有内容
    If aData(x, intY) <> "" Then
    strTime = strTime & aData(x, intY) '当不为空时连接字符
    End If
    Next
    If strTime <> "" Then
    strTime = Replace(strTime, Chr(10), "") '替换换行符
    strMinTime = Format(Left(strTime, 5), "hh:mm:ss") '获取左边5位字符,使用Format函数更改格式既上班时间
    If Len(strTime) > 5 Then
    strMaxTime = Format(Right(strTime, 5), "hh:mm:ss") '当字符长度超过5位时获取右边5位字符,既下班时间
    Else
    strMaxTime = ""
    End If
    strDate = "2021/5/" & intY '连接日期
    Dic(strID & intY) = Array(strName, strID, strGroup, strDate, strMinTime, strMaxTime)
    '关键使用员工ID+数据列位置作为Key,条目为一维数组,相关的元素包含了姓名,ID,部门,上下班时间,日期存入字典
    End If
    Next
                intX = intC'赋值循环行位置
    End If
    Next
    Set Sht = Worksheets("数据整理")
    If Err Then '发生错误代表不包含数据整理工作表
    Err.Clear
    With Sheets.Add(after:=Sheets(Sheets.Count)) '新建数据表
    .Name = "数据整理"
    End With
    Set Sht = Worksheets("数据整理")
    End If
    With Sht
    .Activate
    .Cells.Clear '为方便直接清空内容
    With .Range("a1").Resize(Dic.Count, 6)
    .Value = Application.Rept(Dic.items, 1) '使用Application.Rept输出字典中的Item
    .Borders.ColorIndex = 23 '添加边框
    .Columns.AutoFit '自适应列宽
    End With
    .Cells(2, 1).Select
    ActiveWindow.FreezePanes = True '冻结窗格
    ActiveWindow.DisplayGridlines = False '取消网格线
    End With
    Set Dic = Nothing '释放字典内存
    MsgBox "整理完毕,用时:" & Format(Timer - T, "0.000秒") '计算运行时长
    End Sub


    第12至44行遍历数据源

    第13行判断是否循环至包含工号的位置

    第17至20行获取每个员工在数据源中有多少行的内容

    第22至41行循环数据源中的列位置

    第24至28行循环每一列判断是否包含内容,有内容则连接成一个字符串

    第29至40行,如初始化字符串不为空,代表员工在该日期有考勤内容则获取上下班时间以及日期,并且写入字典中

    第45至52行判断是否有名称为数据整理的工作表,如没有则新建一个工作表,并且命名为数据整理

    第53至64输出内容,设置格式


    示例文件下载


    链接:https://pan.baidu.com/s/1vASyOAInYI8CAudQB3EKjg

    提取码:abcd



    收工!

    如果小伙伴有好的思路,可以在小编的公众号留言发给小编研究下

    文章觉得有用,点个赞+在看,你的每一次点赞和转发就是小编原创的动力

    关注公众号 ↓


    文章转载自Excel VBA练习,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论