' 主调用过程 - 示例循环 (修正版)
Sub MainProcessingLoop()
' 示例:假设用户输入存储在数组中
Dim prefixPairs(1 To 3) As Variant
prefixPairs(1) = Array("sales_Q1_", "sales_Q2_")
prefixPairs(2) = Array("income_H1_", "income_H2_")
prefixPairs(3) = Array("expense_Q1_", "expense_Q2_")
' 初始化输出位置
Dim outputRow As Long: outputRow = GetLastOutputRow(ThisWorkbook.Sheets("Results")) + 2
' 循环处理每组前缀
Dim i As Long
For i = 1 To UBound(prefixPairs)
' 调用处理函数 - 直接传递数组元素
ProcessFilePairSet prefixPairs(i)(0), prefixPairs(i)(1), outputRow
' 更新输出行位置
outputRow = GetLastOutputRow(ThisWorkbook.Sheets("Results")) + 2
Next i
MsgBox "所有文件处理完成!"
End Sub
' 获取工作表最后输出行 (修正版)
Function GetLastOutputRow(ws As Worksheet) As Long
With ws
GetLastOutputRow = .Cells(.Rows.Count, "A").End(xlUp).Row
' 如果工作表为空,从第0行开始
If GetLastOutputRow = 1 And .Range("A1").Value = "" Then GetLastOutputRow = 0
End With
End Function
' 核心处理函数 - 可被循环调用 (修正版)
Sub ProcessFilePairSet(ByVal prefix1 As String, ByVal prefix2 As String, ByVal startRow As Long)
Dim fso As Object
Dim currentPath As String
Dim filePairs As Collection
Dim pair As Variant
Dim ws As Worksheet
' 设置工作表和路径
Set fso = CreateObject("Scripting.FileSystemObject")
Set ws = ThisWorkbook.Sheets("Results")
currentPath = ThisWorkbook.Path & "\"
' 查找匹配的文件对
Set filePairs = FindMatchingFilePairs(fso, currentPath, prefix1, prefix2)
If filePairs.Count = 0 Then
ws.Cells(startRow, 1).Value = "未找到匹配文件对: " & prefix1 & " 和 " & prefix2
Exit Sub
End If
' 输出标题(仅在首次调用或新工作表时)
If startRow <= 1 Or ws.Range("A1").Value = "" Then
SetupOutputHeaders ws
startRow = 2 ' 如果添加了标题,从第2行开始
End If
' 处理每个文件对
Dim currentOutputRow As Long: currentOutputRow = startRow
For Each pair In filePairs
' 读取文件数据
Dim file1Data() As Variant, file2Data() As Variant
ReadFileToArray fso, pair("file1"), file1Data
ReadFileToArray fso, pair("file2"), file2Data
' 执行计算
Dim calc1Result() As Variant
Dim calc2Result As Double
calc1Result = CalculateLineByLine(file1Data, file2Data)
calc2Result = CalculateMaxSum(file1Data, file2Data)
' 输出结果
OutputResults ws, currentOutputRow, pair("suffix"), _
fso.GetFileName(pair("file1")), _
fso.GetFileName(pair("file2")), _
calc1Result, calc2Result
' 更新行位置
currentOutputRow = currentOutputRow + UBound(calc1Result, 1) + 1
Next pair
' 添加分隔线
With ws.Range("A" & currentOutputRow & ":F" & currentOutputRow)
.Interior.Color = RGB(150, 150, 150)
.Value = ""
End With
Set fso = Nothing
End Sub
' 查找匹配的文件对 (修正版)
Function FindMatchingFilePairs(fso As Object, ByVal path As String, _
ByVal prefix1 As String, ByVal prefix2 As String) As Collection
Dim files1 As Object, files2 As Object
Dim filePairs As New Collection
Dim file As Object, suffix As String
Set files1 = CreateObject("Scripting.Dictionary")
Set files2 = CreateObject("Scripting.Dictionary")
' 确保路径以反斜杠结尾
If Right(path, 1) <> "\" Then path = path & "\"
' 检查文件夹是否存在
If Not fso.FolderExists(path) Then
MsgBox "路径不存在: " & path, vbExclamation
Set FindMatchingFilePairs = filePairs
Exit Function
End If
' 获取第一个前缀的所有匹配文件
For Each file In fso.GetFolder(path).Files
If LCase(fso.GetExtensionName(file.Name)) = "txt" Then
If LCase(Left(file.Name, Len(prefix1))) = LCase(prefix1) Then
suffix = Mid(file.Name, Len(prefix1) + 1)
suffix = Left(suffix, InStr(suffix, ".") - 1) ' 移除扩展名
files1(suffix) = file.Path
End If
End If
Next file
' 获取第二个前缀的所有匹配文件
For Each file In fso.GetFolder(path).Files
If LCase(fso.GetExtensionName(file.Name)) = "txt" Then
If LCase(Left(file.Name, Len(prefix2))) = LCase(prefix2) Then
suffix = Mid(file.Name, Len(prefix2) + 1)
suffix = Left(suffix, InStr(suffix, ".") - 1) ' 移除扩展名
files2(suffix) = file.Path
End If
End If
Next file
' 查找共同的后缀(文件对)
Dim key As Variant
For Each key In files1.Keys
If files2.Exists(key) Then
Dim pair As Object
Set pair = CreateObject("Scripting.Dictionary")
pair("suffix") = key
pair("file1") = files1(key)
pair("file2") = files2(key)
filePairs.Add pair
End If
Next key
Set FindMatchingFilePairs = filePairs
End Function
' 读取文件到二维数组 (修正版)
Sub ReadFileToArray(fso As Object, ByVal filePath As String, ByRef data() As Variant)
On Error Resume Next ' 添加错误处理
Dim textStream As Object
Dim lines() As String, line As String
Dim cols() As String
Dim i As Long, validCount As Long, rowIndex As Long
' 检查文件是否存在
If Not fso.FileExists(filePath) Then
ReDim data(1 To 1, 1 To 2)
data(1, 1) = "文件不存在"
Exit Sub
End If
Set textStream = fso.OpenTextFile(filePath, 1)
lines = Split(textStream.ReadAll, vbCrLf)
textStream.Close
' 计算实际数据行数(跳过空行)
validCount = 0
For i = 0 To UBound(lines)
If Trim(lines(i)) <> "" Then validCount = validCount + 1
Next i
If validCount = 0 Then
ReDim data(1 To 1, 1 To 2)
data(1, 1) = "无有效数据"
Exit Sub
End If
' 初始化二维数组
ReDim data(1 To validCount, 1 To 2)
' 处理数据行
rowIndex = 1
For i = 0 To UBound(lines)
line = Trim(lines(i))
If line <> "" Then
' 分割列(支持空格、制表符、逗号分隔)
cols = Split(line, vbTab) ' 先尝试制表符分隔
' 如果分割后只有一列,尝试其他分隔符
If UBound(cols) < 1 Then
cols = Split(Application.Trim(line), " ") ' 处理多个空格
End If
If UBound(cols) < 1 Then
cols = Split(line, ",") ' 尝试逗号分隔
End If
' 存储数据
If UBound(cols) >= 1 Then
data(rowIndex, 1) = cols(0)
data(rowIndex, 2) = cols(1)
ElseIf UBound(cols) >= 0 Then
data(rowIndex, 1) = cols(0)
data(rowIndex, 2) = "" ' 第二列设为空
End If
rowIndex = rowIndex + 1
End If
Next i
End Sub
' 计算1:两个文件第二列逐行相加 (修正版)
Function CalculateLineByLine(ByRef file1Data() As Variant, ByRef file2Data() As Variant) As Variant()
Dim minRows As Long, i As Long
Dim result() As Variant
' 检查数组是否有效
If Not IsArrayInitialized(file1Data) Or Not IsArrayInitialized(file2Data) Then
ReDim result(1 To 1, 1 To 2)
result(1, 1) = "无效数据"
result(1, 2) = "无效数据"
CalculateLineByLine = result
Exit Function
End If
' 确定最小行数
minRows = Application.Min(UBound(file1Data, 1), UBound(file2Data, 1))
' 创建结果数组(两列)
ReDim result(1 To minRows, 1 To 2)
' 进行计算
For i = 1 To minRows
' 第一列(使用file1的第一列)
result(i, 1) = file1Data(i, 1)
' 第二列:两个文件的第二列相加
If IsNumeric(file1Data(i, 2)) And IsNumeric(file2Data(i, 2)) Then
result(i, 2) = file1Data(i, 2) + file2Data(i, 2)
Else
result(i, 2) = "N/A"
End If
Next i
CalculateLineByLine = result
End Function
' 辅助函数:检查数组是否初始化
Function IsArrayInitialized(arr() As Variant) As Boolean
On Error Resume Next
IsArrayInitialized = IsArray(arr) And Not IsError(UBound(arr, 1))
If Err.Number <> 0 Then IsArrayInitialized = False
On Error GoTo 0
End Function
' 计算2:两个文件第二列的最大值相加 (修正版)
Function CalculateMaxSum(ByRef file1Data() As Variant, ByRef file2Data() As Variant) As Double
Dim max1 As Double, max2 As Double
Dim i As Long
' 初始化最大值
max1 = -1.79769313486231E+308 ' 最小双精度值
max2 = max1
' 检查数组是否有效
If Not IsArrayInitialized(file1Data) Or Not IsArrayInitialized(file2Data) Then
CalculateMaxSum = 0
Exit Function
End If
' 查找file1第二列的最大值
For i = 1 To UBound(file1Data, 1)
If IsNumeric(file1Data(i, 2)) Then
If file1Data(i, 2) > max1 Then max1 = file1Data(i, 2)
End If
Next i
' 查找file2第二列的最大值
For i = 1 To UBound(file2Data, 1)
If IsNumeric(file2Data(i, 2)) Then
If file2Data(i, 2) > max2 Then max2 = file2Data(i, 2)
End If
Next i
' 返回总和
CalculateMaxSum = max1 + max2
End Function
' 输出结果到工作表 (修正版)
Sub OutputResults(ws As Worksheet, ByVal startRow As Long, ByVal suffix As String, _
ByVal file1Name As String, ByVal file2Name As String, _
ByRef calc1Result() As Variant, ByVal calc2Result As Double)
On Error Resume Next ' 添加错误处理
With ws
' 输出文件信息 (仅在第一行)
.Cells(startRow, 1).Value = suffix
.Cells(startRow, 2).Value = file1Name
.Cells(startRow, 3).Value = file2Name
.Cells(startRow, 6).Value = calc2Result
' 输出计算1结果 (逐行相加)
If IsArrayInitialized(calc1Result) Then
.Cells(startRow, 4).Resize(UBound(calc1Result, 1), 2).Value = calc1Result
Else
.Cells(startRow, 4).Value = "无计算结果"
End If
' 添加边框
Dim endRow As Long
If IsArrayInitialized(calc1Result) Then
endRow = startRow + UBound(calc1Result, 1) - 1
Else
endRow = startRow
End If
With .Range(.Cells(startRow, 1), .Cells(endRow, 6))
.Borders.LineStyle = xlContinuous
.Borders.Weight = xlThin
End With
' 设置交替背景色
Dim colorIndex As Long
colorIndex = (startRow \ 3) Mod 2 ' 根据行号确定颜色
If colorIndex = 0 Then
.Range(.Cells(startRow, 1), .Cells(endRow, 6)).Interior.Color = RGB(240, 245, 255)
Else
.Range(.Cells(startRow, 1), .Cells(endRow, 6)).Interior.Color = RGB(255, 245, 240)
End If
End With
End Sub
上面的程序中,pair变量报了byref参数不匹配应该怎么解决