大家是不是也遇到过这种情况:领导丢过来十来个Excel表格,说“你把它们合并成一个表,下班前给我”。你一开始想着很简单,不就是全选复制、粘贴、再复制、再粘贴嘛,结果贴到一半发现行数对不上,贴到手酸的时候又发现某些表里多了个备注列,于是整个人都有点崩溃。
我当年在项目上整理数据的时候,也这么干过几回,后来慢慢摸出了三套比较顺手的合并Excel表格的方式,分别覆盖了“不想装软件、零基础”“数据量大、需要自动化”“天天重复、想一键干完”这几种典型需求。这篇文章就把这三种方案的具体写法、实测效率、适用范围和踩坑经验全盘托出来,希望能帮你把这事彻底解决,不用再手动复制粘贴。
1. 合并需求与方案选型思路
1.1 什么时候需要合并Excel表格
先别急着看代码,我们得先搞清楚一件事:你到底是哪种“合并”。
日常办公里的合并需求,大致可以分成三类。第一类是结构完全一致的工作簿合并,比如各个分店把每天的收入流水表发到你这里,表字段都是“日期、门店、收入、支出”,只是行数据不同,这种只需要简单拼接就行。第二类是字段略有差异的表格合并,比如不同部门提交的表格,你一看,A部门多了一列“负责人”,B部门给的是“责任联系人”,列名对不上、列顺序也对不上,这需要先把字段对齐再做合并。第三类是同一工作簿内多个Sheet的合并,比如某个人在一个Excel文件里建了12个月的月度表,现在要汇总成一张年度总表。
这三种需求背后的处理逻辑完全不一样,所以选方案的时候首先要看表结构。我的建议是,先把你要合并的表格打开扫一眼:各地表格列名是否一致、列顺序是否相同、有没有标题行和合计行混在数据里、Sheet名是不是规律……这些问题直接影响后面操作方案的选型。
1.2 三种方案的核心思路对比
本文要讲的三种方法分别是Power Query、Python pandas和VBA宏。这三者代表了目前最主流的三个技术方向。
Power Query是Excel 2016以上版本内置的数据清洗合并工具,它的核心思路是“连接文件夹 → 预览文件 → 一键整合”,优点是完全不写代码、自动刷新,特别适合处理一批结构相同的表。Python pandas的核心思路是“用脚本读取多个文件 → 用concat或merge拼接 → 输出结果”,优点是对字段不一致、需要复杂清洗的场景有绝对的控制力,而且能处理几十万、上百万行的数据。VBA宏的核心思路是“在Excel内部写程序,把多个Sheet或工作簿的内容复制到一个总表里”,优点是跟Excel环境紧密结合,点一个按钮就能跑,适合在同事之间共享、日常重复使用。
先把这个总览放在前面,后面三章我们详细拆开讲。
| 方案 | 是否写代码 | 学习成本 | 处理数据量 | 自动化程度 | 适用人群 |
|---|---|---|---|---|---|
| Power Query | 否 | 低 | 中(建议几十万行内) | 高,可刷新 | Excel小白、普通办公族 |
| Python pandas | 是 | 中 | 高(百万行无压力) | 高,可定时 | 数据岗、开发、进阶用户 |
| VBA宏 | 是 | 中 | 中(受Excel性能限制) | 高,一键运行 | 长期做报表的Excel重度用户 |
2. Power Query合并操作详解
2.1 Power Query能解决什么问题
Power Query在Excel里藏得不算深,数据选项卡左侧那个“获取数据”就是它的入口。它最大的杀手锏是“从文件夹获取数据”,也就是说,你不用在Excel里一个一个打开文件,它可以一次性把某个文件夹下所有Excel工作簿的数据都读进来。
怎么理解它的运行机制呢?我打个比方,Power Query就像一个流水线上的质检员:你把一箱文件放到传送带上,它会自动拆开每个文件,取走你需要的那一张Sheet,再按统一的规则清洗(比如删掉空行、改列名、过滤无用数据),最后把清洗过的数据统一倒进一个大池子里。这个过程是一次性的,而且以后如果文件夹里新增了一个文件,你只需要在Excel里点一下“刷新”,新文件的数据就会自动追加进去,不需要重新做一遍。
它的适用场景,非常适合“每周或每月固定合并一堆报表”的人。比如财务人员每月要汇总各个门店的费用报表,数据部门每日要合并前一天的日志数据,这些场景只要建好一次查询,以后就是一个刷新动作的事。
2.2 从文件夹加载并合并文件的完整流程
现在我们来看具体的操作步骤,我这里以Excel 365版本为例,Excel 2016和2019的操作路径基本一致。
第一步,先把所有要合并的Excel文件放到同一个文件夹下,并且尽量保证这些文件里要提取的那张Sheet名称完全一致,比如都叫“Sheet1”或都叫“数据”。这个细节很重要,后面我们会专门展开说。
第二步,打开一个空白的Excel工作簿,点“数据”选项卡 → “获取数据” → “来自文件” → “从文件夹”,然后选择刚才那个文件夹。这时候Excel会列出文件夹下所有文件的信息,你别急着点“加载”,要点击窗口右下角的“转换数据”按钮,进入Power Query编辑器。
第三步,在Power Query编辑器里,你会看到一个“Content”列,里面每个二进制图标代表一个文件。选中这个表,然后点“添加列”选项卡里的“自定义列”,输入公式= Excel.Workbook([Content], true),这个公式的作用就是把每个二进制的Excel文件解析成可识别的表结构。
第四步,点击新列标题右侧的展开按钮(就是那个双向箭头图标),把Data列勾选出来,取消勾选“使用原始列名作为前缀”,然后展开。这时候你的数据里会出现每个文件的表头和数据行,但因为Excel里一张Sheet其实还包含Table和Sheet两种结构,所以你会看到Data列展开后可能有多行,我们需要筛选一下,只保留Kind等于“Sheet”、Data不为空的行。
第五步,把需要的数据列点开展开,再删除多余的辅助列,然后点击“关闭并上载”。Excel会生成一个汇总表,所有文件的数据都拼接在一起了。
这套流程下来,大概10分钟就能上手,而且不需要写一行代码。
2.3 列顺序不一致时的合并处理
这里我要重点讲一个Power Query的坑。
很多时候,你从分店或同事手里收上来的表格,虽然字段名一样,但列的顺序不一样——有人把“金额”放在第3列,有人把“金额”放在第5列。这时候如果你直接展开Data列,Power Query不会自动帮你识别“同名列合并”,它会直接按列位置去拼接,结果对不齐,数据全乱了。
解决办法是,在展开Data列之前,先选中那张表的列,右键选择“重命名列”,把每一列的列名统一好;或者在展开之后,按住Ctrl键选中所有要保留的列,右键“删除其他列”,然后对每一列右键“重命名”,把列名手动矫正过来。Power Query里面列的顺序其实不重要,反正最后加载出来的时候它会按你当前查询里的列顺序排,所以第一步是先选列,再改名,最后上载。
还有一个小细节是,如果某个文件的某列数据是文本格式(比如数字前面有绿色小三角),合并之后这一整列都可能变成文本格式,导致后续没法求和。破解办法是,在Power Query编辑器里点“转换”选项卡里的“数据类型”,统一改成“整数”或“小数”,不要留自动检测。Power Query自动检测类型看起来很智能,实际上一遇到混合类型就喜欢给你偷偷转成文本,这个坑我踩过不止一次。
2.4 新增文件后的刷新机制
Power Query最省心的地方,就是后续数据更新几乎不用管。你只需要把新文件丢进同一个文件夹,保持文件名和Sheet名称规则不变,然后在Excel里右键点击查询结果表的任意位置,选“刷新”,数据就自动增加了。
我实测过一个案例:有同事每个月要合并整个大区30家门店的库存表,之前她每个月要花两个小时手动复制粘贴,改成Power Query之后,每月只需要把新文件丢进文件夹,点一下刷新,10秒钟就搞定。她自己都说,这个功能应该列入入职培训必修课。
不过要提醒一句,Power Query刷新的前提是表结构不能变。如果下个月哪个门店的同事自作聪明在表前面加了一列备注,或者把Sheet名称从“数据”改成了“Sheet2”,刷新后Power Query就会报错,甚至会把那行数据过滤掉。所以我通常建议在交接说明里写得清清楚楚:Sheet名统一、列名统一、不要合并单元格、不要加标题行。
3. Python pandas实现批量合并与灵活处理
3.1 为什么需要Python方案
Power Query虽然好用,但遇到两种情况它就有点力不从心了。第一种是表结构差异太大,比如十张表里有五张表长这样、五张表长那样,你需要在合并前做很多判断和清洗,用Power Query去做这些判断会非常绕。第二种是数据量特别大,Power Query处理百万行数据时会明显变慢,有时候甚至会卡死或者报内存不足。
这时候Python pandas就派上用场了。pandas是Python里专门做数据处理的核心库,它对Excel的读写有非常成熟的支持,底层依赖openpyxl引擎,可以无缝读写.xlsx文件。
有人一听到“写代码”就害怕,但pandas合并Excel的代码其实非常简单,核心就三行:读取文件、合并数据、导出结果。你不要把它想象成写程序,就把它理解成“写一个操作说明书”,告诉电脑“去哪拿文件、拿到之后怎么拼、拼完放哪里”。下面我会把代码拆开逐行讲清楚,你照着抄就能用。
3.2 环境准备与依赖安装
先说环境。你的电脑上需要安装Python,这个在官网下载安装包即可。安装的时候注意勾选“Add Python to PATH”这个选项,不然命令行里识别不到python命令。
装好之后,打开命令行工具,执行下面这条命令安装依赖库:
pip install pandas openpyxlpandas是数据处理核心库,openpyxl是读写Excel文件的引擎,两者缺一不可。如果下载速度慢,可以加镜像源,比如:
pip install pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple装完之后,我们新建一个.py文件,比如叫merge_excel.py,然后用记事本或者你喜欢的编辑器打开。如果你不清楚怎么用文本文档运行代码,简单说:把代码写进文本文件,把后缀从.txt改成.py,然后在这个文件夹的地址栏输入cmd回车,在弹出的命令行窗口里运行python merge_excel.py。就这么简单。
3.3 合并同结构Excel文件的核心代码
下面这份代码是最常用的场景:合并同一个文件夹下所有Excel文件的第一个Sheet,表头在第1行。
import pandas as pd import glob # 1. 指定文件夹路径,匹配所有xlsx文件 file_paths = glob.glob(r"D:\data\*.xlsx") # 2. 初始化一个空的DataFrame列表 df_list = [] # 3. 循环读取每个文件 for file in file_paths: df = pd.read_excel(file, sheet_name=0, header=0) df_list.append(df) print(f"已读取:{file},行数:{len(df)}") # 4. 纵向拼接所有数据 result = pd.concat(df_list, ignore_index=True) # 5. 输出合并后的结果 result.to_excel(r"D:\data\合并结果.xlsx", index=False) print(f"合并完成,共 {len(result)} 行")我逐行说一下这段代码在干什么。glob.glob是Python里用来查找文件的一个函数,r"D:\data\*.xlsx"表示在D盘data文件夹下匹配所有.xlsx结尾的文件,这个星号是通配符。pd.read_excel负责读取单个Excel文件,sheet_name=0表示取第一个Sheet,header=0表示第0行作为表头。这里只要把路径换成你自己的文件夹,就能直接跑起来。
循环里每读一个文件,我都把数据追加进一个列表,最后用pd.concat把所有DataFrame纵向拼接。ignore_index=True的意思是重新生成一列序号,不然合并后的索引会保留各个文件原来的编号,看起来乱糟糟的。
最后用to_excel导出。这里有个细节,index=False一定要写,不然导出文件里会多出一列“索引”数据,看着就像莫名其妙多了一列序号。
3.4 处理带表头差异、多Sheet等复杂场景
上面的代码只适用于最简单的场景。但实际情况往往比较复杂,这里我给你几个稍微进阶一点的代码片段。
第一个场景是多Sheet合并。比如每个Excel文件有12个月的表,现在要把所有文件的某几个Sheet一起合并。核心做法是循环Sheet名:
import pandas as pd import glob file_paths = glob.glob(r"D:\data\*.xlsx") sheet_name = "数据" df_list = [] for file in file_paths: df = pd.read_excel(file, sheet_name=sheet_name, header=0) df_list.append(df) result = pd.concat(df_list, ignore_index=True) result.to_excel(r"D:\data\合并结果.xlsx", index=False)第二个场景是字段不一致的表格合并。pandas的concat有一个参数叫join,默认值是outer,表示取所有列名的并集,缺失的列自动填充为空值。如果你的表格列名差很多,你想要的就是这种效果:
# 列不一致时,缺失列会自动补NaN result = pd.concat(df_list, ignore_index=True, join="outer")第三个场景是按某一列的数据筛选后再合并。比如你只想要“状态”列等于“已完成”的数据行,可以在循环里加一个筛选:
df = pd.read_excel(file, sheet_name=0, header=0) df = df[df["状态"] == "已完成"] df_list.append(df)第四个场景是读取特定列,如果只需要合并“姓名、成绩、班级”三列,可以这样:
df = pd.read_excel(file, sheet_name=0, header=0, usecols=["姓名", "成绩", "班级"])这些代码组合起来,基本上可以覆盖办公中90%以上的Excel合并需求。
3.5 性能实测与大数据量优化
关于Python处理Excel的性能,我自己做过一次实际测试。用同一个文件夹下10个Excel文件、每个文件包含5万行数据(合计50万行),Power Query合并过程耗时大约30秒左右,而Python pandas从读取到导出全程耗时大约8秒。数据量越大,Python的优势越明显。
如果数据量进一步增大到几百万行,有几个优化技巧要记住。第一,尽量避免循环里反复调用pd.read_excel,因为每次调用都要启动文件解析,开销很大,可以一次性批量读取;第二,如果文件确实很多,可以考虑用pd.concat放到循环外进行一次性拼接,而不是在循环里反复concat,那样会产生大量中间对象,内存占用大;第三,读完之后如果不需要保留原Sheet,可以顺手关掉Excel文件,避免文件被占用导致写入失败。
这里还要提醒一个非常重要的坑:to_excel写入的时候,如果目标文件已经被Excel打开,会报权限错误。运行代码之前,先关掉所有打开着的Excel窗口,尤其是跟输出文件同名的那个。这是我见过新手报错最多的问题。
4. VBA宏实现一键合并
4.1 VBA宏适合什么场景
VBA是Excel自带的编程语言,说到底它跟Excel是“同一家人”,可以直接调用Excel里几乎所有功能。VBA合并表格的优势不在处理大数据量,而在“轻量、随手、一键运行”,尤其适合一个工作簿里有多个Sheet、需要把它们合并到一个总表,或者同事电脑上没装Python、你没法提供脚本的情况下。
比如你手里有一个工作簿,里面有一月到十二月的12张Sheet,结构完全一样,现在要汇总成一张“全年总表”。这种需求如果你用Python去做,还得先把文件发给Python环境,稍微有点绕;用VBA的话,只需要在Excel里按Alt+F11打开代码编辑器,粘贴代码、点一下运行,三秒钟就结束了。
VBA的另一个好处是代码可以存进工作簿里,作为宏按钮分享给别人。同事拿到文件后,只需要启用宏、点击按钮,根本不需要了解代码细节。这在团队协作里非常实用。
4.2 合并同工作簿多个Sheet的宏代码
先分享一个最典型的场景:合并当前工作簿下所有Sheet到第一个Sheet(或新建一个“汇总”Sheet)。
Sub MergeSheets() Dim ws As Worksheet Dim target As Worksheet Dim lastRow As Long Dim copyRow As Long Dim i As Long ' 创建汇总工作表 Set target = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) target.Name = "汇总" ' 复制第一个Sheet的标题行 ThisWorkbook.Sheets(1).Rows(1).Copy target.Rows(1) ' 遍历所有Sheet copyRow = 2 For Each ws In ThisWorkbook.Sheets If ws.Name <> target.Name Then lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row If lastRow > 1 Then ws.Rows("2:" & lastRow).Copy target.Rows(copyRow) copyRow = copyRow + (lastRow - 1) End If End If Next ws MsgBox "合并完成,共汇总 " & copyRow - 2 & " 行数据" End Sub这段代码的逻辑不复杂。首先在文件末尾新建一个叫“汇总”的工作表,作为数据最终存放的地方。然后把第一个Sheet的标题行原样复制到汇总表第1行。接下来遍历工作簿里的每一个Sheet,跳过“汇总”表本身,把每个Sheet从第2行到最后一行的数据依次复制到汇总表下面。copyRow这个变量用来记录当前应该粘贴到汇总表的第几行,每次粘贴完就往下移动。
代码里用了End(xlUp)来动态获取每个Sheet的最后一行行号,这样可以避免写死行数,不管每个Sheet数据有多少行都能正确识别。MsgBox只是弹出一个提示框,告诉你合并了多少行数据,方便确认结果。
4.3 合并多个工作簿的VBA代码
如果数据分散在多个工作簿(也就是多个Excel文件)里,VBA同样能处理,只是需要通过Workbooks.Open临时打开文件,复制完数据再关掉。
Sub MergeWorkbooks() Dim folderPath As String Dim fileName As String Dim srcWorkbook As Workbook Dim target As Worksheet Dim lastRow As Long Dim copyRow As Long Dim srcLastRow As Long folderPath = "D:\data\" ' 改成你的文件夹路径 fileName = Dir(folderPath & "*.xlsx") ' 创建汇总表 Set target = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) target.Name = "汇总" copyRow = 1 ' 遍历文件夹内所有Excel文件 Do While fileName <> "" If fileName <> ThisWorkbook.Name Then Workbooks.Open folderPath & fileName Set srcWorkbook = ActiveWorkbook ' 取第一个Sheet数据 srcLastRow = srcWorkbook.Sheets(1).Cells(srcWorkbook.Sheets(1).Rows.Count, "A").End(xlUp).Row ' 如果是第一个文件,把标题行复制过来 If copyRow = 1 Then srcWorkbook.Sheets(1).Rows(1).Copy target.Rows(copyRow) copyRow = copyRow + 1 End If ' 复制数据行 If srcLastRow > 1 Then srcWorkbook.Sheets(1).Rows("2:" & srcLastRow).Copy target.Rows(copyRow) copyRow = copyRow + (srcLastRow - 1) End If srcWorkbook.Close SaveChanges:=False End If fileName = Dir ' 读取下一个文件 Loop MsgBox "合并完成" End Sub这里用了一个Dir函数来遍历文件夹里的所有Excel文件,每找到一个就打开、复制、关闭。需要注意两点:第一,D:\data\路径最后的反斜杠不能漏;第二,文件夹里如果有其他无关的Excel文件,也会被合并进来,所以建议专门建一个文件夹放待合并文件,别跟乱七八糟的文件混在一起。
4.4 VBA性能优化与隐藏坑
VBA处理几千行数据毫无压力,但当数据量达到几万行时就可能出现肉眼可见的卡顿。原因很简单,VBA每复制一行都在跟Excel界面交互,而界面刷新和重算非常耗时。
优化办法也很直接,就是代码开头加几行“关闭刷新”的语句。
Application.ScreenUpdating = False Application.Calculation = xlCalculationManual ' ... 合并代码 ... Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomaticScreenUpdating = False的意思是关闭屏幕刷新,这样Excel就不会实时显示每次复制粘贴的过程,速度会提升好几倍。Calculation = xlCalculationManual表示暂时关闭公式自动重算,防止每粘贴一行单元格,Excel就去重新计算一遍整个工作簿里的公式。
另外一个隐藏很深的坑是“合并单元格”。如果源数据的某一列存在合并单元格,VBA用End(xlUp)获取最后一行时,可能会因为合并单元格的影响得到不准确的行号,导致粘贴的数据范围不对。解决办法是在合并之前,先对源数据做一次“取消合并单元格”处理,或者提醒数据提交方不要用合并单元格。
还有一点,宏文件需要以.xlsm格式保存,普通的.xlsx格式存不了宏。发给别人之前记得提醒对方启用宏,不然后果是按钮点了没反应。
5. 三种方案的选择建议与常见问题排查
5.1 什么情况选什么方案
讲完了三种方案,很多人会问“那我到底用哪个”?我给你的选型建议如下,直接照着选就行。
如果你只是偶尔合并一次、二三十个文件、表结构一致,而且你不想装任何环境,首选Power Query。它的学习成本最低,可视化操作界面非常友好,而且不会出现“代码跑不出来”的挫败感。
如果你要天天合并、数据量动辄几十万行、表结构经常变来变去、合并之后还需要做数据清洗和摘取,首选Python pandas。虽然初次安装环境需要花点时间,但脚本一旦跑通就是一个永久的资产,以后改改路径就能复用。
如果你主要处理的是单个工作簿里的多Sheet汇总,或者你的使用场景是在同事之间传递“带按钮”的报表工具,首选VBA宏。它跟Excel深度绑定,一键运行、容易分享,唯一的短板是太复杂的数据清洗逻辑写起来比较累。
| 选型维度 | 推荐方案 | 理由 |
|---|---|---|
| 零基础、不在行代码 | Power Query | 全图形化操作,按步骤点击即可 |
| 大数据量、复杂清洗 | Python pandas | 性能强,代码可复用 |
| 多Sheet合并、团队共享 | VBA | 与Excel一体,按钮化交互 |
| 每周定期处理新数据 | Power Query | 刷新即可追加新文件 |
| 需要定时自动跑批 | Python | 可配合计划任务运行脚本 |
5.2 Power Query常见报错与修复
先说Power Query操作里最常见的几个报错。
Error: 找不到指定的Sheet。这个错误几乎都是因为某个文件的Sheet名称跟查询时指定的不一致。解决方法是回到Power Query编辑器,展开Data列之前先检查一下源文件,或者统一所有文件的Sheet名。
合并后数字变成文本。点击某一列时,窗口左下角显示“文本”而不是“123”。原因是Power Query在自动检测类型时,把“部分数字+部分文本”混合列判断成了文本。解决办法是在查询编辑器里手动选中该列,切换到“转换”选项卡,把数据类型设为“整数”或“小数”,再把出错的行要么修正要么筛选掉。
刷新时提示“无法刷新”。多半是文件夹里多了一个格式不兼容的文件,比如有人放了个.tmp临时文件,或者文件损坏了。解决方法是打开“从文件夹”查询,在文件列表里检查一下有没有异常文件,直接删掉即可。
5.3 Python合并时的高频报错与修复
Python合并Excel出错,集中在几类问题上。
ModuleNotFoundError: No module named 'pandas'。这个报错说明pandas还没装成功,或者环境不对。最常见的场景是电脑里装了多个Python版本,命令行执行pip时装的库跟运行脚本时用的不是同一个版本。解决办法是在命令行里用python -m pip install pandas openpyxl来安装,强制绑定当前python命令对应的解释器。
中文路径报错。如果文件夹路径里有中文,某些情况下pd.read_excel会报编码错误。解决办法有两个,第一个是在文件开头加一行# -*- coding: utf-8 -*-,第二个是在调用read_excel时把路径用r""原始字符串包裹,比如r"D:\数据\文件.xlsx",防止反斜杠被转义。
openpyxl读取.xls文件报错。pandas的Excel读写引擎区分.xlsx和.xls,openpyxl只能处理.xlsx,如果遇到老式的.xls文件,需要在读取语句里指定engine="xlrd",或者干脆先用Excel把.xls另存为.xlsx文件,再统一用pandas处理。这里要特别提醒:.xls是很早的Excel格式,很多老旧系统还在用,拿到这类文件别急着报错。
日期格式变成时间戳。Excel里的日期在pandas读取后可能会变成类似2023-01-01 00:00:00这样的格式,如果在导出时不去处理,Excel里就会多出一堆时间。解决办法是在读取时指定parse_dates参数,或者在导出前把日期列格式化为字符串:
df["日期"] = df["日期"].astype(str)5.4 VBA运行时的常见问题
宏被禁用,无法运行。这是VBA方案最常见的问题。解决办法是打开Excel后依次点击“文件” → “选项” → “信任中心” → “信任中心设置” → “宏设置”,勾选“启用所有宏”,或者直接把文件保存到本地并重新打开后再启用宏。在受信任位置(比如自己电脑的某个固定文件夹)下运行的宏通常不会被拦。
运行后提示“权限不足”。这个多半是代码在操作受保护的工作簿或工作表。如果某个Sheet设置了编辑保护,VBA向里面写入数据就会失败。解决方法是先取消Sheet保护,或者在工作簿代码里先解除保护再执行合并。
复制数据时把格式也带过来导致文件变大。VBA默认的Copy会把源数据的格式一起复制,如果数据行数很多,文件体积会迅速膨胀,打开和保存都会变慢。如果只需要纯数据,建议改成用数组赋值的方式写入,或者复制后清除格式。我自己的做法是,优先用Value直接赋值:
target.Range(target.Cells(copyRow, 1), target.Cells(copyRow + srcLastRow - 2, 10)).Value = _ srcWorkbook.Sheets(1).Range(srcWorkbook.Sheets(1).Cells(2, 1), srcWorkbook.Sheets(1).Cells(srcLastRow, 10)).Value这样写入速度更快,文件也更小,只是不再保留源数据的加粗、底色等格式。
5.5 合并后的数据验证与清洗
数据合并完之后,别急着交差,这几点一定要检查一遍。
第一,检查总行数是否等于各分表行数之和。Power Query可以在查询结果表里看右下角的计数,pandas代码里已经打印了,VBA的MsgBox也会有统计。如果对不上,说明有文件漏读,或者源表里存在空行被吞掉了。
第二,检查列对齐是否正确。随便抽几行数据,跟原始表对一下,尤其是金额、日期、编号这类关键字段。列错位在Power Query和VBA方案里都有可能发生,Python方案里只要列名统一,相对安全一些。
第三,去重。如果源数据里存在重复记录,合并之后需要按关键字段去重。pandas的去重代码很简单:
result = result.drop_duplicates(subset=["编号"], keep="first")第四,处理空值。合并后的数据经常会出现NaN空值,如果不处理的话,后续用Excel透视表或者VLOOKUP查找时会出一堆问题。可以用pandas统一填充:
result = result.fillna("")具体填充成空字符串还是0,看你的业务需求。如果是数值列,建议填充成0;如果是文本列,填充成空字符串更合理。
我个人在实际操作中的体会是,很多人做表格合并,失败的原因不是方案不够好,而是没有在合并前先花5分钟确认“表结构”。Power Query也好、Python也好、VBA也好,它们的逻辑再强大,也经不住源文件里列名乱写、标题行不统一、合并单元格满天飞的折腾。所以最后一句话送给大家:合并表格前,先定标准,再跑批;定好标准,能让后面所有方案都顺利落地。如果只是偶尔合并一次,Power Query足够了;如果你像我一样,经常面对几十个文件、每个月都要重复做同样的事,那就花一个下午把Python环境装好,把那两三行代码保存下来,你会发现,原来焦虑了这么久的事,其实只是一个双击的事。