|
以下是实现您需求的Excel VBA宏代码。请按照以下步骤使用:
1. 打开Excel,按 `Alt + F11` 进入VBA编辑器。
2. 插入一个新模块(点击菜单栏的“插入” -> “模块”)。
3. 将以下代码复制到模块中。
4. 返回Excel,运行宏(按 `Alt + F8`,选择宏并执行)。
- Option Explicit
- Sub 汇总报表()
- Dim folderPath As String
- Dim baseFile As String
- Dim excludeRows As String
- Dim excludeCols As String
- Dim fileList As Collection
- Dim file As Variant
- Dim wbBase As Workbook, wbSummary As Workbook, wbSource As Workbook
- Dim wsBase As Worksheet, wsSummary As Worksheet, wsSource As Worksheet
- Dim rowArray() As Integer, colArray() As Integer
- Dim i As Integer, j As Integer, k As Integer, r As Integer, c As Integer
- Dim cellValue As Variant
- Dim fileCount As Integer
- Dim response As VbMsgBoxResult
-
- ' 步骤1: 选择文件夹并列出xlsx文件
- With Application.FileDialog(msoFileDialogFolderPicker)
- .Title = "请选择包含xlsx表格的文件夹"
- If .Show <> -1 Then Exit Sub
- folderPath = .SelectedItems(1)
- End With
-
- If Right(folderPath, 1) <> "" Then folderPath = folderPath & ""
-
- Set fileList = New Collection
- file = Dir(folderPath & "*.xlsx")
- Do While file <> ""
- fileList.Add file
- file = Dir
- Loop
-
- If fileList.Count = 0 Then
- MsgBox "未找到任何xlsx文件。"
- Exit Sub
- End If
-
- MsgBox "共找到 " & fileList.Count & " 个xlsx文件:" & vbCrLf & Join(CollectionToArray(fileList), vbCrLf)
-
- ' 步骤2: 选择基表并复制为汇总表
- baseFile = InputBox("请从上述列表中输入一个基表文件名(如123.xlsx):", "指定基表")
- If baseFile = "" Then Exit Sub
-
- On Error Resume Next
- Set wbBase = Workbooks.Open(folderPath & baseFile)
- On Error GoTo 0
- If wbBase Is Nothing Then
- MsgBox "无法打开基表文件,请检查文件名。"
- Exit Sub
- End If
-
- wbBase.SaveCopyAs folderPath & "汇总表.xlsx"
- Set wbSummary = Workbooks.Open(folderPath & "汇总表.xlsx")
- wbSummary.Activate
-
- ' 步骤3: 输入不参与累加的行号和列号
- excludeRows = InputBox("请输入不参与累加的行号(用逗号或点分隔,如1,2,3或1.2.3):", "排除行")
- excludeCols = InputBox("请输入不参与累加的列号(用逗号或点分隔,如A,B,C或A.B.C):", "排除列")
-
- ' 解析行号和列号
- rowArray = ParseInput(excludeRows, True)
- colArray = ParseInput(excludeCols, False)
-
- ' 步骤4: 遍历文件并累加
- fileCount = 0
- For Each file In fileList
- If file <> baseFile And file <> "汇总表.xlsx" Then
- On Error Resume Next
- Set wbSource = Workbooks.Open(folderPath & file)
- On Error GoTo 0
- If Not wbSource Is Nothing Then
- For Each wsSource In wbSource.Worksheets
- Set wsSummary = wbSummary.Worksheets(wsSource.Name)
- If Not wsSummary Is Nothing Then
- For r = 1 To wsSource.UsedRange.Rows.Count
- If Not IsInArray(r, rowArray) Then
- For c = 1 To wsSource.UsedRange.Columns.Count
- If Not IsInArray(c, colArray) Then
- cellValue = wsSource.Cells(r, c).Value
- If IsEmpty(cellValue) Then cellValue = 0
- If IsNumeric(cellValue) Then
- wsSummary.Cells(r, c).Value = wsSummary.Cells(r, c).Value + cellValue
- End If
- End If
- Next c
- End If
- Next r
- End If
- Next wsSource
- wbSource.Close SaveChanges:=False
- fileCount = fileCount + 1
- End If
- End If
- Next file
-
- wbSummary.Save
-
- ' 步骤5: 显示结果
- MsgBox "累加完成!共处理了 " & fileCount & " 个xlsx表格。"
- End Sub
- ' 辅助函数:将集合转换为数组
- Function CollectionToArray(coll As Collection) As Variant
- Dim arr() As Variant
- ReDim arr(1 To coll.Count)
- Dim i As Integer
- For i = 1 To coll.Count
- arr(i) = coll(i)
- Next i
- CollectionToArray = arr
- End Function
- ' 辅助函数:解析输入的行或列字符串
- Function ParseInput(inputStr As String, isRow As Boolean) As Integer()
- Dim parts() As String
- Dim tempArray() As Integer
- Dim i As Integer, num As Integer
- ReDim tempArray(0 To 0) ' 初始化为空数组
-
- If inputStr = "" Then
- ParseInput = tempArray
- Exit Function
- End If
-
- ' 替换点号为逗号,统一分隔符
- inputStr = Replace(inputStr, ".", ",")
- parts = Split(inputStr, ",")
-
- For i = 0 To UBound(parts)
- parts(i) = Trim(parts(i))
- If isRow Then
- num = Val(parts(i))
- Else
- num = ColumnLetterToNumber(parts(i))
- End If
- If num > 0 Then
- If tempArray(0) = 0 Then
- ReDim tempArray(0 To 0)
- tempArray(0) = num
- Else
- ReDim Preserve tempArray(0 To UBound(tempArray) + 1)
- tempArray(UBound(tempArray)) = num
- End If
- End If
- Next i
-
- ParseInput = tempArray
- End Function
- ' 辅助函数:将列字母转换为数字
- Function ColumnLetterToNumber(colLetter As String) As Integer
- Dim colNum As Integer
- colNum = 0
- On Error Resume Next
- colNum = Range(colLetter & "1").Column
- On Error GoTo 0
- ColumnLetterToNumber = colNum
- End Function
- ' 辅助函数:检查数字是否在数组中
- Function IsInArray(num As Integer, arr() As Integer) As Boolean
- Dim i As Integer
- IsInArray = False
- For i = 0 To UBound(arr)
- If arr(i) = num Then
- IsInArray = True
- Exit Function
- End If
- Next i
- End Function
复制代码
使用说明:
- 宏运行后,会提示选择文件夹,然后列出所有xlsx文件。
- 输入基表文件名时,请确保名称正确(包括扩展名)。
- 输入排除的行号和列号时,可用逗号或点分隔(例如:1,2,3 或 A.B.C)。
- 累加过程中,空单元格视为0,只累加数值数据。
- 确保所有表格的sheet结构相同,否则可能出错。
如果遇到问题,请检查文件路径和名称是否正确。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|