Excel教程完整指南 从 Excel 教程开始,像驯兽师一样驾驭数据

VBA 数据清洗实战案例

所属主题:VBA 数据清洗 Excel 表格自动化脚本

执行前检查

$ 要完成: VBA 数据清洗是处理日常脏数据的核心技能,能把上班族几小时的手工修复工作压缩到几秒。本文围绕 VBA 数...
$ 适用范围: 数据整理

VBA 数据清洗是处理日常脏数据的核心技能,能把上班族几小时的手工修复工作压缩到几秒。本文围绕 VBA 数据清洗实战案例 提供可直接复制使用的代码拆解,以及最常踩坑的环节。

适用场景:你有一张销售表、员工表或日志表,里面混着文本型数字、前后空格、重复记录或者格式不一致的值时,用 VBA 比手工处理快得多。

入口位置:VBA 编辑器与模块添加

打开 VBA 编辑器最快路径:

  • Alt + F11 直接打开(Windows 下通用,适用 Excel 2007 至当前版本)
  • 如果功能区习惯用鼠标:开发工具 → Visual Basic

添加模块用于存放清洗代码:

  • 在 VBA 编辑器左侧工程资源管理器(Project Explorer)里,右键你的工作簿(通常是 VBAProject (YourWorkbookName.xlsm))→ 插入 → 模块。

每次开始清洗前建议先备份工作表——否则写错后需要 Ctrl+Z 来回退,VBA 里的 Ctrl+Z 只保留一次状态。

操作示例

示例数据集说明

假设工资表结构如下(可从第 2 行开始放数据,第 1 行为标题):

员工号 部门 销售金额 负责人
E001 南区 25400 张三
E002 北区 18900 李四
E003 东区 31200 王五
E004 西区 22300 赵六

表中存在四个常见坏数据情况:

  1. 一个单元格为空(某人销售数缺失)
  2. 一个单元格为文本型数字(以单引号开头录入,比如 '22300
  3. 一个重复的员工号(防止后续用 VLOOKUP 合拼时出 #N/A)
  4. 一个员工号前后带不可见空格(用户 Excel 从网页、ERP 导出拼接时的典型遗留问题

案例一:清理文本型数字并修复数据格式

Sub CleanTextNumbers()
    Dim ws As Worksheet
    Set ws = ActiveSheet
    
    ' 假设销售金额在 C 列,从第 2 行到第 100 行
    Dim i As Long
    For i = 2 To 100
        ' 检查单元格是否包含单引号前导(由Text导入引起)
        If Left(ws.Cells(i, 3).Text, 1) = "'" Or _
           VarType(ws.Cells(i, 3).Value) = vbString Then
            ws.Cells(i, 3).NumberFormat = "0"
            ws.Cells(i, 3).Value = Val(ws.Cells(i, 3).Value)
        End If
    Next i
End Sub

上面代码逐一检查从第 2 行到第 100 行第 3 列的单元格。VarType(ws.Cells(i,3).Value) = vbString 会判断该值是否被Excel认成文本——常见场景是从SAP或CRM导出的数字显示为「文本」单元格格式时触发。检查后使用 Val() 函数将其转成真正数值格式,数字原本没有变化,但后续公式(合计、透视)才可以正确引用。

预期结果:原本显示左上角绿色三角(错误指示器)的单元格消失,对该列求和时可正常汇总。

案例之二:移除员工号前后的空格

Sub TrimEmployeeIDs()
    Dim ws As Worksheet
    Set ws = ActiveSheet
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    
    ' 假设员工号在 A 列
    Dim i As Long
    For i = 2 To lastRow
        If InStr(ws.Cells(i, 1).Value, " ") > 0 Then
            ws.Cells(i, 1).Value = Trim(ws.Cells(i, 1).Value)
        End If
    Next i
End Sub

Trim 只能移除前后正常空格(ASCII 32)。部分系统使用不间断空格(ASCII 160或HTML实体  ),这种情况需要用 Replace(ws.Cells(i,1).Value, Chr(160), "") 额外处理一次,才能在VLOOKUP匹配时找到正确索引行。

案例之三:删除完全重复行

Sub RemoveDuplicateRows()
    Dim ws As Worksheet
    Set ws = ActiveSheet
    
    ' 选中数据区域全部列,指定第一列(员工号)为判断重复的依据列
    Dim rng As Range
    Set rng = ws.Range("A1").CurrentRegion
    
    ' 用RemoveDuplicates方法(Excel 2007+可行)
    rng.RemoveDuplicates Columns:=Array(1, 2, 3, 4), Header:=xlYes
End Sub

注意:RemoveDuplicates 是 Excel 原生方法,但只能针对整行判断是否完全一样,而不是只看单列。如果不同员工号的数据碰巧其余列完全一样,也会被删掉。稳妥做法是先排序再逐行比较关键列。

公式或快捷键示例(非 VBA 替代方案)

如果嫌 VBA 门槛高,以下三个手动方案可以快速复用:

目标 方法 路径 结果
文本型转数值 选中列 → 数据 → 分列 → 直接完成 Alt + A → E → 按两次 Enter 文本转为数值
去重 选中区域 → 数据 → 删除重复值 Alt → D → D 按所选列去重
清除前后空格 在新列用 =TRIM(A2) 填充,再粘贴为值 公式写完后 Ctrl+C → 右键粘贴为值 移除空格但要覆盖原列

表格中「分列」方法虽简单,但遇到值本身带单引号(比如文本中确实要保留撇号)时会误伤。更稳的做法是在 VBA 里额外加 If Not IsNumeric(ws.Cells(i,3).Value) Then 判断再决定是否转换。

常见错误

  • 忘记锁定数字格式:转完文本型数字后没设置 .NumberFormat = "0",导致数值显示正常但参与计算时出错。
  • 用相对引用而不是绝对 ws.Cells:循环时用 Range("C" & i) 够用,但容易在插入/删除行列后跑偏。
  • 只检查前导空格、没检查尾部和中间不可见字符:用 Trim 只能解决前一种,必须配合 ReplaceClean 处理回执符号。
  • 删除重复行前没备份:RemoveDuplicates 会直接删除,不可撤销(Ctrl+Z 也只能撤一步)。

常见问题

VBA 数据清洗实战案例 是什么?

用一个真实的数据表场景,逐步演示如何用 VBA 自动化完成文本型数字转换、空格清理、重复行删除等任务。这类案例强调从“脏数据”清洗到“可计算状态”的完整流程,而非只讲孤立语法点。

VBA 数据清洗实战案例 怎么操作?

以上面代码示例为起点:在模块中粘贴一个过程,按自己的实际列位置与数据范围调整循环变量和列索引,先用一个小样本(20行)测试,确认无误后延展到最后一行。

VBA 数据清洗实战案例 常见错误有哪些?

最经典的三个坑:处理前没有设置工作表的正确称呼(例如用了 Sheet1 而非 ActiveSheet 导致数据在原表未更新)、循环中忘记退出条件(死循环按 Esc 可中断)、以及将删除重复后的数据保存时覆盖原文件。每次运行前存一份 .xlsm 副本做保护。


延伸阅读:关于更高级的数据清洗自动化场景,可以参考[VBA 数据清洗](ilink:VBA 数据清洗)的系统实战讲解,以及数据整理中对比 VBA 与 Power Query 的适用边界。