常用 Excel VBA 技巧,简单好学易上手

在日常办公中,我们常常会遇到各种繁琐的数据处理任务,而 Excel VBA(Visual Basic for Applications)作为一款强大的自动化工具,能够帮助我们轻松应对这些挑战。本文将介绍一些常用且简单好学的 Excel VBA 技巧,包括文档的合并与拆分,以及如何使用 Control 配置表进行灵活配置。

在 VBA 代码中,可以通过读取 Control Sheet 中的这些参数来实现灵活配置,通过学习和掌握这些常用的 Excel VBA 技巧,如文档的合并与拆分,以及利用 Control Sheet 进行灵活配置,我们能够显著提高数据处理的效率,轻松应对各种复杂的办公任务。希望本文介绍的内容能够帮助你在日常工作中更好地发挥 Excel VBA 的强大功能。

启用 VBA 编辑器

在开始使用 VBA 之前,需要确保 Excel 中启用了开发工具选项卡。具体步骤如下:

  1. 点击 “文件” 选项卡。
  2. 选择 “选项”。
  3. 在弹出的 “Excel 选项” 对话框中,选择 “自定义功能区”。
  4. 在右侧的 “主选项卡” 列表中,勾选 “开发工具”,然后点击 “确定”。
    启用开发工具选项卡后,只需按下 “Alt + F11” 组合键,即可快速打开 VBA 编辑器。

case 1

文档拆分

有时我们需要将一个包含多个工作表的 Excel 文件拆分为多个独立的文件。以下是实现这一功能的 VBA 代码:

场景 例如将集团的数据按公司代码进行拆分

整体业务目标

该代码的主要业务目标是从一个源 Excel 文件中提取特定数据,按照一定规则进行排序和分组,例如是公司代码,然后将分组后的数据分别保存到多个新的 Excel 文件中,并且对这些新文件进行一些格式设置和保护操作。

具体需求步骤

1. 数据配置获取
  • 代码从当前工作簿(主工作簿)的名为 “control” 的工作表中读取一系列配置信息,这些信息包括:
    • 源文件的文件名、所在工作表名和文件夹路径。
    • 粘贴数据的工作表名。
    • 表头的行数。有时候表头不只一行,可能是组合式的多行表头,拆分的时候要复制表头。
    • 保存文件的文件名、工作表名和文件夹路径。
2. 数据准备
  • 清空主工作簿中名为 “raw” 的工作表的所有内容。
  • 打开源文件和指定的工作表,将源工作表中 A 列到 I 列的数据复制到 “raw” 工作表中。
3. 数据排序
  • 对 “raw” 工作表中的数据按照公司代码B 列的值进行升序排序。排序的表头设置为有表头,排序方法为按拼音排序。
4. 数据分组与保存
  • 初始化一些变量,用于跟踪当前处理的数据分组情况,包括上一个值、区域、复制起始行和上一次值变化的行。
  • 遍历 “raw” 工作表中的数据行(从第 2 行到最后一行):
    • 当 B 列的值发生变化或者到达最后一行时:
      • 创建一个新的工作簿,并选择其第一个工作表作为目标工作表。
      • 将 “raw” 工作表的表头(A1 到指定列宽对应的表头行)复制到目标工作表的第一行,同时粘贴格式。
      • 根据当前行和上一次值变化的行,确定要复制的数据行范围,将这些数据行(包括格式)复制到目标工作表的第二行开始的位置。
      • 自动调整目标工作表 A 列到 I 列的列宽
      • 对目标工作表的 I 列设置可编辑区域,同时对整个工作表进行保护,防止用户修改绘图对象、内容和方案。
      • 在目标工作表的第一行处冻结窗格,方便查看数据。
      • 根据配置信息和当前区域、值生成保存文件的路径和文件名,将新工作簿保存到指定位置,然后关闭该工作簿。
      • 更新上一个值、区域和复制起始行,以便处理下一个分组。

业务场景实例

要拆开的内容

实际的数据要从其他 file 获得

设置 control 配置表

代码说明

变量声明部分

vba

Dim wbMaster As Workbook
Dim wsControl As Worksheet
Dim sourceFileName As String
Dim sourceSheetName As String
Dim sourceFolderPath As String
Dim pasteSheetName As String
Dim headerRows As Long
Dim maxRows As Long
Dim saveFileName As String
Dim saveSheetName As String
Dim saveFolderPath As String
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim wsRaw As Worksheet
Dim wsTarget As Worksheet
Dim rowCount As Long
Dim pasteRow As Long
Dim lastValueChangeRow As Long
Dim copyRowRange As Range

此部分代码的作用是声明程序里要用到的各类变量,涵盖工作簿对象、工作表对象、字符串变量、长整型变量以及区域对象等。这些变量分别用于存储源文件与目标文件的相关信息、工作表对象、行数、区域范围等内容。

初始化对象与获取配置信息部分

vba

Set wbMaster = ThisWorkbook
Set wsControl = wbMaster.Sheets("control")
Set wsRaw = wbMaster.Sheets("raw")sourceFileName = wsControl.Range("B3").Value
sourceSheetName = wsControl.Range("B4").Value
sourceFolderPath = wsControl.Range("B5").Value
pasteSheetName = wsControl.Range("B8").Value
headerRows = wsControl.Range("B9").Value
maxRows = wsControl.Range("B10").Value
saveFileName = wsControl.Range("B13").Value
saveSheetName = wsControl.Range("B14").Value
saveFolderPath = wsControl.Range("B15").Value
colWidth = wsControl.Range("D9").ValuewsRaw.Select
Cells.Select
Selection.ClearContents

  • Set wbMaster = ThisWorkbook:把当前正在运行代码的工作簿赋值给 wbMaster
  • Set wsControl = wbMaster.Sheets("control") 和 Set wsRaw = wbMaster.Sheets("raw"):分别获取名为 “control” 和 “raw” 的工作表对象。
  • 后续代码从 “control” 工作表的特定单元格里读取配置信息,像源文件名、源工作表名、保存文件名等。
  • wsRaw.SelectCells.Select 和 Selection.ClearContents:选中 “raw” 工作表的所有单元格并清空其内容。

打开源工作簿并复制数据部分

vba

Set wbSource = Workbooks.Open(sourceFolderPath & "\" & sourceFileName)
Set wsSource = wbSource.Sheets(sourceSheetName)wsRaw.Range("A:I").Value = wsSource.Range("A:I").ValueendRow = wsRaw.Cells(Rows.Count, 1).End(xlUp).Row

  • Set wbSource = Workbooks.Open(sourceFolderPath & "\" & sourceFileName):依据之前获取的源文件路径和文件名打开源工作簿。
  • Set wsSource = wbSource.Sheets(sourceSheetName):获取源工作簿里指定名称的工作表对象。
  • wsRaw.Range("A:I").Value = wsSource.Range("A:I").Value:把源工作表中 A 列到 I 列的数据复制到 “raw” 工作表对应的列。
  • endRow = wsRaw.Cells(Rows.Count, 1).End(xlUp).Row:找出 “raw” 工作表中 A 列有数据的最后一行。

数据排序部分

vba

wsRaw.Activate
wsRaw.Sort.SortFields.Add2 Key:=Range( _"B2:B26275"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _xlSortNormal
With wsRaw.Sort.SetRange Range("A1:I26275").Header = xlYes.MatchCase = False.Orientation = xlTopToBottom.SortMethod = xlPinYin.Apply
End With

  • 此部分代码对 “raw” 工作表中的数据进行排序。
  • wsRaw.Sort.SortFields.Add2:添加排序字段,按照 B2 到 B26275 单元格的值进行升序排序。
  • With wsRaw.Sort 块:设置排序范围为 A1 到 I26275,表明有表头,不区分大小写,排序方向为从上到下,排序方法为按拼音排序,最后应用排序操作。

初始化分组变量部分

vba

lastValue = wsRaw.Cells(headerRows + 1, 2).Value
Region = wsRaw.Cells(headerRows + 1, 1).Value
rowCopyFrom = headerRows + 1
lastValueChangeRow = headerRows + 1

这部分代码对分组操作所需的变量进行初始化。lastValue 存储当前分组的判断值,Region 存储区域信息,rowCopyFrom 记录复制数据的起始行,lastValueChangeRow 记录上一次值发生变化的行。

数据分组与保存部分

vba

For rowCount = 2 To endRowcurrentValue = wsRaw.Cells(rowCount, 2).ValueIf currentValue <> lastValue Or rowCount = endRow ThenlastValueChangeRow = rowCount' 创建新工作簿Set NewWorkbook = Workbooks.AddSet wsTarget = NewWorkbook.Sheets(1)' 复制表头Set copyRowRange = wsRaw.Range("A1:" & colWidth & headerRows)copyRowRange.CopywsTarget.Cells(1, 1).PasteSpecial xlPasteAllApplication.CutCopyMode = False' 复制内容If rowCount = endRow ThenSet copyRowRange = wsRaw.Range("A" & rowCopyFrom & ":" & colWidth & lastValueChangeRow)ElseSet copyRowRange = wsRaw.Range("A" & rowCopyFrom & ":" & colWidth & lastValueChangeRow - 1)End IfcopyRowRange.CopywsTarget.Cells(2, 1).PasteSpecial xlPasteAllApplication.CutCopyMode = False' 调整列宽wsTarget.Columns("A:I").EntireColumn.AutoFit' 保护工作表wsTarget.Protection.AllowEditRanges.Add Title:="AREA1", Range:=Columns("I:I")wsTarget.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True' 冻结窗格wsTarget.ActivateWith ActiveWindow.SplitColumn = 0.SplitRow = 1End WithActiveWindow.FreezePanes = True' 保存并关闭工作簿savePath = saveFolderPath & "\" & saveFileName & "_" & Region & "_" & lastValue & ".xlsx"NewWorkbook.SaveAs savePathNewWorkbook.Close' 更新变量lastValue = currentValueRegion = wsRaw.Cells(rowCount, 1).ValuerowCopyFrom = rowCountEnd If
Next rowCount

  • 这是一个 For 循环,会遍历 “raw” 工作表中从第 2 行到最后一行的数据。
  • 当 currentValue(当前行第 2 列的值)和 lastValue 不同,或者到达最后一行时,就会进行分组操作:
    • 创建一个新的工作簿和工作表对象。
    • 复制 “raw” 工作表的表头到新工作簿的工作表中。
    • 根据当前行和上一次值变化的行,确定要复制的数据范围并复制到新工作簿的工作表里。
    • 自动调整新工作簿工作表中 A 列到 I 列的列宽。
    • 对新工作簿的工作表进行保护,允许编辑 I 列。
    • 在新工作簿的工作表第一行处冻结窗格。
    • 按照指定的规则生成保存路径和文件名,保存新工作簿并关闭。
    • 更新 lastValueRegion 和 rowCopyFrom 变量,为下一个分组做准备。

综上所述,这段代码的主要功能是读取源文件的数据,对数据进行排序和分组,然后将分组后的数据分别保存到多个新的工作簿中,同时对这些新工作簿的工作表进行格式设置和保护。

完整代码

Sub CopyData()Dim wbMaster As WorkbookDim wsControl As WorksheetDim sourceFileName As StringDim sourceSheetName As StringDim sourceFolderPath As StringDim pasteSheetName As StringDim headerRows As LongDim maxRows As LongDim saveFileName As StringDim saveSheetName As StringDim saveFolderPath As StringDim wbSource As WorkbookDim wsSource As WorksheetDim wsRaw As WorksheetDim wsTarget As WorksheetDim rowCount As LongDim pasteRow As LongDim lastValueChangeRow As LongDim copyRowRange As RangeSet wbMaster = ThisWorkbookSet wsControl = wbMaster.Sheets("control")Set wsRaw = wbMaster.Sheets("raw")sourceFileName = wsControl.Range("B3").ValuesourceSheetName = wsControl.Range("B4").ValuesourceFolderPath = wsControl.Range("B5").ValuepasteSheetName = wsControl.Range("B8").ValueheaderRows = wsControl.Range("B9").ValuemaxRows = wsControl.Range("B10").ValuesaveFileName = wsControl.Range("B13").ValuesaveSheetName = wsControl.Range("B14").ValuesaveFolderPath = wsControl.Range("B15").ValuecolWidth = wsControl.Range("D9").ValuewsRaw.SelectCells.SelectSelection.ClearContents' 打开源工作簿和工作表Set wbSource = Workbooks.Open(sourceFolderPath & "\" & sourceFileName)Set wsSource = wbSource.Sheets(sourceSheetName)wsRaw.Range("A:I").Value = wsSource.Range("A:I").ValueendRow = wsRaw.Cells(Rows.Count, 1).End(xlUp).RowwsRaw.ActivatewsRaw.Sort.SortFields.Add2 Key:=Range( _"B2:B26275"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _xlSortNormalWith wsRaw.Sort.SetRange Range("A1:I26275").Header = xlYes.MatchCase = False.Orientation = xlTopToBottom.SortMethod = xlPinYin.ApplyEnd With' ?? 初始化变量lastValue = wsRaw.Cells(headerRows + 1, 2).ValueRegion = wsRaw.Cells(headerRows + 1, 1).ValuerowCopyFrom = headerRows + 1lastValueChangeRow = headerRows + 1For rowCount = 2 To endRowcurrentValue = wsRaw.Cells(rowCount, 2).ValueIf currentValue <> lastValue Or rowCount = endRow ThenlastValueChangeRow = rowCount' company code 变化 create new workbookSet NewWorkbook = Workbooks.AddSet wsTarget = NewWorkbook.Sheets(1)'表头Set copyRowRange = wsRaw.Range("A1:" & colWidth & headerRows)' 粘贴到目标工作表copyRowRange.CopywsTarget.Cells(1, 1).PasteSpecial xlPasteAll ' 粘贴所有内容包括格式Application.CutCopyMode = False'内容If rowCount = endRow ThenSet copyRowRange = wsRaw.Range("A" & rowCopyFrom & ":" & colWidth & lastValueChangeRow)ElseSet copyRowRange = wsRaw.Range("A" & rowCopyFrom & ":" & colWidth & lastValueChangeRow - 1)End If' 粘贴到目标工作表copyRowRange.CopywsTarget.Cells(2, 1).PasteSpecial xlPasteAll ' 粘贴所有内容包括格式Application.CutCopyMode = FalsewsTarget.Columns("A:I").EntireColumn.AutoFitwsTarget.Protection.AllowEditRanges.Add Title:="AREA1", Range:=Columns("I:I")wsTarget.Protect DrawingObjects:=True, Contents:=True, Scenarios:=TruewsTarget.ActivateWith ActiveWindow.SplitColumn = 0.SplitRow = 1End WithActiveWindow.FreezePanes = TruesavePath = saveFolderPath & "\" & saveFileName & "_" & Region & "_" & lastValue & ".xlsx"NewWorkbook.SaveAs savePathNewWorkbook.Close'update lastvaluelastValue = currentValueRegion = wsRaw.Cells(rowCount, 1).ValuerowCopyFrom = rowCountEnd IfNext rowCountEnd Sub

如何利用 AI 协助写代码

关键:将问题拆开为独立的小问题,不要贪心让AI 给你完整代码,逻辑一定要自己掌握。

' 方法一:自动调整整个工作表的列宽
Sub AutoFitColumnsInSheetA()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("SheetA")
    ws.Cells.EntireColumn.AutoFit
End Sub

' 方法二:自动调整指定列范围的列宽
Sub AutoFitSpecificColumnsInSheetA()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("SheetA")
    ws.Range("A:E").EntireColumn.AutoFit
End Sub

 

     Set ws = ThisWorkbook.Sheets("SheetA")
    
    ' 取消工作表的保护(如果已保护)
    If ws.ProtectContents Then
        ws.Unprotect
    End If

    ' 添加 I 列作为可编辑区域
    ws.Protection.AllowEditRanges.Add Title:="EditableColumnI", Range:=ws.Columns("I")
    
    ' 保护工作表
    ws.Protect 
 

文档合并

业务场景

在实际工作中,经常会遇到需要将多个 Excel 文件的数据合并到一个工作表中的情况。例如,某公司不同部门每个月都会生成各自的业务数据报表,这些报表格式基本相同,但分别存储在不同的 Excel 文件中。为了进行整体的数据分析和统计,需要将这些分散的文件数据整合到一个文件里。此 VBA 代码就是为解决这类数据合并问题而设计的,它可以从指定文件夹中获取所有 Excel 文件,将它们的数据合并到一个名为 “Combine” 的工作表中,最后还能将合并后的数据保存为一个新的 Excel 文件。

处理逻辑

  1. 初始化设置
    • 设定主工作簿和控制工作表,控制工作表 “control” 用于存储配置信息,如要合并的文件夹路径、表头行数等。
    • 从控制工作表中读取要合并的文件夹路径、表头行数、列宽和新文件的文件名等配置信息。
  2. 目标工作表准备
    • 检查主工作簿中是否存在名为 “Combine” 的目标工作表,若不存在则创建该工作表。
    • 清空目标工作表中的所有内容,为合并数据做准备。
  3. 文件遍历与数据合并
    • 对指定文件夹中的所有 Excel 文件进行遍历,记录合并的文件数量。
    • 依次打开每个 Excel 文件,假设只处理文件中的第一个工作表。
    • 找出当前打开文件中第一列有数据的最后一行。
    • 若还未复制过表头,就将当前文件的完整数据(从 A1 到 L 列最后一行)复制到目标工作表中;若已复制过表头,则只复制当前文件的数据行(从 A2 到 L 列最后一行)到目标工作表中。
    • 关闭当前处理的 Excel 文件,继续处理下一个文件。
  4. 错误处理
    • 在打开 Excel 文件时,如果出现错误,会弹出消息框提示用户检查文件是否正常,然后继续处理下一个文件。
  5. 合并完成提示与保存新文件
    • 当所有文件都处理完毕后,弹出消息框提示 “合并完成!”。
    • 创建一个新的工作簿,将合并数据所在的目标工作表复制到新工作簿中。
    • 按照控制工作表中指定的文件名保存新工作簿,最后关闭新工作簿。

例如之前的拆分,在收集用户的反馈后进行合并。

1. 变量声明区块

vba

Dim folderPath As String
Dim targetSheetName As String
Dim wbMaster As Workbook
Dim wsControl As Worksheet
Dim wbB As Workbook
Dim wsB As Worksheet
Dim lastRow As Long
Dim i As Long
Dim copyRowRange As Range
Dim pasteCol As Long
Dim pasteRow As Long
Dim key1 As String
Dim key2 As String
Dim key3 As String
Dim key4 As String
Dim colWidth As String
Dim rowHeight As Long
Dim checkRow As Long
Dim pasteRows As Long
Dim j As Long
Dim fileCount As Long ' 新增:用于记录合并的文件数量

功能:声明了宏中会用到的各种变量,涵盖字符串变量(如文件夹路径、工作表名称)、工作簿和工作表对象、长整型变量(用于记录行号等)、范围对象等。fileCount 变量用于记录合并的文件数量。

2. 设置主工作簿及控制工作表区块

vba

Set wbMaster = ThisWorkbook
Set wsControl = wbMaster.Sheets("control")

  • 功能:将 wbMaster 设定为当前运行宏的工作簿,把 wsControl 设定为该工作簿中名为 “control” 的工作表,此工作表用于存储配置信息。

3. 获取配置信息区块

vba

folderPath = wsControl.Range("B18").Value
targetSheetName = "Combine"
headerRows = wsControl.Range("B9").Value
colWidth = wsControl.Range("D9").Value
newFileName = wsControl.Range("B19").Value

  • 功能:从控制工作表 “control” 里读取配置信息,像要合并的文件夹路径(B18 单元格)、表头行数(B9 单元格)、列宽(D9 单元格)以及新文件的文件名(B19 单元格)。同时把目标工作表的名称设定为 “Combine”。

4. 设置目标工作表区块

vba

On Error Resume Next
Set wsTarget = wbMaster.Sheets(targetSheetName)
On Error GoTo 0
If wsTarget Is Nothing ThenSet wsTarget = wbMaster.Sheets.Add(After:=wbMaster.Sheets(wbMaster.Sheets.Count))wsTarget.Name = targetSheetName
End If

  • 功能:尝试获取主工作簿中名为 “Combine” 的目标工作表。若该工作表不存在,就会在主工作簿的最后添加一个新的工作表,并将其命名为 “Combine”。

5. 清空目标工作表内容区块

vba

wsTarget.Select
Cells.Select
Selection.ClearContents

  • 功能:选中目标工作表中的所有单元格,然后清空其内容,为后续合并数据做好准备。

6. 初始化变量区块

vba

isTitleCopy = False
lastRow = 0 ' targer 的最后一行

  • 功能:初始化两个变量,isTitleCopy 用于标记表头是否已复制,lastRow 用于记录目标工作表中数据的最后一行,初始值设为 0。

7. 文件遍历与数据合并区块

vba

folderPath = folderPath & "\"
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
Filename = Dir(folderPath & "*.xls*")
fileCount = 0 ' 初始化文件数量为 0
Do While Filename <> ""fileCount = fileCount + 1 ' 每次循环,文件数量加 1On Error GoTo OpenErrorHandlerSet wbB = Workbooks.Open(folderPath & Filename)On Error GoTo 0Set wsB = wbB.Sheets(1) ' 这里假设只处理每个工作簿的第一个工作表,可按需修改endRowFrom = wsB.Cells(Rows.Count, 1).End(xlUp).RowcopyStartRow = lastRow + 1If isTitleCopy = False ThenwsB.Range("A1:L" & endRowFrom).Copy wsTarget.Range("A" & copyStartRow)lastRow = endRowFromisTitleCopy = TrueElsewsB.Range("A2:L" & endRowFrom).Copy wsTarget.Range("A" & copyStartRow)lastRow = lastRow + endRowFrom - 1End IfwbB.Close FalseFilename = Dir
Loop

  • 功能
    • 保证文件夹路径以反斜杠结尾。
    • 运用 Dir 函数获取指定文件夹中所有扩展名为 .xls 或 .xlsx 的文件。
    • 循环处理每个文件,每次循环时 fileCount 加 1。
    • 尝试打开文件,若出现错误则跳转到错误处理程序。
    • 假设只处理每个工作簿的第一个工作表,找出该工作表第一列有数据的最后一行。
    • 若表头还未复制,就将当前文件的完整数据(从 A1 到 L 列最后一行)复制到目标工作表;若表头已复制,则只复制数据行(从 A2 到 L 列最后一行)。
    • 关闭当前处理的文件,继续处理下一个文件。

8. 错误处理区块

vba

OpenErrorHandler:MsgBox "打开工作簿 " & Filename & " 时出现错误,请检查文件是否正常。"Resume Next

  • 功能:若在打开文件时出现错误,会弹出消息框提示用户检查文件是否正常,然后继续处理下一个文件。

9. 合并完成提示与保存新文件区块

vba

MsgBox "合并完成!"
Set newWb = Workbooks.Add
wsTarget.Copy Before:=newWb.Sheets(1)
newWb.SaveAs newFileName
newWb.Close SaveChanges:=True

  • 功能
    • 所有文件处理完毕后,弹出消息框提示 “合并完成!”。
    • 创建一个新的工作簿。
    • 将合并数据所在的目标工作表复制到新工作簿的第一个工作表之前。
    • 按照控制工作表中指定的文件名保存新工作簿,最后关闭新工作簿。

10. 退出宏区块

vba

Exit Sub

  • 功能:正常退出宏的执行。

完整代码如下

Sub MergeExcels()' 声明所有变量Dim folderPath As StringDim targetSheetName As StringDim wbMaster As WorkbookDim wsControl As WorksheetDim wbB As WorkbookDim wsB As WorksheetDim lastRow As LongDim i As LongDim copyRowRange As RangeDim pasteCol As LongDim pasteRow As LongDim key1 As StringDim key2 As StringDim key3 As StringDim key4 As StringDim colWidth As StringDim rowHeight As LongDim checkRow As LongDim pasteRows As LongDim j As LongDim fileCount As Long ' 新增:用于记录合并的文件数量' 1. 设置主工作簿及控制工作表Set wbMaster = ThisWorkbookSet wsControl = wbMaster.Sheets("control")' 2. 获取要合并的文件夹路径及目标工作表名folderPath = wsControl.Range("B18").ValuetargetSheetName = "Combine"headerRows = wsControl.Range("B9").ValuecolWidth = wsControl.Range("D9").ValuenewFileName = wsControl.Range("B19").Value' 4. 设置目标工作表,如果不存在则创建On Error Resume NextSet wsTarget = wbMaster.Sheets(targetSheetName)On Error GoTo 0If wsTarget Is Nothing ThenSet wsTarget = wbMaster.Sheets.Add(After:=wbMaster.Sheets(wbMaster.Sheets.Count))wsTarget.Name = targetSheetNameEnd If'CLEAR combine sheet contentwsTarget.SelectCells.SelectSelection.ClearContentsisTitleCopy = FalselastRow = 0 ' targer 的最后一行' 9. 获取文件夹中的所有 Excel 文件并遍历合并folderPath = folderPath & "\"If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"Filename = Dir(folderPath & "*.xls*")fileCount = 0 ' 初始化文件数量为 0Do While Filename <> ""fileCount = fileCount + 1 ' 每次循环,文件数量加 1On Error GoTo OpenErrorHandlerSet wbB = Workbooks.Open(folderPath & Filename)On Error GoTo 0Set wsB = wbB.Sheets(1) ' 这里假设只处理每个工作簿的第一个工作表,可按需修改endRowFrom = wsB.Cells(Rows.Count, 1).End(xlUp).RowcopyStartRow = lastRow + 1If isTtileCopy = False ThenwsB.Range("A1:L" & endRowFrom).Copy wsTarget.Range("A" & copyStartRow)lastRow = endRowFromisTtileCopy = TrueElsewsB.Range("A2:L" & endRowFrom).Copy wsTarget.Range("A" & copyStartRow)lastRow = lastRow + endRowFrom - 1End If' 16. 关闭当前遍历的工作簿wbB.Close FalseFilename = DirLoopMsgBox "合并完成!"'创建一个新的工作簿Set newWb = Workbooks.Add'将原工作表复制到新工作簿wsTarget.Copy Before:=newWb.Sheets(1)'保存新工作簿到指定路径newWb.SaveAs newFileName'关闭新工作簿newWb.Close SaveChanges:=TrueExit Sub
OpenErrorHandler:MsgBox "打开工作簿 " & Filename & " 时出现错误,请检查文件是否正常。"Resume Next
End Sub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 基础 - 反射(1)

文章目录 引入类加载过程1. 通过 new 创建对象2. 通过反射创建对象2.1 触发加载但不初始化2.2 按需触发初始化2.3 选择性初始化控制 核心用法示例1. 通过无参构造函数创建实例对象2. 通过有参构造函数创建实例对象3. 反射通过私有构造函数创建对象&#xff0c; 破坏单例模式4. …

如何在React中集成 PDF.js?构建支持打印下载的PDF阅读器详解

本文深入解析基于 React 和 PDF.js 构建 PDF 查看器的实现方案&#xff0c;该组件支持 PDF 渲染、图片打印和下载功能&#xff0c;并包含完整的加载状态与错误处理机制。 完整代码在最后 一个PDF 文件&#xff1a; https://mozilla.github.io/pdf.js/web/compressed.tracemo…

数据结构与算法-动态规划-线性动态规划,0-1背包,多重背包,完全背包,有依赖的背包,分组背包,背包计数,背包路径

动态规划原理 动态规划这玩意儿&#xff0c;就好比是在拓扑图上玩跳格子游戏。在图论中&#xff0c;咱们是从特定的节点跳到其他节点&#xff1b;而在动态规划里呢&#xff0c;我们是从一个状态 “嗖” 地转移到另一个状态。状态一般用数组来表示&#xff0c;就像 f [i][j]&am…

解决文件夹解压中文字符产生乱码的问题

太tm智能了&#xff0c;本来还想看看解压工具在哪里修改&#xff0c;智能的识别到乱码了。点赞 看到那个地球了吗&#xff0c;点击那个球&#xff0c;这个修改不是侵略性的&#xff0c;不会修改压缩文件本身所以需要在当前页面解压 参考 https://blog.csdn.net/QCSYSZQ/artic…

C++与C的区别

目录 前言 一、从字面上看 二、从编程思想上看 三、C 和 C++ 都有各自适合的领域和特性 四、划重点 前言 本文主要对 C 和 C++ 两种编程语言进行对比区分,便于大家理解 一、从字面上看 1.首先:两者第一个字符完全一致 说明:C++ 完全兼容 C ,凡是合法的 C 程序在 C…

水利水电安全员ABC适合哪些人考?

水利水电安全员证是水利工程建设领域的重要职业资格证书&#xff0c;主要涉及水利水电工程施工安全管理、风险防控和应急处理等工作。那么&#xff0c;哪些人适合考取&#xff1f; 哪些人适合考水利水电安全员&#xff1f; 1. 水利水电工程从业人员 ✅ 施工管理人员&#xf…

Linux中用gdb查看coredump文件

查看dump的命令&#xff1a; gdb 可执行文件 dump文件路径查看函数调用栈 (gdb)bt查看反汇编代码 (gdb)disassemble查看寄存器的值 (gdb)info all-registers如果通过上述简单命令无法排查&#xff0c;还是通过-g参数编译带符号表的可执行文件&#xff0c;再用gdb查看

【前端】【React】useCallback的作用与使用场景总结

一、useCallback 的作用与使用场景总结 useCallback 是 React 提供的一个 Hook&#xff0c;用于缓存函数的引用&#xff0c;避免因为组件重新渲染而导致函数地址发生变化。它返回一个记忆&#xff08;memoized&#xff09;后的回调函数&#xff0c;只有当依赖项发生变化时才会…

蓝桥杯备赛学习笔记:高频考点与真题预测(C++/Java/python版)

2025蓝桥杯备赛学习笔记 ——高频考点与真题预测 一、考察趋势分析 通过对第13-15届蓝桥杯真题的分析&#xff0c;可以发现题目主要围绕基础算法、数据结构、数学问题、字符串处理、编程语言基础展开&#xff0c;且近年逐渐增加动态规划、图论、贪心算法等较难题目。 1. 基…

20250410在荣品的PRO-RK3566开发板使用Rockchip原厂的buildroot系统时自动挂载eth0【直接编译进IMG】

【暂时没有找到第一次编译就可以修改的地方&#xff01;&#xff01;&#xff01;&#xff01;】 rootrootrootroot-X99-Turbo:~/RK3566_RK3568_Linux5.10_V1.2.0$ find . -name interfaces 【完整编译之后&#xff0c;基本确认修改这里有效。】 ./buildroot/output/rockchip_r…

c11新特性,继承构造函数

#include <iostream> #include <string>class Person { public:std::string name;int age;// 主构造函数Person(const std::string& name, int age) : name(name), age(age) {std::cout << "Person created with name: " << name <&l…

【TS学习】(24)什么是装饰器

在 TypeScript 中&#xff0c;装饰器&#xff08;Decorators&#xff09; 是一种特殊的声明&#xff0c;用于为类、类成员&#xff08;属性、方法、访问器&#xff09;、方法参数或整个类添加元数据或修改其行为。装饰器是 JavaScript 和 TypeScript 的实验性特性&#xff0c;广…

datagrip如何连接数据库

datagrip连接数据库的步骤 2025版本 想要链接数据库是需要一个jar包的&#xff0c;所以将上面进行删除之后&#xff0c;需要下载一个jar包 那么这个时候需要链接上传一个mysql链接的jar包 选择核心驱动类 上述操作完成之后&#xff0c;然后点击apply再点击ok即可 如下图说明my…

菊风RTC 2.0 开发者文档正式发布,解锁音视频新体验!

重磅发布&#xff01; 开发者们&#xff0c;菊风实时音视频2.0文档已正式发布上线&#xff0c;为您提供更清晰、更高效的开发支持&#xff01;让菊风实时音视频2.0为您的音视频应用加速~ 菊风实时音视频2.0聚焦性能升级、体验升级、录制服务升级&#xff0c;助力视频通话、语…

轻量级碎片化笔记memos本地NAS部署与跨平台跨网络同步笔记实战

文章目录 前言1. 使用Docker部署memos2. 注册账号与简单操作演示3. 安装cpolar内网穿透4. 创建公网地址5. 创建固定公网地址 推荐 ​ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站 前言…

【Vue #2】脚手架 指令

一、脚手架 脚手架&#xff1a;一个保证各项工作顺利开展的平台&#xff0c;方便我们 拿来就用&#xff0c;零配置 1. Vue 代码开发方式 相比直接 script 引入 vue 源码&#xff0c;有没有更好的方式编写vue代码呢? ① 传统开发模式&#xff1a; 基于html文件开发Vue&…

ArkTS语言入门之接口、泛型、空安全、特殊运算符等

前言 臭宝们&#xff0c;今天我们来学习ArkTS中最后的一些内容。 实现接口 包含implements子句的类必须实现列出的接口中定义的所有方法&#xff0c;但使用默认实现定义的方法除外。 interface DateInterface {now(): string; } class MyDate implements DateInterface {no…

Maven超级详细安装部署

1.到底什么是Maven&#xff1f;搞清楚这个 Maven 是一个项目管理工具&#xff0c;主要用于 Java 项目的构建、依赖管理和文档生成。 它基于项目对象模型&#xff08;POM&#xff09;&#xff0c;通过 pom.xml 文件定义项目的配置。 &#xff08;简单说破&#xff1a;就是工程…

高并发内存池(三):PageCache(页缓存)的实现

前言&#xff1a; 在前两期内容中&#xff0c;我们深入探讨了内存管理机制中在 ThreadCache 和 CentralCache两个层级进行内存申请的具体实现。这两层缓存作为高效的内存分配策略&#xff0c;能够快速响应线程的内存需求&#xff0c;减少锁竞争&#xff0c;提升程序性能。 本期…

机器学习 | 强化学习方法分类汇总 | 概念向

文章目录 📚Model-Free RL vs Model-Based RL🐇核心定义🐇核心区别📚Policy-Based RL vs Value-Based RL🐇核心定义🐇 核心区别📚Monte-Carlo update vs Temporal-Difference update🐇核心定义🐇核心区别📚On-Policy vs Off-Policy🐇核心定义🐇核心区别…