上次我们讲到对单个工作簿内具有相同格式的所有工作表进行汇总,那对来自不同工作簿的数据怎么进行汇总呢?例如一个文件夹内有10个工作簿(workbook),每个工作簿里的第一个工作表(worksheet)存放了某个班不同学生的成绩(包括语文、数学、英语)。现在要将所有班级的学生成绩进行汇总。如果一个一个工作簿打开后进行手工复制会显得很麻烦。当这样工作簿过多时,更不可能用手工复制,此时怎么做才能更快完成工作呢?
例子
为了便于讲解,我们以汇总4个班的成绩为例,4个班的成绩来自不同的工作簿的第一个工作表。成绩如下图所示:
代码如下:
Sub 多工作簿汇总()
Dim item As Integer
Dim fn As String
Dim wb As Workbook
If Application.FileDialog(3).Show = -1 Then
fn = Application.FileDialog(3).SelectedItems(1)
Workbooks.Open fn
Set wb = ActiveWorkbook
wb.Worksheets(1).UsedRange.Copy ThisWorkbook.Worksheets(1).Cells(1)
Workbooks(wb.Name).Close
For item = 2 To Application.FileDialog(3).SelectedItems.Count
fn = Application.FileDialog(3).SelectedItems(item)
Workbooks.Open fn
Set wb = ActiveWorkbook
wb.Worksheets(1).UsedRange.Offset(1, 0).Copy ThisWorkbook.Worksheets(1).Cells(ThisWorkbook.Worksheets(1).Rows.Count, 1).End(xlUp).Offset(1, 0)
Workbooks(wb.Name).Close
Next item
End If
End Sub
打开一个新工作簿,运行上述代码后,程序会打开文件选择对话框,我们打开图1所示的文件夹,并选择要汇总的工作簿(共4个)后,点击确定会得到下图的汇总结果。
这些代码是怎么实现这一功能的呢?
首先讲解一下代码思路,多工作簿不同于单工作簿,我们需要选择一个装有所要汇总工作簿的文件夹,这就涉及到对文件夹的操作。打开文件后,我们需要循环文件夹下所有工作簿。所以我们要先知道工作簿的路径。最后通过路径打开工作簿,进行复制粘贴操作。
我们首先使用FileDialog函数来获取我们要汇总的所有工作簿的完整路径。FileDialog的使用方法如下:
Filedialog函数使用方法
功能:显示对话框,选择文件,获取指定路径
application.FileDialog(3).Show表示显示文件选择对话框,如果文件选择对话框中选择文件或文件夹后点击“确定”,则返回 -1,点击“取消”则返回0 。
用application.FileDialog(3).SelectedItems(i)表示第i个文件的完整路径
用application.FileDialog(3).SelectedItems.Count表示所选择的工作簿个数
接下来,我们来逐行看代码的意思
If Application.FileDialog(3).Show = -1 Then
执行代码
end if
这一部分表示如果我们选择文件中的工作簿后点击“确定”按钮则继续执行“执行代码”,如果点击“取消”就结束if语句。在我们的代码中如果结束了if语句,过程就结束了,不进行任何操作。
如果我们选择了文件,点击确定后,则执行下面的代码:
fn = Application.FileDialog(3).SelectedItems(1)表示将所选择的第一个工作簿的完整路径赋值给fn,fn是一个字符串,在使用前需要用dim fn as string进行声明。也可以用其它字母代替。
Workbooks.Open fn 表示打开fn指定的工作簿。
当我们打开代表某个班成绩的工作簿后,此时有两个打开的工作簿,还有一个是我们新建的存放代码的工作簿。为了区分这两个工作簿,我们使用Set wb = ActiveWorkbook 进行赋值,以后wb就代表我们打开的代表成绩的工作簿。在对wb进行赋值前,需要用dim wb as workbook对其声明,说明wb是一个工作簿,而不是字符串或者其它。
我们使用ThisWorkbook来代表代码所在的工作簿,也就是汇总工作簿。
wb.Worksheets(1).UsedRange.Copy ThisWorkbook.Worksheets(1).Cells(1)这一句就表示复制第一个工作簿的内容到代码所在工作簿的第一个单元格。如果有不明白的地方可以查看单工作簿多工作表汇总一文的相应部分。
wb代表我们打开的工作簿
wb.Name代表我们打开的工作簿的名称
Workbooks(wb.Name).Close表示关闭我们打开的代表成绩的工作簿。
要点:现在汇总工作表里有1班各个同学的成绩,以及第一行显示的变量名(姓名,语文,数学,英语)。在复制其它班级成绩的过程中,我们只需要复制各班成绩,而不要第一行。操作是相同的,所以我们使用循环来完成剩下的班级成绩汇总。
循环形式如下:
For item = 2 To Application.FileDialog(3).SelectedItems.Count
fn = Application.FileDialog(3).SelectedItems(item)
Workbooks.Open fn
Set wb = ActiveWorkbook
wb.Worksheets(1).UsedRange.Offset(1, 0).Copy ThisWorkbook.Worksheets(1).Cells(ThisWorkbook.Worksheets(1).Rows.Count, 1).End(xlUp).Offset(1, 0)
Workbooks(wb.Name).Close
Next item
我们使用item作为循环变量,同样使用前需要先声明。 我们用For item = 2 To Application.FileDialog(3).SelectedItems.Count从第2个开始循环到最后一个。其它代码的意思有不清楚的,结合前述和单工作簿多工作表汇总一文的说明进行理解。
总结
今天讲的是多个工作簿内单工作表的汇总模板。
想像一下,如果一个工作簿内有几个班的成绩分别放在不同的工作表中,并且这样的工作簿有多个时,应该怎样写代码呢?如果有兴趣,请看下次的讲解。
(本文为原创,未经允许,不得转载)