最近在项目上,有小伙伴在验工计价的过程中需要对很多张计价表编号,据说多时上千张表要干这事儿,人工做是一件很头疼的事,于是建议他们用vba来解决这个问题,几秒钟就能完成令你焦头烂额的事。可能是几个人要做这个验工计价表,所以存在很多Excel文件,每个Excel文件又有多个工作表。这让我想起数年前为水泥搅拌桩编号的事,不能遗漏不能重复,虽然活简单,几千根桩编下来,累死,且不一定能保证符合要求。这些是计算机擅长干的事,所不同的是,我们要编写程序让计算机去做。要完成修改多个工作簿中的内容,可以按照如下思路来:01
获取指定文件夹将要编号的所有Excel文件放到一个文件夹下,实施统一修改。不可能将电脑里的文件全改了吧?代码如下,不是唯一的:Private Sub CommandButton1_Click()
Set fileDlg = Application.FileDialog(msoFileDialogFolderPicker)
With fileDlg
If .Show = -1 Then
For Each fld In .SelectedItems
path = fld
Exit For
Next fld
End If
End With
Label1.Caption = path
End Sub
这段代码能看懂么?定义一个文件夹对话框对象,msoFileDialogFolderPicke参数允许用户选择一个文件夹。在这个问题中,只需要一个文件夹。
02
获取指定文件夹下所有Excel文件获取指定路径下所有Excel文件代码:
Function GetFiles(ByVal path) As String()
Application.ScreenUpdating = False
Set fso = CreateObject("scripting.filesystemobject")
Set ff = fso.getfolder(path)
ActiveSheet.UsedRange.ClearContents
Dim ls() As String
Dim a As Integer
ReDim ls(1 To 1)
a = 1
ReDim Preserve GetFiles(a)
For Each F In ff.files
If F.Name = "" Then Exit For
ext = Split(F.Name, ".")(UBound(Split(F.Name, ".")))
If ext = "xlsx" Then
ls(a) = F
a = a + 1
ReDim Preserve ls(1 To a)
End If
Next F
Application.ScreenUpdating = True
Dim b As Integer
b = UBound(ls)
GetFiles = ls
End Function
把这个功能做成了一个函数,方便以后修改和调用。函数返回的是一个字符串数组,每个数组元素是一个Excel文件名(包括路径)。
03
在Excel中打开其他的Excel文件并修改1和2已经做好打开的准备。下面是打开工作簿的代码,也包含读取各个sheet并编号汇总:
Private Sub CommandButton2_Click()
Sheet1.UsedRange.ClearContents
If path = "" Then MsgBox "请先选择文件夹": Exit Sub'没有选文件夹则退出
Dim files() As String
files = GetFiles(path)'获取指定文件夹Excel文件名及路径信息
Dim NO As Integer'编号计数
Dim Trow As Integer'为统计表填表行号
Trow = 1
NO = 1
For i = 1 To UBound(files) - 1
Workbooks.Open Filename:=files(i)'打开第i个Excel文件
For j = 1 To Workbooks(Workbooks.Count).Sheets.Count'循环搜索第i个文件中的所有工作表
Workbooks(Workbooks.Count).Activate
Dim lssheet As Worksheet'准备操作工作表
Set lssheet = Workbooks(Workbooks.Count).Sheets(j)
lssheet.Activate
Dim Rows As Integer
Rows = ActiveSheet.UsedRange.Rows.Count
For m = 1 To Rows
If InStr(lssheet.Cells(m, 1).Value, "总包单位") > 0 Then'由于总包单位是编号的唯一标识行,故搜索这个条件
lssheet.Cells(m, 1) = "总包单位:*********** 合 同 号: 编 号:" & TextBox1.Text & GetNO(NO)'编号并写入
Sheet1.Cells(Trow, 1).Value = files(i)'统计被修改过的文件名
Sheet1.Cells(Trow, 2).Value = lssheet.Name'统计被修改过的表名
Sheet1.Cells(Trow, 3).Value = TextBox1.Text & GetNO(NO)'写入的编号
Trow = Trow + 1
NO = NO + 1
End If
Next m
Next j
Workbooks(Workbooks.Count).Save'保存修改后的第i个文件
Workbooks(Workbooks.Count).Close'关闭打开的第i个文件
Next i
Ftotal = UBound(files) - 1'打开的总的文件数
Ntotal = NO - 1'总的编号
MsgBox "共编写了" & Ftotal & "个文件," & Ntotal & "个编号"
End Sub