フォルダー内のすべてのExcelファイルの名前を取得してから、各ファイルに変更を加える必要があります。 「変更を加える」部分が整理されました。 1つのフォルダー内の.xlsx
ファイルのリストを取得する方法、たとえばD:\Personal
を取得して、ストリング配列に保存する方法はありますか。
次に、ファイルのリストを繰り返し処理し、使用できると判断した各ファイルでマクロを実行する必要があります。
Filepath = "D:\Personal\"
For Each i in FileArray
Workbooks.Open(Filepath+i)
Next
this を見ましたが、ファイルを開くことができなかったため、Variant
形式で名前が保存されていました。
要するに、VBAを使用して特定のフォルダー内のExcelファイル名のリストを取得するにはどうすればよいですか?
パスを取得して、フォルダー内のファイル名の配列を返す関数は、これでうまくいくかもしれません。 ifステートメントを使用して、配列をループするときにExcelファイルのみを取得できます。
Function listfiles(ByVal sPath As String)
Dim vaArray As Variant
Dim i As Integer
Dim oFile As Object
Dim oFSO As Object
Dim oFolder As Object
Dim oFiles As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(sPath)
Set oFiles = oFolder.Files
If oFiles.Count = 0 Then Exit Function
ReDim vaArray(1 To oFiles.Count)
i = 1
For Each oFile In oFiles
vaArray(i) = oFile.Name
i = i + 1
Next
listfiles = vaArray
End Function
インデックス番号でファイルオブジェクトのファイルにアクセスできればいいのですが、VBAでは何らかの理由で壊れているようです(バグ?)。
組み込みのDir関数またはFileSystemObjectを使用できます。
Dir関数: VBA:Dir Function
FileSystemObject: VBA:FileSystemObject-Files Collection
それぞれに長所と短所があります。
Dir関数
Dir関数は、ファイルのリストを取得するための組み込みの軽量メソッドです。それを使用する利点は次のとおりです。
秘Theは、パラメータを指定して呼び出す場合と指定しない場合の違いを理解することです。以下に、非常に簡単な例を示します。
Public Sub ListFilesDir(ByVal sPath As String, Optional ByVal sFilter As String)
Dim sFile As String
If Right(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
If sFilter = "" Then
sFilter = "*.*"
End If
'call with path "initializes" the dir function and returns the first file name
sFile = Dir(sPath & sFilter)
'call it again until there are no more files
Do Until sFile = ""
Debug.Print sFile
'subsequent calls without param return next file name
sFile = Dir
Loop
End Sub
ループ内のファイルのいずれかを変更すると、予測できない結果が得られます。ファイルに対して操作を行う前に、すべての名前を文字列の配列に読み込むことをお勧めします。以下は、前の例に基づいた例です。これは、文字列配列を返す関数です。
Public Function GetFilesDir(ByVal sPath As String, _
Optional ByVal sFilter As String) As String()
'dynamic array for names
Dim aFileNames() As String
ReDim aFileNames(0)
Dim sFile As String
Dim nCounter As Long
If Right(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
If sFilter = "" Then
sFilter = "*.*"
End If
'call with path "initializes" the dir function and returns the first file
sFile = Dir(sPath & sFilter)
'call it until there is no filename returned
Do While sFile <> ""
'store the file name in the array
aFileNames(nCounter) = sFile
'subsequent calls without param return next file
sFile = Dir
'make sure your array is large enough for another
nCounter = nCounter + 1
If nCounter > UBound(aFileNames) Then
'preserve the values and grow by reasonable amount for performance
ReDim Preserve aFileNames(UBound(aFileNames) + 255)
End If
Loop
'truncate the array to correct size
If nCounter < UBound(aFileNames) Then
ReDim Preserve aFileNames(0 To nCounter - 1)
End If
'return the array of file names
GetFilesDir = aFileNames()
End Function
ファイルシステムオブジェクト
ファイルシステムオブジェクトは、ファイルを操作するためのオブジェクトモデルをサポートするIO操作のライブラリです。このアプローチの長所:
「Windows Script Host Object Model」(または「Windows Scripting Runtime」)への参照を追加して、次のようにオブジェクトを宣言できます。
Public Sub ListFilesFSO(ByVal sPath As String)
Dim oFSO As FileSystemObject
Dim oFolder As Folder
Dim oFile As File
Set oFSO = New FileSystemObject
Set oFolder = oFSO.GetFolder(sPath)
For Each oFile In oFolder.Files
Debug.Print oFile.Name
Next 'oFile
Set oFile = Nothing
Set oFolder = Nothing
Set oFSO = Nothing
End Sub
インテリセンスが必要ない場合は、参照を設定せずにそのようにすることができます。
Public Sub ListFilesFSO(ByVal sPath As String)
Dim oFSO As Object
Dim oFolder As Object
Dim oFile As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(sPath)
For Each oFile In oFolder.Files
Debug.Print oFile.Name
Next 'oFile
Set oFile = Nothing
Set oFolder = Nothing
Set oFSO = Nothing
End Sub
Dim iIndex as Integer
Dim ws As Excel.Worksheet
Dim wb As Workbook
Dim strPath As String
Dim strFile As String
strPath = "D:\Personal\"
strFile = Dir(strPath & "*.xlsx")
Do While strFile <> ""
Set wb = Workbooks.Open(Filename:=strPath & strFile)
For iIndex = 1 To wb.Worksheets.count
Set ws = wb.Worksheets(iIndex)
'Do something here.
Next iIndex
strFile = Dir 'This moves the value of strFile to the next file.
Loop
必要なのがファイル拡張子のないファイル名だけである場合
Dim fileNamesCol As New Collection
Dim MyFile As Variant 'Strings and primitive data types aren't allowed with collection
filePath = "c:\file directory" + "\"
MyFile = Dir$(filePath & "*.xlsx")
Do While MyFile <> ""
fileNamesCol.Add (Replace(MyFile, ".xlsx", ""))
MyFile = Dir$
Loop
Excelワークシートに出力するには
Dim myWs As Worksheet: Set myWs = Sheets("SheetNameToDisplayTo")
Dim ic As Integer: ic = 1
For Each MyFile In fileNamesCol
myWs.Range("A" & ic).Value = fileNamesCol(ic)
ic = ic + 1
Next MyFile
主にここで詳述する手法に基づいています: https://wordmvp.com/FAQs/MacrosVBA/ReadFilesIntoArray.htm
賛成の回答については、結果の「listfiles」配列が配列式{CSE}で使用される場合、リストの値がすべて水平の行に表示されることを除いて、それが気に入りました。それらを垂直の列に表示するには、次のように単純に配列を2次元にします。
ReDim vaArray(1 To oFiles.Count, 0)
i = 1
For Each oFile In oFiles
vaArray(i, 0) = oFile.Name
i = i + 1
Next