VBA를 사용하여 폴더의 파일을 순환하시겠습니까?
엑셀 2010에서 vba를 사용하여 디렉토리의 파일을 루프하고 싶습니다.
루프에서 필요한 것은 다음과 같습니다.
- 파일 이름 및
- 파일이 포맷된 날짜.
폴더에 50개 이하의 파일이 있으면 정상적으로 작동하는 다음 항목을 코딩했습니다. 그렇지 않으면 엄청나게 느립니다(파일이 10000개 이상인 폴더에서 작업하려면 필요합니다).이 코드의 유일한 문제는 검색 작업이file.name
매우 많은 시간이 걸립니다.
작동하지만 속도가 너무 느린 코드(100개 파일당 15초):
Sub LoopThroughFiles()
Dim MyObj As Object, MySource As Object, file As Variant
Set MySource = MyObj.GetFolder("c:\testfolder\")
For Each file In MySource.Files
If InStr(file.name, "test") > 0 Then
MsgBox "found"
Exit Sub
End If
Next file
End Sub
문제 해결:
- 나의 문제는 아래의 해결책으로 해결되었습니다.
Dir
특정 방식(15000개 파일의 경우 20초) 및 명령을 사용하여 타임스탬프를 확인합니다.FileDateTime
. - 20초 미만의 다른 응답을 고려하면 1초 미만으로 줄어듭니다.
Dir
와일드카드를 사용하여 필터를 추가하면 큰 차이를 만들 수 있습니다.test
각 파일을 테스트하는 것을 방지합니다.
Sub LoopThroughFiles()
Dim StrFile As String
StrFile = Dir("c:\testfolder\*test*")
Do While Len(StrFile) > 0
Debug.Print StrFile
StrFile = Dir
Loop
End Sub
Dir는 매우 빠른 것 같습니다.
Sub LoopThroughFiles()
Dim MyObj As Object, MySource As Object, file As Variant
file = Dir("c:\testfolder\")
While (file <> "")
If InStr(file, "test") > 0 Then
MsgBox "found " & file
Exit Sub
End If
file = Dir
Wend
End Sub
대신 함수로 해석하면 다음과 같습니다.
'#######################################################################
'# LoopThroughFiles
'# Function to Loop through files in current directory and return filenames
'# Usage: LoopThroughFiles ActiveWorkbook.Path, "txt" 'inputDirectoryToScanForFile
'# https://stackoverflow.com/questions/10380312/loop-through-files-in-a-folder-using-vba
'#######################################################################
Function LoopThroughFiles(inputDirectoryToScanForFile, filenameCriteria) As String
Dim StrFile As String
'Debug.Print "in LoopThroughFiles. inputDirectoryToScanForFile: ", inputDirectoryToScanForFile
StrFile = Dir(inputDirectoryToScanForFile & "\*" & filenameCriteria)
Do While Len(StrFile) > 0
Debug.Print StrFile
StrFile = Dir
Loop
End Function
Dir 함수가 가는 길이지만 문제는 여기에 언급된 것처럼 아래쪽을 향해 함수를 재귀적으로 사용할 수 없다는 것입니다.
제가 이 일을 처리하는 방법은Dir
대상 폴더의 모든 하위 폴더를 가져와 배열에 로드한 다음 배열을 재귀 함수로 전달하는 기능입니다.
이것을 달성하기 위해 제가 쓴 클래스가 있습니다. 필터를 검색하는 기능이 포함되어 있습니다. (헝가리 표기법을 용서해야 할 것입니다. 이것은 유행할 때 쓰여졌습니다.)
Private m_asFilters() As String
Private m_asFiles As Variant
Private m_lNext As Long
Private m_lMax As Long
Public Function GetFileList(ByVal ParentDir As String, Optional ByVal sSearch As String, Optional ByVal Deep As Boolean = True) As Variant
m_lNext = 0
m_lMax = 0
ReDim m_asFiles(0)
If Len(sSearch) Then
m_asFilters() = Split(sSearch, "|")
Else
ReDim m_asFilters(0)
End If
If Deep Then
Call RecursiveAddFiles(ParentDir)
Else
Call AddFiles(ParentDir)
End If
If m_lNext Then
ReDim Preserve m_asFiles(m_lNext - 1)
GetFileList = m_asFiles
End If
End Function
Private Sub RecursiveAddFiles(ByVal ParentDir As String)
Dim asDirs() As String
Dim l As Long
On Error GoTo ErrRecursiveAddFiles
'Add the files in 'this' directory!
Call AddFiles(ParentDir)
ReDim asDirs(-1 To -1)
asDirs = GetDirList(ParentDir)
For l = 0 To UBound(asDirs)
Call RecursiveAddFiles(asDirs(l))
Next l
On Error GoTo 0
Exit Sub
ErrRecursiveAddFiles:
End Sub
Private Function GetDirList(ByVal ParentDir As String) As String()
Dim sDir As String
Dim asRet() As String
Dim l As Long
Dim lMax As Long
If Right(ParentDir, 1) <> "\" Then
ParentDir = ParentDir & "\"
End If
sDir = Dir(ParentDir, vbDirectory Or vbHidden Or vbSystem)
Do While Len(sDir)
If GetAttr(ParentDir & sDir) And vbDirectory Then
If Not (sDir = "." Or sDir = "..") Then
If l >= lMax Then
lMax = lMax + 10
ReDim Preserve asRet(lMax)
End If
asRet(l) = ParentDir & sDir
l = l + 1
End If
End If
sDir = Dir
Loop
If l Then
ReDim Preserve asRet(l - 1)
GetDirList = asRet()
End If
End Function
Private Sub AddFiles(ByVal ParentDir As String)
Dim sFile As String
Dim l As Long
If Right(ParentDir, 1) <> "\" Then
ParentDir = ParentDir & "\"
End If
For l = 0 To UBound(m_asFilters)
sFile = Dir(ParentDir & "\" & m_asFilters(l), vbArchive Or vbHidden Or vbNormal Or vbReadOnly Or vbSystem)
Do While Len(sFile)
If Not (sFile = "." Or sFile = "..") Then
If m_lNext >= m_lMax Then
m_lMax = m_lMax + 100
ReDim Preserve m_asFiles(m_lMax)
End If
m_asFiles(m_lNext) = ParentDir & sFile
m_lNext = m_lNext + 1
End If
sFile = Dir
Loop
Next l
End Sub
Dir
다른 폴더의 파일을 처리하고 처리할 때 기능의 초점이 쉽게 사라집니다.
부품에 대한 결과가 더 좋습니다.FileSystemObject
.
전체 예는 다음과 같습니다.
http://www.xl-central.com/list-files-fso.html
Visual Basic Editor에서 Microsoft 스크립팅 런타임에 대한 참조를 설정하는 것을 잊지 마십시오(도구 > 참조 사용).
한 번 해보세요!
이것을 사용해 보세요. (LINK)
Private Sub CommandButton3_Click()
Dim FileExtStr As String
Dim FileFormatNum As Long
Dim xWs As Worksheet
Dim xWb As Workbook
Dim FolderName As String
Application.ScreenUpdating = False
Set xWb = Application.ThisWorkbook
DateString = Format(Now, "yyyy-mm-dd hh-mm-ss")
FolderName = xWb.Path & "\" & xWb.Name & " " & DateString
MkDir FolderName
For Each xWs In xWb.Worksheets
xWs.Copy
If Val(Application.Version) < 12 Then
FileExtStr = ".xls": FileFormatNum = -4143
Else
Select Case xWb.FileFormat
Case 51:
FileExtStr = ".xlsx": FileFormatNum = 51
Case 52:
If Application.ActiveWorkbook.HasVBProject Then
FileExtStr = ".xlsm": FileFormatNum = 52
Else
FileExtStr = ".xlsx": FileFormatNum = 51
End If
Case 56:
FileExtStr = ".xls": FileFormatNum = 56
Case Else:
FileExtStr = ".xlsb": FileFormatNum = 50
End Select
End If
xFile = FolderName & "\" & Application.ActiveWorkbook.Sheets(1).Name & FileExtStr
Application.ActiveWorkbook.SaveAs xFile, FileFormat:=FileFormatNum
Application.ActiveWorkbook.Close False
Next
MsgBox "You can find the files in " & FolderName
Application.ScreenUpdating = True
End Sub
언급URL : https://stackoverflow.com/questions/10380312/loop-through-files-in-a-folder-using-vba
'programing' 카테고리의 다른 글
mongoDB 레코드 일괄 찾기(mongoid 루비 어댑터 사용) (0) | 2023.05.23 |
---|---|
Bash에서 플래그가 있는 인수를 가져오는 방법 (0) | 2023.05.23 |
Postgre에 사용자 정의 유형이 이미 있는지 확인합니다.SQL (0) | 2023.05.23 |
로컬 리포지토리 git을 삭제하려면 어떻게 해야 합니까? (0) | 2023.05.23 |
목록을 주문하려면 어떻게 해야 합니까? (0) | 2023.05.23 |