HI,大家好,我是星光。分享一段VBA代碼,作用是將指定文件夾下全部excel或csv類(lèi)型文件的數(shù)據(jù)匯總到當(dāng)前工作表。
如下圖所示的文件夾,包含了Excel/csv等多個(gè)文件,每個(gè)Excel工作簿內(nèi)又包含了多張工作表……
現(xiàn)在需要由用戶自由選擇數(shù)據(jù)來(lái)源文件夾,將所有數(shù)據(jù)匯總為一張工作表。標(biāo)題行的行數(shù)也由用戶自由指定;匯總后的數(shù)據(jù)需保持文本型數(shù)值不變形;并提供數(shù)據(jù)來(lái)源工作簿名、工作表名以及工作表序號(hào)等,以方便后續(xù)數(shù)據(jù)篩選處理。
示例代碼如下▼
Sub GetFilesDataByNUM()
Dim aFileName(), strPath As String
Dim i As Long, x As Long, k As Long, intTitCount
Dim wb As Workbook, sht As Worksheet, shtSum As Worksheet
Dim rngData As Range
Dim intLastRow As Long, intFirstRow As Long
Dim aData, aSource
On Error Resume Next
strPath = getStrPath() '用戶選擇路徑
If strPath = "" Then Exit Sub
intTitCount = getTitCount() '用戶設(shè)置標(biāo)題行數(shù)
If intTitCount = "錯(cuò)誤" Then Exit Sub
aFileName = GetWbFullNames(strPath) '獲取文件名單
Call disAppSet '取消屏幕刷新
Call CreateShtSum '創(chuàng)建匯總數(shù)據(jù)的工作表
Set shtSum = Worksheets("星光-匯總")
intFirstRow = 1
For i = 1 To UBound(aFileName) '遍歷文件
Set wb = Workbooks.Open(aFileName(i))
For Each sht In wb.Worksheets '遍歷工作表
Set rngData = sht.UsedRange
If IsEmpty(rngData) = False Then '如果工作表非空
k = k + 1
'數(shù)據(jù)來(lái)源的工作簿、工作表等信息
aSource = Array(wb.Name, sht.Name, sht.Index)
If k = 1 Then
aData = rngData.Value
'根據(jù)首張工作表,設(shè)置可能有的文本值格式
Call DataFormat(aData, shtSum)
Else
aData = rngData.Offset(intTitCount).Value
End If
With shtSum '數(shù)據(jù)寫(xiě)入工作表
4).Resize( _
UBound(aData, 2)) = aData
intLastRow = GetLastRow(shtSum) '結(jié)束行
1), .Cells(intLastRow, 3)) _
aSource '來(lái)源信息寫(xiě)入工作表 =
intFirstRow = intLastRow + 1
End With
End If
Next
False
Next
shtSum.Select
c1") = Array("工作簿名稱", "工作表名稱", "工作表索引") :
Cells.EntireColumn.AutoFit
Call reAppSet
If Err.Number Then
MsgBox Err.Description
Else
MsgBox "匯總完成。"
End If
End?Sub
'用戶選擇文件夾路徑
Function getStrPath() As String
Dim strPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show Then
strPath = .SelectedItems(1)
Else '如用戶為選中文件夾則退出
Exit Function
End If
End With
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
getStrPath = strPath
End Function
'獲取用戶輸入的標(biāo)題行數(shù)
Function getTitCount()
Dim intTitCount
intTitCount = InputBox("請(qǐng)輸入標(biāo)題行的行數(shù)", _
Title:="公眾號(hào)Excel星球", _
Default:=1)
If StrPtr(intTitCount) = False Then
getTitCount = "錯(cuò)誤"
Exit Function
End If
If IsNumeric(intTitCount) = False Then
MsgBox "標(biāo)題行的行數(shù)只能輸入數(shù)字。"
getTitCount = "錯(cuò)誤"
Exit Function
End If
If intTitCount < 0 Then
MsgBox "標(biāo)題行數(shù)不能為負(fù)數(shù)。"
getTitCount = "錯(cuò)誤"
Exit Function
End If
getTitCount = intTitCount
End Function
'判斷是否文本格式,由前10行決定
Sub DataFormat(ByRef aData As Variant, shtSum As Worksheet)
Dim i As Long, j As Long
Dim vnt, strADS
For j = 1 To UBound(aData, 2) '遍歷列
For i = 1 To UBound(aData) '遍歷前10行
If i > 10 Then Exit For
vnt = aData(i, j)
If IsNumeric(vnt) Then '是否數(shù)值
If VarType(aData(i, j)) = 8 Then '是否文本
strADS = strADS & "," & Cells(1, j + 3).Address
Exit For
End If
End If
Next
Next
strADS = Mid(strADS, 2) '需要設(shè)置文本格式的單元格地址
If Len(strADS) Then
"@" =
End If
End Sub
'獲取文件名名單
Function GetWbFullNames(strPath As String)
Dim strName As String, strTemp As String
Dim aRes(), k As Long
strName = Dir(strPath & "*.*")
Do While strName <> ""
strTemp = Right(strName, 4)
If strTemp Like "*xls*" Or strTemp Like "*csv*" Then
k = k + 1
ReDim Preserve aRes(1 To k)
strPath & strName =
End If
strName = Dir()
Loop
GetWbFullNames = aRes
End Function
'創(chuàng)建匯總表
Sub CreateShtSum()
Dim sht As Worksheet
For Each sht In Worksheets
If sht.Name = "星光-匯總" Then sht.Delete
Next
, Sheets(1)
"星光-匯總" =
End Sub
'查詢有效數(shù)據(jù)最大行
Function GetLastRow(shtData As Worksheet)
GetLastRow = shtData.Cells.Find("*", _
LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
End Function
Sub disAppSet() '撤銷(xiāo)屏幕刷新
With Application
False =
False =
False =
False =
xlCalculationManual =
End With
End Sub
Sub reAppSet() '恢復(fù)屏幕刷新等
With Application
True =
True =
True =
True =
xlCalculationAutomatic =
End With
End Sub
代碼詳細(xì)解釋見(jiàn)注釋工作表函數(shù)怎么設(shè)置,概要說(shuō)明如下。
第9至第10行代碼,調(diào)用函數(shù)過(guò)程,打開(kāi)文件瀏覽對(duì)話框,允許用戶選擇任意文件夾;如果用戶未選取文件夾,則退出程序。
第11至第12行代碼工作表函數(shù)怎么設(shè)置,調(diào)用函數(shù)過(guò)程,通過(guò)語(yǔ)句,獲取用戶設(shè)置的標(biāo)題行的行數(shù)。
第13行代碼,函數(shù)過(guò)程,利用Dir語(yǔ)句獲取指定文件夾下符合匯總條件的文件路徑數(shù)組集合。
第14行代碼取消屏幕刷新等系統(tǒng)設(shè)置。
第15行代碼在當(dāng)前工作簿創(chuàng)建一張名為"星光-匯總"的工作表。
第18至第44行代碼遍歷文件。
其中第19行代碼打開(kāi)工作簿,第20至第42行代碼遍歷工作簿內(nèi)的工作表。第22行代碼判斷工作表是否非空,如果不為空,則繼續(xù)判斷是否匯總的首張工作表。如果是首張工作表,則根據(jù)前10行數(shù)據(jù)調(diào)整匯總工作表的單元格格式,避免文本型數(shù)值變形。
第33至39行代碼將數(shù)組的數(shù)據(jù)寫(xiě)入?yún)R總工作表,并在前3列寫(xiě)入數(shù)據(jù)來(lái)源的工作簿名稱、工作表名稱以及工作表序號(hào)。
第44行代碼關(guān)閉工作簿,執(zhí)行下一個(gè)文件。
第48行代碼恢復(fù)屏幕刷新等系統(tǒng)設(shè)置。
第49至第53行代碼彈窗告知用戶匯總結(jié)果。
……
沒(méi)了。下期再見(jiàn)。
代碼示例文件及練習(xí)文件下載,百度網(wǎng)盤(pán)▼
鏈接:
提取碼: bxi6