在网上找EXCEL多文件合并的方法,思路:

一、Linux 或者window+cmder,直接用命令行cat合并EXCEL文件,但是,需要安装辅助东西才能直接处理(也许也不可以,但是,可以用文件格式转换工具转换是可行的,把EXCEL文件转换成txt文件,再操作,操作好了,再转换成EXCEL格式);还有一种是perl或者Python有自己自带的EXCEL处理包,能像处理数组一样,实现直接处理EXCEL文件的目的

二、EXCEL自带VBA编程实现合并,但是,网上搜了很多,格式很类似的VBA脚本,都不能很完美的实现合并功能,都或多或少合并有不完整的现象,于是遇到下面的这个版本,可以很好正确的实现合并,就在此把脚本里边每条的功能给详细注释一下,如有不正确的地方,欢迎留言,感激不尽~

脚本:

Sub 合并目录所有工作簿全部工作表()

Dim MP, MN, AW, Wbn, wn               #定义变量(MP=MyPath,MN=MyName,AW=ActiveWorkbookName,Wbn=WorkBookName,wn=workbooksheet(i)name),但未指定变量类型,这样不是很规范

Dim Wb As Workbook                        #定义变量Wb为工作簿类型   #Dim Wbn As string,G As Long  #定义变量Wbn为字符型,G为长整型 #Dim Num,ini As Long #定义Num未声明类型,定义并声明ini为长整型

Dim i, a, b, d, c, e                               #定义变量,但未指定变量类型,这样不是很规范

Application.ScreenUpdating = False  #关闭屏幕刷新

MP = ActiveWorkbook.Path               #将当前工作簿(活动工作簿)的路径赋值给MP

MN = Dir(MP & "\" & "*.xls")               #将当前工作簿(活动工作簿)的路径加上\*.xls后缀,从而捕获到的*位置的所有文件名的值,Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。

AW = ActiveWorkbook.Name            #将当前工作簿(活动工作簿)的名字赋值给AW(不带后缀,只是名字)

Num = 0     #Num=0

e = 1           #ini=0

Do While MN <> ""                           #运行下面的DO while 循环,直到MN值为空值

  If MN <> AW Then                    #如果,MN值不等于AW值,就运行IF到END IF之间的判断语句

    Set Wb = Workbooks.Open(MP & "\" & MN)                #打开MP\路径下名为MN变量值的工作簿,并引用(Set的作用)赋给Wb  ##引用赋值如果,对Wb更改了,被引用的也随着更改了,详细见下边PS(3)

    a = a + 1                                                      #对a进行循环累加

    With Workbooks(1).ActiveSheet                                   #对已打开的所有工作簿中的第一个工作簿中的被激活的工作表运用with语句

      For i = 1 To Sheets.Count                    #在Workbooks(1).ActiveSheet的所有sheet中循环

        If Sheets(i).Range("a1") <> "" Then                #如果Wb工作簿的第i个工作表的A1单元格内容不为空,就进行IF判断内容,如果为空,跳过IF判断进入For的下一个循环

          Wb.Sheets(i).Range("a1").Resize(1, Sheets(i).UsedRange.Columns.Count).Copy  .Cells(1, 1)  #将wb工作簿中第i个工作表的A1单元格区域扩充为一行,有应用痕迹列数(x)大小的区域,即A1:x1区域,  扩充后区域内的内容复制到Workbooks(1).ActiveSheet的A1位置

          d = Wb.Sheets(i).UsedRange.Columns.Count     #wb工作簿的第i工作表有应用痕迹的列计数,并赋值给d

          c = Wb.Sheets(i).UsedRange.Rows.Count - 1     #wb工作簿的第i工作表有应用痕迹的行计数,并赋值给c

          wn = Wb.Sheets(i).Name            #wb工作簿的第i个工作表的名字赋值给wn

          .Cells(1, d + 1) = "表名"              #Workbooks(1).ActiveSheet工作表的第1行,第d+1列单元格填充“表名”字符串 
          .Cells(e + 1, d + 1).Resize(c, 1) = MN & wn    #Workbooks(1).ActiveSheet工作表的第e+1行,第d+1列区域扩充为c行,1列区域,并在该区域填充为MN & wn
          e = e + c                   
          Wb.Sheets(i).Range("a2").Resize(c, d).Copy   .Cells(.Range("a1048576").End(xlUp).Row + 1, 1)   #将区域内容,复制到Workbooks(1).ActiveSheet中,每次从Workbooks(1).ActiveSheet的最后一个非空行开始粘贴

        End If

      Next
      Wbn = Wbn & Chr(13) & Wb.Name                                         #将Wbn的值加上空格和Wb工作簿的名称后赋值给Wbn

      Wb.Close False                    #将Wb工作簿关闭
    End With
  End If
MN = Dir                             #获得上边Dir匹配到的下一次文件名;#Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。
Loop
Range("a1").Select                         #选中当前工作簿的第一个单元格
Application.ScreenUpdating = True                  #开启屏幕刷新
MsgBox "共合并了" & a & "个工作薄下全部工作表。如下:" & Chr(13) & Wbn, vbInformation, "提示"        #给出最后提示

End Sub

参考:https://www.jianshu.com/p/f52e6edc2d63

参考:https://zhinan.sogou.com/guide/detail/?id=1610003487  #将模块加入按钮(窗体控件)

注意:被合并的文件第一行都得是行标题,而且只保留被合并的第一个文件的第一行,没有行标题会出错,缺少数据;被合并的每个文件的A1单元格不能是空单元格,否则整个文件将不会别合并;

实例:

1文件是:

2文件是:

1、2是要合并的文件,3是新建的空文件;要放到一个目录文件夹下;

打开3文件,打开VBA,粘贴脚本保存,3文件保存为启用宏的格式文件;

运行宏;

结果展示:

说明:使用的话直接复制粘贴PPS下的脚本即可,把#更换为了符合VBA的注释格式‘

PS:

(1)Resize

使用Range对象的Resize属性调整指定区域的大小,并返回调整大小后的单元格区域,如下面的代码所示。
Sub Resize()
Sheet4.Range("A1").Resize(3, 3).Select   ‘意思就是把工作表4中的A1单元格扩充为3行3列大小的区域,结果为A1:C3区域
End Sub
代码解析:
Resize过程使用Range对象的Resize属性选中A1单元格扩展为三行三列后的区域。
Resize属性的语法如下:
expression.Resize(RowSize, ColumnSize)
参数expression是必需的,返回要调整大小的Range 对象
参数RowSize是可选的,新区域中的行数。如果省略该参数,则该区域中的行数保持不变。
参数ColumnSize是可选的,新区域中的列数。如果省略该参数。则该区域中的列数保持不变。

参考:http://www.excelpx.com/thread-174857-1-1.html

(2)Dir

这是一个用VBA函数Dir()构造的判断文件是否存在的自定义函数

Function FileExists(fname) As Boolean ' Returns TRUE if the file exists Dim x As String x = Dir(fname) If x <> "" Then FileExists = True _ Else FileExists = False End Function

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Dir 函数

返回一个 String,用以表示一个文件名、目录名或文件夹名称,它必须与指定的模式或文件属性、或磁盘卷标相匹配。

语法

Dir[(pathname[, attributes])]

Dir 函数的语法具有以下几个部分:

部分描述pathname可选参数。用来指定文件名的字符串表达式,可能包含目录或文件夹、以及驱动器。如果没有找到 pathname,则会返回零长度字符串 ("")。attributes可选参数。常数或数值表达式,其总和用来指定文件属性。如果省略,则会返回匹配 pathname 但不包含属性的文件。

设置值

attributes 参数的设置可为:

常数值描述vbNormal0(缺省) 指定没有属性的文件。vbReadOnly1指定无属性的只读文件vbHidden2指定无属性的隐藏文件VbSystem4指定无属性的系统文件 在Macintosh中不可用。vbVolume8指定卷标文件;如果指定了其它属性,则忽略vbVolume 在Macintosh中不可用。vbDirectory16指定无属性文件及其路径和文件夹。vbAlias64指定的文件名是别名,只在Macintosh上可用。

注意 这些常数是由 VBA 所指定的,在程序代码中的任何位置,可以使用这些常数来替换真正的数值。

说明

在 Microsoft Windows 中, Dir 支持多字符 (*) 和单字符 (?) 的通配符来指定多重文件。

在 Macintosh 中,这些字符作为合法文件名字符并且不能作为通配符来指定多个文件

由于 Macintosh 不支持通配符,使用文件类型指定文件组。可以使用 MacID 函数指定文件类型而不用文件名。比如,下列语句返回当前文件夹中第一个TEXT文件的名称:

Dir("SomePath", MacID("TEXT"))

为选中文件夹中所有文件,指定一空串:

Dir("")

在 Microsoft Windows 中,如果在Dir函数中使用MacID函数,将产生错误。

任何大于256的attribute值都被认为是MacID 函数的值。

在第一次调用 Dir 函数时,必须指定 pathname,否则会产生错误。如果也指定了文件属性,那么就必须包括 pathname

Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。不必访问到所有匹配当前 pathname 的文件名,就可以改变到一个新的 pathname 上。但是,不能以递归方式来调用 Dir 函数。以 vbDirectory 属性来调用 Dir 不能连续地返回子目录。

提示 由于文件名并不会以特别的次序来返回,所以可以将文件名存储在一个数组中,然后再对这个数组排序。

参考:http://club.excelhome.net/thread-121668-1-1.html

(3)Set

VBA中SET是定义一个有属性和方法的对象

Excel版本参考:2010
1、语法 Set objectvar = {[New]
objectexpression | Nothing} Set 语句的语法包含下面部分: 描述 objectvar
必需的。变量或属性的名称,遵循标准变量命名约定。 New
可选的。通常在声明时使用 New,以便可以隐式创建对象。如果 New 与
Set 一起使用,则将创建该类的一个新实例。如果
objectvar 包含了一个对象引用,则在赋新值时释放该引用。不能使用 New 关键字来创建任何内部数据类型的新实例,也不能创建从属对象。 objectexpression
必需的。由对象名,所声明的相同对象类型的其它变量,或者返回相同对象类型的函数或方法所组成的表达式。 Nothing
可选的。断绝 objectvar 与任何指定对象的关联。若没有其它变量指向
objectvar 原来所引用的对象,将其赋为 Nothing 会释放该对象所关联的所有系统及内存资源。
2、说明: 为确保合法,objectvar 必须是与所赋对象相一致的对象类型。 Dim、Private、Public、ReDim以及 Static 语句都只声明了引用对象的变量。在用
Set 语句将变量赋为特定对象之前,该变量并没有引用任何实际的对象。 下面的示例说明了如何使用 Dim 来声明 Form1 类型的数组。Form1 实际上还没有实例。然后使用
Set 将新创建的 Form1 的实例的引用赋给 myChildForms 变量。在 MDI
应用程序中可以使用这些代码来创建子窗体。
Dim myChildForms(1 to 4) As Form1
Set myChildForms(1) = New Form1
Set myChildForms(2) = New Form1
Set myChildForms(3) = New Form1
Set myChildForms(4) = New Form1 通常,当使用 Set 将一个对象引用赋给变量时,并不是为该变量创建该对象的一份副本,而是创建该对象的一个引用。可以有多个对象变量引用同一个对象。因为这些变量只是该对象的引用,而不是对象的副本,因此对该对象的任何改动都会反应到所有引用该对象的变量。不过,如果在
Set 语句中使用 New 关键字,那么实际上就会新建一个该对象的实例。
3、Set 语句示例 该示例使用 Set 语句将对象引用赋给变量。假定 YourObject 指向一个具有 Text
属性的合法对象。
Dim YourObject, MyObject, MyStr
Set MyObject = YourObject '对象引用赋值。
'MyObject 和 YourObject 引用同一个对象。
YourObject.Text = "Hello World" '初始化属性。
MyStr = MyObject.Text '返回 "Hello World"。
'脱离关联。MyObject 不再引用 YourObject。
Set MyObject = Nothing '释放该对象。
 参考:https://wenwen.sogou.com/z/q705635956.htm
 
 
PPS:(直接复制粘贴脚本即可,修改了符合VBA的注释符号)

Sub 合并目录所有工作簿全部工作表()

Dim MP, MN, AW, Wbn, wn '定义变量(MP=MyPath,MN=MyName,AW=ActiveWorkbookName,Wbn=WorkBookName,wn=workbooksheet(i)name),但未指定变量类型,这样不是很规范

Dim Wb As Workbook '定义变量Wb为工作簿类型 #Dim Wbn As string,G As Long #定义变量Wbn为字符型,G为长整型 #Dim Num,ini As Long #定义Num未声明类型,定义并声明ini为长整型

Dim i, a, b, d, c, e '定义变量,但未指定变量类型,这样不是很规范

Application.ScreenUpdating = False '关闭屏幕刷新

MP = ActiveWorkbook.Path '将当前工作簿(活动工作簿)的路径赋值给MP

MN = Dir(MP & "\" & "*.xls") '将当前工作簿(活动工作簿)的路径加上\*.xls后缀,从而捕获到的*位置的所有文件名的值,Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。

AW = ActiveWorkbook.Name '将当前工作簿(活动工作簿)的名字赋值给AW(不带后缀,只是名字)

Num = 0 'Num=0

e = 1 'ini=0

Do While MN <> "" '运行下面的DO while 循环,直到MN值为空值

If MN <> AW Then '如果,MN值不等于AW值,就运行IF到END IF之间的判断语句

Set Wb = Workbooks.Open(MP & "\" & MN) '打开MP\路径下名为MN变量值的工作簿,并引用(Set的作用)赋给Wb ##引用赋值如果,对Wb更改了,被引用的也随着更改了,详细见下边PS(3)

a = a + 1 '对a进行循环累加

With Workbooks(1).ActiveSheet '对已打开的所有工作簿中的第一个工作簿中的被激活的工作表运用with语句

For i = 1 To Sheets.Count '在Workbooks(1).ActiveSheet的所有sheet中循环

If Sheets(i).Range("a1") <> "" Then '如果Workbooks(1).ActiveSheet工作簿的第i个工作表的A1单元格内容不为空,就进行IF判断内容

Wb.Sheets(i).Range("a1").Resize(1, Sheets(i).UsedRange.Columns.Count).Copy .Cells(1, 1) '将wb工作簿中第i个工作表的A1单元格区域扩充为一行,有应用痕迹列数(x)大小的区域,即A1:x1区域, 扩充后区域内的内容复制到Workbooks(1).ActiveSheet的A1位置

d = Wb.Sheets(i).UsedRange.Columns.Count 'wb工作簿的第i工作表有应用痕迹的列计数,并赋值给d

c = Wb.Sheets(i).UsedRange.Rows.Count - 1 'wb工作簿的第i工作表有应用痕迹的行计数,并赋值给c

wn = Wb.Sheets(i).Name 'wb工作簿的第i个工作表的名字赋值给wn

.Cells(1, d + 1) = "表名" 'Workbooks(1).ActiveSheet工作表的第1行,第d+1列单元格填充“表名”字符串
.Cells(e + 1, d + 1).Resize(c, 1) = MN & wn 'Workbooks(1).ActiveSheet工作表的第e+1行,第d+1列区域扩充为c行,1列区域,并在该区域填充为MN & wn
e = e + c
Wb.Sheets(i).Range("a2").Resize(c, d).Copy .Cells(.Range("a1048576").End(xlUp).Row + 1, 1) '将区域内容,复制到Workbooks(1).ActiveSheet中,每次从Workbooks(1).ActiveSheet的最后一个非空行开始粘贴

End If

Next
Wbn = Wbn & Chr(13) & Wb.Name '将Wbn的值加上空格和Wb工作簿的名称后赋值给Wbn

Wb.Close False '将Wb工作簿关闭
End With
End If
MN = Dir '获得上边Dir匹配到的下一次文件名;#Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。
Loop
Range("a1").Select '选中当前工作簿的第一个单元格
Application.ScreenUpdating = True '开启屏幕刷新
MsgBox "共合并了" & a & "个工作薄下全部工作表。如下:" & Chr(13) & Wbn, vbInformation, "提示" '给出最后提示
End Sub

excel-合并多个Excel文件--VBA合并当前目录下所有Excel工作簿中的所有工作表的更多相关文章

  1. 我们无法找到服务器加载工作簿的数据模型"的 SharePoint 网站,当您刷新 Excel 2013 工作簿中的数据透视表时出错

    假定您使用 Analysis Services 源在 Microsoft Excel 2013 中创建数据透视表.将 Excel 工作簿上载到 Microsoft SharePoint 网站中.当您尝 ...

  2. Excel VBA在生成副本的工作表中插入本工作簿中的VBA模块代码

    即在工作簿中添加一个工作表,然后移出并存为新的工作簿,在移出前将本工作簿的一个模块的代码拷贝至新的工作簿.下面是关键代码: '===================================== ...

  3. Excel-同个工作簿中,多个工作表中有格式一致的表格,做汇总透视合并信息

    12.同个工作簿中,多个工作表中有格式一致的表格,做汇总透视合并信息 在工作簿中新建一个工作表-汇总表->按Alt+D+P调出数据透视表和数据透视图向导->选择"多重合并计算数据 ...

  4. 在Excel里如何将多个工作簿合并到一个工作簿中

    在Excel里如何将多个工作簿合并到一个工作簿中 当你必须将多个工作簿合并到一个工作簿时,你遇到过麻烦吗?最让人心烦的就是需要合并的工作簿里有很多张工作表.有人能推荐方法解决这个问题吗? 利用VBA ...

  5. 【集中工作薄】 当前文件夹中所有Excel文件中 多个工作簿的第一个工作表 复制到工作簿中

    功能:当前文件夹中所有Excel文件中 多个工作簿的第一个工作表 复制到工作簿中 Sub Books2Sheets() '定义对话框变量 Dim fd As FileDialog Set fd = A ...

  6. EXCEL中,怎样查看一个工作簿中有几个工作表?

    EXCEL中,怎样查看一个工作簿中有几个工作表 有几个EXCEL文件,每个文件(工作簿)中都有上百个工作表, 怎样可以一次性查看一个簿包含几个表? 目前好像没有直接可以看到有多少张工作表的按钮,这就需 ...

  7. 怎么拆分一个Excel工作簿中的多个工作表?

    打开需要编辑的Excel文档.如图所示,工作簿下方有很多工作表.现在需要将这些工作表单独拆分开成一个个工作簿.   右键任意一个工作表标签,在弹出的下拉列表中选择查看代码.即弹出代码窗口.如下图所示. ...

  8. 获取Excel工作薄中Sheet页(工作表)名集合

    #region 获取Excel工作薄中Sheet页(工作表)名集合 02./// <summary> 03./// 获取Excel工作薄中Sheet页(工作表)名集合 04./// < ...

  9. Excel VBA 从一个工作簿查找另一个一个工作簿中的一些内容复制到另外一个工作簿

    帮朋友来写个Excel VBA 以前写过ASP,所以对vb略微熟悉,但VBA 没有仔细研究过. 以前只研究过 vba 写一个 计算个人所得税的程序. 这次写的功能也算是简单,但也耗费了两天的功夫. 需 ...

随机推荐

  1. STM32必学的时钟系统

    STM32的时钟系统 相较于51单片机,stm32的时钟系统可以说是非常复杂了,我们现在看下面的一张图:   上图说明了时钟的走向,是从左至右的从时钟源一步步的分配给外设时钟.需要注意的是,上图左侧一 ...

  2. STM32时钟系统之利用 systick 定时器来实现准确的延时。

    本篇文章带着大家来认识一下 STM32 的时钟系统,以及利用 systick 定时器来实现一个比较准确的延时. 我们首先从时钟说起,时钟在MCU中的作用,就好比于人类的心脏一样不可或缺.STM32 的 ...

  3. 洛谷 P3209 [HNOI2010] 平面图判定

    链接: P3209 题意: 给出 \(T\) 张无向图 \((T\leq100)\),并给出它对应的哈密顿回路,判断每张图是否是平面图. 分析: 平面图判定问题貌似是有线性做法的,这里给出链接,不是本 ...

  4. linux命令中find, which、whereis、locate,有什么区别?

    whatis 用于查询一个命令执行什么功能,并将查询结果打印到终端上 which 查看可执行文件的位置 whereis 查看文件的位置 man Linux提供了丰富的帮助手册,当你需要查看某个命令的参 ...

  5. poj 2960 S-Nim (SG)

    题意: K个数,s1...sk. m个状态,对于某一个状态,有L堆石子,每人每次取的石子个数只能是s1...sk的一个,且只能在一堆中取. 输出m个状态是先手胜还是先手败,先手胜输出W,否则输出L. ...

  6. filter tools

    // 过滤商品分类 Vue.filter("cateFilter", (data) => {   let tmp = ["一级分类", "二级分 ...

  7. makefile简单学习(一)

    第一层 显式规则 目标:依赖 [tab] 指令 伪目标:.PHONY: 递归规则 hello : hello.o gcc hello.o -o hello hello.o : hello.s gcc ...

  8. VIM处理工具与正则表达式

    *本文中/data目录为训练目录 1.在vim中设置TAB缩进为四个字符 打开vim 输入:set tabstop=4 2.复制/etc/rc.d/init.d/functions文件至/tmp/,替 ...

  9. 【JAVA】笔记(2)---面向过程与面向对象;类,对象;实例变量,引用;构造方法;

    面向过程与面向对象: 1.面向过程思想的典型栗子是C语言,C语言实现一个程序的流程是:在主函数中一步一步地罗列代码(定义子函数来罗列也是一样的道理),以此来实现我们想要的效果: 2.面向对象思想的典型 ...

  10. SpringCloud微服务实战——搭建企业级开发框架(十六):集成Sentinel高可用流量管理框架【自定义返回消息】

    Sentinel限流之后,默认的响应消息为Blocked by Sentinel (flow limiting),对于系统整体功能提示来说并不统一,参考我们前面设置的统一响应及异常处理方式,返回相同的 ...