当前位置: 首页 > news >正文

常用 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

相关文章:

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

在日常办公中&#xff0c;我们常常会遇到各种繁琐的数据处理任务&#xff0c;而 Excel VBA&#xff08;Visual Basic for Applications&#xff09;作为一款强大的自动化工具&#xff0c;能够帮助我们轻松应对这些挑战。本文将介绍一些常用且简单好学的 Excel VBA 技巧&#xf…...

第7篇:Linux程序访问控制FPGA端LEDR<五>

Q&#xff1a;如何设计.c程序代码实现FPGA端外设LEDR流水灯&#xff1f; A&#xff1a;在DE1-SoC开发板上实现的流水灯效果&#xff1a;一次只点亮一个红色LED&#xff0c;初始状态为向左移动直至点亮LEDR9&#xff0c;然后改变移动的方向为向右直至点亮LEDR0&#xff0c;以此…...

PyTorch 深度学习实战(35):图生成模型与分子设计

在上一篇文章中&#xff0c;我们探讨了强化学习在机器人控制中的应用。本文将深入介绍图生成模型及其在分子设计领域的应用&#xff0c;这是一个结合深度学习与化学的交叉领域。我们将使用PyTorch Geometric实现基于图神经网络的分子生成模型&#xff0c;并在ZINC250k数据集上进…...

免费送源码:Java+ssm+HTML 三分糖——甜品店网站设计与实现 计算机毕业设计原创定制

录 摘要 1 1 绪论 3 1.1 研究背景 3 1.2 研究意义 3 1.3论文结构与章节安排 3 2系统分析 4 2.1 可行性分析 4 2.2 系统流程分析 4 2.2.1 登录流程 4 2.2.2数据删除流程 5 2.3 系统功能分析 5 2.3.1功能性分析 6 2.3.2 非功能性分析 7 2.4 系统用例分析 7 2.5本章…...

JVM 调试与内存优化实战详解

&#x1f31f; JVM 调试与内存优化实战详解 &#x1f31f; 前言一、JVM 内存模型概览二、常见内存问题与诊断思路三、核心调试工具与命令详解四、实战案例一&#xff1a;频繁 Full GC 深度排查与优化1. &#x1f575;️ 问题现象2. &#x1f52c; 排查流程3. ✅ 优化方案 五、实…...

Linux上通过Docker部署Zabbix6.2监控平台

文章目录 前言Zabbix概述zabbix特性 一、Zabbix架构二、主节点部署容器2.1 部署Docker 三、主节点部署数据库3.1 创建存储卷3.2 查看存储卷3.3 删除存储卷3.4 运行容器MySQL8 四、主节点部署Zabbix4.1 安装zabbix-java-gateway4.2 运行zabbix-server4.3 安装zabbix-web 五、配置…...

Grok3 API 已经免费开放了,附上免费使用 Grok3 API的教程

Grok-3是什么 Grok-3 是 xAI&#xff08;由 Elon Musk 创立的 AI 公司&#xff09;开发的最新大语言模型&#xff08;LLM&#xff09;&#xff0c;属于 Grok 系列模型的第三代&#xff0c;旨在与 OpenAI 的 GPT-4、Anthropic 的 Claude 3 和 Google 的 Gemini 1.5 等顶尖 AI 竞…...

2025年4月9日-华为暑期实习-第三题-300分

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 03. 矩阵螺旋排序 问题描述 卢小姐是一家艺术展览馆的策展人,她正在为一个数字艺术展览设计一个特殊的展示方案。展览厅的墙面是一个 N N N \times N...

【Web API系列】WebSocketStream API 深度实践:构建高吞吐量实时应用的流式通信方案

前言 在当今的 Web 开发领域&#xff0c;实时通信已成为许多应用的核心需求。无论是即时聊天、实时数据仪表盘&#xff0c;还是在线游戏和金融交易系统&#xff0c;都需要高效的双向数据传输能力。传统的 WebSocket API 为此提供了基础支持&#xff0c;但在处理大规模数据流、…...

WEB攻防-Java安全JNDIRMILDAP五大不安全组件RCE执行不出网不回显

目录 1. RCE执行-5大类函数调用 1.1 Runtime方式 1.2 Groovy执行命令 1.3 脚本引擎代码注入 1.4 ProcessImpl 1.5 ProcessBuilder 2. JNDI注入(RCE)-RMI&LDAP&高版本 2.1 RMI服务中的JNDI注入场景 2.2 LDAP服务中的JNDI注入场景 攻击路径示例&#…...

在android实现Google的web登录

前言 由于业务上的需要,想要在android端实现Google登录。但是android的原生方法受到限制,实现起来比较麻烦。于是想到了一个曲线救国的方法,在android端使用Google的web登录。 实现逻辑 在andorid端拉起外部浏览器,用户登录Google账号,登录成功后,再将登录信息返回到a…...

opencv常用边缘检测算子示例

opencv常用边缘检测算子示例 1. Canny算子2. Sobel算子3. Scharr算子4. Laplacian算子5. 对比 1. Canny算子 从不同视觉对象中提取有用的结构信息并大大减少要处理的数据量的一种技术&#xff0c;检测算法可以分为以下5个步骤&#xff1a; 噪声过滤&#xff08;高斯滤波&…...

安装了VM Tools,仍无法复制拖动-解决方案

今天在安装ubuntu时遇到了困扰许久的问题&#xff0c;安装了VM Tools&#xff0c;仍无法拖动主机文件到虚拟机&#xff0c;主要有两种原因并对应解决办法。 1.相关虚拟机设置选项卡中-客户机隔离-两个功能没有勾选 解决方案&#xff1a;勾选重启虚拟机即可 2.&#xff08;这个…...

一文读懂WPF布局

WPF布局 布局WPF 布局的核心机制常用布局控件详解Grid&#xff08;网格布局&#xff09;StackPanel&#xff08;堆叠布局&#xff09;DockPanel&#xff08;停靠布局&#xff09;WrapPanel&#xff08;自动换行布局&#xff09;Canvas&#xff08;绝对定位布局&#xff09;Unif…...

【Docker基础-网络】--查阅笔记4

目录 Docker 网络网络类型none 网络host 网络bridge 网络自定义网络 容器间通信IP 通信Docker DNS Serverjoined 容器 容器与外部通信容器访问外部外部访问容器 Docker 网络 学习Docker提供的几种原生网络如何创建自定义网络容器间通信&#xff0c;容器于外界交互 Docker 安装…...

FacialExpressionDetection的conda虚拟环境搭建Window

安装conda的URL&#xff1a;Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 清华源下载conda版本&#xff0c;哪个最新用哪个&#xff0c;这里下载Anaconda3-5.3.1-Windows-x86_64.exe版本 安装conda虚拟环境 conda create --name py1…...

IPD推进中关键角色与岗位(七)LTDT确保技术开发的实用性与可靠性,满足市场需求

IPD 体系作为一种先进的研发管理模式&#xff0c;其核心在于打破传统职能部门的壁垒&#xff0c;通过跨部门团队的协同合作&#xff0c;实现产品开发的全流程优化。在 IPD 体系的架构中&#xff0c;存在着多个关键团队&#xff0c;它们各司其职又紧密配合&#xff0c;共同推动产…...

c++自学笔记——字符串与指针

字符串与指针 1. 字符串基础 字符串的定义&#xff1a;字符的序列&#xff0c;通常用来表示文本。 字符串字面量&#xff08;String Literal&#xff09;是在程序中直接用双引号括起来的文本序列。字符串字面量的类型是 const char*&#xff0c;即指向字符常量的指针。字符串…...

Jmeter分布式测试启动

代理客户端配置 打开jmeter.properties文件&#xff0c;取消注释并设置端口&#xff08;如server_port1099&#xff09;&#xff0c; 并添加server.rmi.ssl.disabletrue禁用SSL加密。 &#xff08;Linux系统&#xff09;修改jmeter-server文件中的RMI_HOST_DEF为代理机实际IP。…...

.DS_Store文件泄露、.git目录泄露、.svn目录泄露漏洞利用工具

&#x1f409;工具介绍 一款图形化的 .DS_Store文件泄露、.git目录泄露、.svn目录泄露漏洞利用工具。 &#x1f3af;使用 本工具使用Python3 PyQt5开发&#xff0c;在开始使用前&#xff0c;请确保已经安装了相关模块&#xff1a; pip3 install -r requirements.txt -i ht…...

Coze+大模型智能体环境搭建

1 前言 Coze作为字节跳动推出的新一代AI Bot开发平台&#xff0c;为开发者提供了快速构建、部署智能对话代理的一站式解决方案。Coze平台通过提供可视化工作流编排、知识库集成、插件扩展等核心功能&#xff0c;结合一些大模型&#xff0c;例如豆包、deepseek、通义千问等大模型…...

计算机视觉与深度学习 | 视觉SLAM学习思路总结与视觉SLAM发展历程(1986年至2025年)

视觉SLAM(Simultaneous Localization and Mapping,同时定位与建图)是计算机视觉和机器人领域的重要研究方向,涉及数学、几何、优化、传感器融合等多学科知识。以下是学习视觉SLAM的系统化思路总结,适合从入门到进阶的学习路径:视觉SLAM学习思路总结 一、基础准备 数学基…...

Ansible(8)——循环与条件任务

目录 一、循环迭代任务&#xff1a; 1、简单循环&#xff1a; 2、循环字典列表&#xff1a; 3、Ansible 2.5 之前的循环关键字&#xff1a; 4、在循环中使用 register 变量&#xff1a; 二、条件任务&#xff1a; 1、使用条件句的常见场景&#xff1a; 2、条件任务语法…...

搭建Trae+Vue3的AI开发环境

从2024年2025年&#xff0c;不断的有各种AI工具会在自媒体中火起来&#xff0c;号称各种效率王炸&#xff0c;而在AI是否会替代打工人的话题中&#xff0c;程序员又首当其冲。 作为一个后端开发&#xff0c;这篇文章基于Trae工具&#xff0c;来创建和运行一个简单的Vue前端应用…...

【免费公测】可遇AI直播/无人直播/矩阵直播/AI场控

前言 经过了一个多月的内测打磨&#xff0c;实现了非常稳定的无人直播效果&#xff0c;AI直播语音及其真实&#xff0c;软件交互方便&#xff0c;可以快速的构建AI直播间。 免费公测&#xff0c;内置无限激活卡密一张&#xff0c;打开即用。 亮点 高仿真语音模型&#xff0c…...

大数据Hadoop(MapReduce)

MapReduce概述 MapReduce定义 MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一个Hadoop集群上…...

使用apache-jmeter时,控制台打不开应用的解决方法

运行jmeter.bat的时候&#xff0c;提示&#xff1a; findstr 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 Not able to find Java executable or version. Please check your Java installation. errorlevel2这个错误信息表明系统无法识别 findstr 命令…...

leetcode 74. 搜索二维矩阵

class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m matrix.length;int n matrix[0].length;int l 0;int r n * m - 1; // 记得减一while (l < r) {int mid (l r) / 2;if(matrix[mid / n][mid % n] > target) {r mid - 1;} else if…...

函数式编程在 Java:Function、BiFunction、UnaryOperator 你真的会用?

大家好&#xff0c;我是你们的Java技术博主&#xff01;今天我们要深入探讨Java函数式编程中的几个核心接口&#xff1a;Function、BiFunction和UnaryOperator。很多同学虽然知道它们的存在&#xff0c;但真正用起来却总是不得要领。这篇文章将带你彻底掌握它们&#xff01;&am…...

SpringMVC基础一(SpringMVC运行原理)

先了解MVC&#xff0c;在JavaWeb基础五中。 回忆servlet&#xff0c;在javaweb基础二中。 创建一个web项目&#xff1a; 1、新建maven项目&#xff0c;导入依赖。&#xff08;junit、springmvc、spring-webmvc、servlet-api、jsp-api、jstl&#xff09; <groupId>org…...

libva之ffavdemo分析

ffavdemo 代码库实现了一个基于FFmpeg和VAAPI的硬件加速视频解码与渲染框架&#xff0c;主要用于演示视频解码与渲染的完整硬件加速流程。支持多种渲染后端&#xff08;X11、DRM、EGL&#xff09;&#xff0c;适应不同显示环境。包含视频处理过滤器&#xff0c;可进行格式转换和…...

从零开始写android 的智能指针

Android中定义了两种智能指针类型&#xff0c;一种是强指针sp&#xff08;strong pointer&#xff09;&#xff0c;源码中的位置在system/core/include/utils/StrongPointer.h。另外一种是弱指针&#xff08;weak pointer&#xff09;。其实称之为强引用和弱引用更合适一些。强…...

Spark-SQL 之 Window

window 函数实例 select concat(substr(p_dt,1,4),substr(p_dt,6,2)...

Python设计模式-单例模式

一、单例模式核心思想 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点。该模式主要解决以下问题&#xff1a; 资源控制&#xff08;如数据库连接池&#xff09;配置信息全局一…...

富文本编辑器的内容导出html,并保留图片

富文本编辑器的上传的图片默认转为base64&#xff0c;但是如果需要保存到数据库&#xff0c;base64的数据就太大了&#xff0c;所以一般都会长传到文件服务器&#xff0c;然会返回图片url。 但是当我们需要把富文本编辑器的内容导出为html时&#xff0c;因为图片时url,当浏览器…...

jQueryHTML与插件

1.jQuery 事件机制 1.1 注册事件 bind()、on()方法向被选元素添加一个或多个事件处理程序&#xff0c;以及当事件发生时运行的函数 $("p").on({"click": function () {alert("点击了")},"mouseenter": function () {…...

KTH5772 系列游戏手柄摇杆专用3D 霍尔位置传感器

产品概述 KTH5772是一款专为游戏手柄上的摇杆应用而设计的3D霍尔磁感应芯片&#xff0c;主要面向对线性度、回报率、灵敏度、功耗要求严格的摇杆应用。KTH5772基于3D霍尔技术&#xff0c;内部分别集成了X轴、Y轴和Z轴三个独立的霍尔元件&#xff0c;能够通过测量和处理磁通密度…...

C++进阶——C++11_右值引用和移动语义_可变参数模板_类的新功能

目录 1、右值引用和移动语义 1.1 左值和右值 1.2 左值引用和右值引用 1.3 引用延长生命周期 1.4 左值和右值的参数匹配 1.5 右值引用和移动语义的使用场景 1.5.1 左值引用主要使用场景 1.5.2 移动构造和移动赋值 1.5.3 右值引用和移动语义解决传值返回问题 1.5.4 右值…...

(五)深入了解AVFoundation-播放:多音轨、字幕、倍速播放与横竖屏切换

引言 在之前的博客中&#xff0c;我们已经实现了一个相对完整的播放器&#xff0c;具备了基本功能&#xff0c;如播放、暂停、播放进度显示和拖拽快进等。这为我们提供了一个坚实的基础。接下来&#xff0c;我们将进一步扩展播放器的功能&#xff0c;使其更具灵活性和实用性&a…...

matplotlib.pyplot常见图形及组合基础用法文档

matplotlib.pyplot 常见图形及组合基础用法文档 一、引言 matplotlib.pyplot 是 Python 中用于数据可视化的强大库&#xff0c;提供了丰富的绘图函数&#xff0c;可绘制折线图、散点图、柱状图等多种类型的图形。同时&#xff0c;还能将不同类型的图形组合在一起&#xff0c;…...

mysql的基础语句和外键查询及其语句

思路&#xff1a;双指针思路可以吗&#xff0c;我就直接找G,如果后一个是1就cnt&#xff0c;如果不是数字&#xff0c;用一个指针i指向G&#xff0c;另一个指针j移动&#xff0c;当不是G时停止&#xff0c;统计G的个数&#xff0c;如果是奇数个同时G的下一个是1&#xff0c;cnt…...

如何使用 DeepSeek 帮助自己的工作?

1. 信息检索 信息检索是获取特定信息的过程&#xff0c;尤其是在大量数据或文本中查找相关内容。这个过程应用广泛&#xff0c;从网页搜索引擎到数据库查询&#xff0c;再到企业内部信息系统。在使用 DeepSeek 或其它类似工具进行信息检索时&#xff0c;可以考虑以下几个重要方…...

为 Doub 打造吸引 CMO 的 SEO 报告

在数字营销中&#xff0c;SEO 报告不仅是展示工作成果的工具&#xff0c;更是向高层管理者&#xff08;如 CMO&#xff09;证明 SEO 价值的关键。对于 Doub 这样一家提供精密模切解决方案的网站&#xff08;基于 WordPress 和 WooCommerce&#xff09;&#xff0c;撰写一份吸引…...

数据可视化 —— 折线图应用(大全)

一、导入需要的库 # Matplotlib 是 Python 最常用的绘图库&#xff0c;pyplot 提供了类似 MATLAB 的绘图接口 import matplotlib.pyplot as plt import numpy as np import pandas as pd 二、常用的库函数 plt.plot(x轴,y轴)&#xff1a;plot()是画折线图的函数。 plt.xlabe…...

配置mac mini M4 的一些软件

最近更换了 mac mini M4 &#xff0c;想要重新下载配置软件 &#xff0c;记录一下。 Homebrew是什么&#xff1f; homebrew是一款Mac OS平台下的软件包管理工具&#xff0c;拥有安装、卸载、更新、查看、搜索等功能。通过简单的指令可以实现包管理&#xff0c;而不用关心各种…...

八邻域轮廓跟踪算法_传感器技术

在科学技术日新月异的今天&#xff0c;人们对机器设备的智能性、自主性要求也越来越高&#xff0c;希望其完全替代人的角色&#xff0c;把人们从繁重、危险的工作任务中解脱出来&#xff0c;而能否像人一样具有感知周围环境的能力已成为设备实现智能化自主化的关键。 广义的“…...

python实战:如何正确安装 ffmpeg(window、linux、mac都通用)

直接使用 Conda 安装 FFmpeg,而无需手动下载或配置环境变量。Conda 会自动管理依赖项,并将 FFmpeg 添加到你的环境路径中。 方法 1:使用 Conda 安装 FFmpeg 在 Anaconda Prompt(或终端)中运行: conda install ffmpeg -c conda-forge-c conda-forge 表示从 conda-forge…...

网络机顶盒常见问题全解析:从安装到故障排除

WiFi连接问题 机顶盒无法连接WiFi&#xff0c;先检查路由器信号强度。若信号弱&#xff0c;可将机顶盒移近路由器&#xff0c;或调整路由器天线方向。也可重启机顶盒与路由器&#xff0c;若仍不行&#xff0c;进入机顶盒设置&#xff0c;重置网络设置。若支持5GHz频段&#xf…...

使用stm32cubeide stm32f407 lan8720a freertos lwip 实现tcp客户端、服务端及网络数据转串口数据过程详解

1前言 项目需要使用MCU实现网络功能&#xff0c;后续确定方案stm32f407 外接lan8720a实现硬件平台搭建&#xff0c;针对lan8720a也是用的比较多的phy&#xff0c;网上比较多的开发板&#xff0c;硬件上都是选用了这个phy&#xff0c;项目周期比较短&#xff0c;选用了这个常用…...

GAT-GRAPH ATTENTION NETWORKS(论文笔记)

CCF等级&#xff1a;A 发布时间&#xff1a;2018年 代码位置 25年4月21日交 目录 一、简介 二、原理 1.注意力系数 2.归一化 3.特征组合与非线性变换 4.多头注意力 4.1特征拼接操作 4.2平均池化操作 三、实验性能 四、结论和未来工作 一、简介 图注意力网络&…...