Excel VBA优化需求:按ID保留最后一次Login记录并去重
优化VBA代码实现你的登录记录清理需求
我来帮你搞定这个问题!首先咱们明确核心需求:
- 只保留同时拥有Log in和Log out记录的ID(比如删除示例里的ID D)
- 对于有多次Log in的ID,仅保留最后一次Log in记录,同时保留对应的Log out
你的原代码只处理了相邻的重复登录记录,没实现保留最后一次登录的逻辑,也没筛选无登出的ID。下面是优化后的完整解决方案:
原始表格
| Id | Status | Date |
|---|---|---|
| A | Log in | 01.01.2018 01:44:03 |
| A | Log out | 01.01.2018 02:57:03 |
| C | Log in | 01.01.2018 01:55:03 |
| C | Log in | 01.01.2018 01:59:03 |
| C | Log in | 01.01.2018 01:59:03 |
| D | Log in | 01.01.2018 01:59:03 |
| E | Log in | 01.01.2018 01:59:03 |
| E | Log out | 01.01.2018 01:59:03 |
目标表格
| Id | Status | Date |
|---|---|---|
| A | Log in | 01.01.2018 01:44:03 |
| A | Log out | 01.01.2018 02:57:03 |
| E | Log in | 01.01.2018 01:59:03 |
| E | Log out | 01.01.2018 01:59:03 |
优化后的VBA代码
Sub CleanLoginLogoutRecords() Dim ws As Worksheet Dim lastRow As Long Dim idDict As Object Dim i As Long Dim currentId As String Dim currentStatus As String ' 设置当前工作表(可修改为指定工作表,比如Sheets("Sheet1")) Set ws = ActiveSheet ' 获取数据区域的最后一行 lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row ' 创建字典存储每个ID的关键信息:是否有Log out、最后一次Log in的行号 Set idDict = CreateObject("Scripting.Dictionary") ' 第一次循环:收集所有ID的状态信息 For i = 2 To lastRow currentId = ws.Cells(i, "A").Value currentStatus = ws.Cells(i, "B").Value ' 如果字典里没有这个ID,初始化条目 If Not idDict.Exists(currentId) Then idDict(currentId) = Array(False, 0) ' 数组元素:(是否有Log out, 最后登录行号) End If ' 更新ID的Log out状态 If currentStatus = "Log out" Then idDict(currentId) = Array(True, idDict(currentId)(1)) End If ' 更新ID的最后一次Log in行号 If currentStatus = "Log in" Then idDict(currentId) = Array(idDict(currentId)(0), i) End If Next i ' 第二次反向循环:删除不需要的行(反向循环避免行号错乱) Application.ScreenUpdating = False ' 关闭屏幕刷新提升效率 For i = lastRow To 2 Step -1 currentId = ws.Cells(i, "A").Value currentStatus = ws.Cells(i, "B").Value ' 情况1:该ID没有对应的Log out,直接删除整行 If Not idDict(currentId)(0) Then ws.Rows(i).Delete GoTo NextRow ' 跳过后续判断,处理下一行 End If ' 情况2:该ID有Log out,但当前行是重复的Log in(不是最后一次),删除该行 If currentStatus = "Log in" And i <> idDict(currentId)(1) Then ws.Rows(i).Delete End If NextRow: Next i Application.ScreenUpdating = True ' 恢复屏幕刷新 MsgBox "记录清理完成!", vbInformation End Sub
代码关键逻辑说明
- 字典的使用:用
Scripting.Dictionary高效存储每个ID的核心信息,避免重复遍历,提升效率 - 两次循环策略:
- 第一次正向循环:收集所有ID的登录/登出状态,记录每个ID的最后一次登录行号
- 第二次反向循环:从最后一行往第一行处理,避免删除行后导致后续行号错乱的问题
- 两种删除规则:
- 直接删除没有对应Log out的ID的所有行
- 删除重复的Log in记录,仅保留最后一次登录的行
使用方法
- 打开你的Excel文件,按下
Alt + F11打开VBA编辑器 - 右键点击左侧的工作簿名称,选择「插入」→「模块」
- 将上面的代码粘贴到模块中
- 返回Excel界面,按下
Alt + F8,选择CleanLoginLogoutRecords并点击「运行」
内容的提问来源于stack exchange,提问作者Catalin Vasilescu
相关产品推荐
相关产品推荐

