Excel VBA 7.18 Excel标头顺序不一致的多工作薄如何合并?
这个也是小伙伴们在阅读了之前的文章之后提出的问题,之前我们分享了将多个规范的工作薄数据合并在一个工作表的操作的方法,本来也没有想过特殊的数据需求里面会有数据表头顺序不一致的情况,不过既然小伙伴们已经提出了这样的场景需求,那证明还是有可能会碰到的,我今天就针对这个情况在分享下我自己的解法
场景模拟
我们这里还是那之前的数据作为一个模拟参考对象
A班是标准格式
B班我们将python的成绩移动到第二列
C班我们将姓名移动到最后一列
还有其他的工作薄的顺序就不更改了,只要更改了一个工作薄的的所有的工作表的顺序,也能够代表表头顺序不同的情况了,来上代码
代码区
我们今天直接用数组的写法吧,因为小伙伴们表示数据可能会比较大,所以我们用数组吧,数组能够实现一次写入,避免了多次写入导致卡顿的情况出现
Sub test()
Dim rng As Range, sth As Worksheet, arr(), book As Workbook
Application.DisplayAlerts = False
Set book = ActiveWorkbook
Set rng = Application.InputBox("请选择要合并的列名", "表头的确定", , , , , , 8)
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = -1 Then
pathn = .SelectedItems(1)
End If
End With
f = Dir(pathn & "\")
Do While f <> ""
Workbooks.Open pathn & "\" & f
For Each sth In Worksheets
l = Cells(Rows.Count, 1).End(xlUp).Row
On Error Resume Next
maxl = UBound(arr, 2)
k = 0
For Each a In rng
k = k + 1
num = a.Column
ReDim Preserve arr(1 To rng.Columns.Count, 1 To maxl + l - 1)
For i = 2 To l
j = j + 1
arr(k, j) = sth.Cells(i, num)
Next i
If k <> rng.Columns.Count Then
j = maxl
End If
Next a
Next sth
If ActiveWorkbook.Name <> book.Name Then
ActiveWorkbook.Close False
End If
f = Dir()
Loop
book.Worksheets(1).Cells(2, 1).Resize(UBound(arr, 2), rng.Columns.Count) = WorksheetFunction.Transpose(arr)
End Sub
来看看操作步骤
依然实现选择合适的文件夹
然后程序就会自动执行合并操作,看看最后的结果
依然是非常的整齐,表头就算是顺序不一致,依然可以成功的按照正确的表头来合并数据
代码分析
其实今天的代码就比较的简单了,因为基本上都是前面学习过的知识点,我就来简单的说下代码实现的原理和步骤吧
If k = 1 Then
sth.UsedRange.Copy tsth.Cells(1, 1)
arr = tsth.UsedRange.Rows(1)
首先我们通过遍历循环文件夹的方式打开第一个工作薄,然后如果是第一个操作的话呢,我们会将当前的工作表的所有已用区域全部直接复制到新建的工作表中
为什么要这样操作呢,因为在这样的话,我们就有了一个表头对不对,这个表头就是我们后面复制的参照物了。
然后就是简单的循环,然后利用数组的方式保存数据了,当然相对于上一节的代码,这里又有一点不同了,因为上节我们是第一次就开始就开始使用数组了,有明确的参照物
而本次是第二次才开始使用的,所以数组的构造上面就需要花费一点功夫了。这里又回到了7-15讲述的最大下标的问题了,
大家首先要有一个逻辑概念,就是我们构造的数组是一个多维数组,多行多列的,那么有多少行,多少列呢?
首先列数是确定的,因为是根据表头来确定的,表头是多少列,那么就是多少列了,所以这个列数我们可以直接确定了
1 To UBound(arr1, 2),就是确定数组的列数了
然后确定行数,行数是根据我们统计的工作表的数据来确定的,怎么确定呢?当前数组的最大小标+当前工作表总共有多少行,代码就出来了。
1 To l + Count - 1,l是当前工作表的总行数,count是当前数组的最大小标,因为后续不需要汇总表头这一行了,所以要-1
合起来就是最终获得动态数组的代码了。
ReDim Preserve arrt(1 To UBound(arr1, 2), 1 To l + Count - 1)
本节换了一种说法,不知道大家会不会理解的更加清楚一点~~
如果大家确实比较难理解的话,可以像这样子,通过断点+调试的方式来关注每次数组的变化情况,慢慢的理论数组的运用
最后就是直接将数组整体写入我们新建的工作表中,得到我们想要的结果了。
好了~明晚19:00,准时再见。