简体   繁体   中英

Is there a better way to loop through and process files in a directory?

I have a directory with a set of files that I want to be able to process. Once I'm able to acquire the file set using an FSO object, I can get the file names and can even output to a message box.

Once I pass the full path of each file in the loop however, I run into a '424: Object required' error. Am I missing something? Is there something within the code that's not quite accepting the value as I intended.

Any help in this would be appreciated. Thank you very much.

UPDATE : I finally realized where my problem was thanks to @Dorian below. The main issue stemmed from the error handling code. I have issues with error handling in general in VBA. Thanks again.

Public Sub getAllCSVFiles()
Dim oFSO As Object
Dim oFolder As Object
Dim oFile As Object
Dim i As Integer
Dim fileName As String

Set oFSO = CreateObject("Scripting.FileSystemObject")

Set oFolder = oFSO.GetFolder(dataImportSourceLocationFolder())
On Error GoTo ErrorMessage
For Each oFile In oFolder.Files
    If InStr(oFile.Name, "csv") Then
        MsgBox (oFile)
        fileName = oFile
        If InStr(fileName, "EXTDATA1") <> 0 Then
            Call loadCSVData(fileName, "EXTDATA1")
        ElseIf InStr(fileName, "EXTDATA2") <> 0 Then
            Call loadCSVData(fileName, "EXTDATA2")
        ElseIf InStr(fileName, "EXTDATA3") <> 0 Then
            Call loadCSVData(fileName, "EXTDATA3")
        End If
    End If
Next oFile
Application.StatusBar = "File Processing Completed"
ErrorMessage:
MsgBox Err.Source & vbCrLf & vbCrLf & Err.Description, vbCritical, "Error Importing Data"
End Sub

'This subroutine gets the csv file passed from getAllCSVs()
'
Private Sub loadCSVData(ByVal sourceFile As String, ByVal destinationWorksheet As String)
    Dim destinationCell As Range
    Dim destinationSheet As Excel.Worksheet
    On Error GoTo errMsg
    'Set destinationSheet = Worksheets("CSVDataImport") 'predefined worksheet.
    Set destinationSheet = Worksheets(destinationWorksheet)
    'Set destinationCell = destinationSheet.Range("A" & blankRow(destinationSheet))
    Set destinationCell = destinationSheet.Range("A" & blankRow(destinationSheet))
    With destinationSheet.QueryTables.Add(Connection:="TEXT;" & _
        sourceFile, Destination:=destinationCell)
        .FieldNames = False
        .RowNumbers = False
        .FieldNames = True
        .RefreshOnFileOpen = False
       .RefreshPeriod = 0
        .TextFileStartRow = 2
        .TextFileCommaDelimiter = True
        .TextFileColumnDataTypes = Array(1, 1, 4, 1, 1, 1, 1, 1)
        .Refresh BackgroundQuery:=False
    End With
errMsg:
    MsgBoxErr.Description , vbCritical, Err.Number
End Sub

'This function gets the first blank row in the worksheet provided by the ws Worksheet Argument
Function blankRow(ws As Worksheet) As Long
    With ws
        blankRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
    End With
End Function

'This function gets the data location by allowing the user to select
'the location of the data files

Function dataImportSourceLocationFolder() As String
    Dim fldr As FileDialog
    Dim sItem As String
    Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
    With fldr
        .Title = "Select the location of the CSV Files:"
        .AllowMultiSelect = False
        .InitialFileName = Application.DefaultFilePath
        If .Show <> -1 Then GoTo NextCode
        sItem = .SelectedItems(1)
    End With
NextCode:
    dataImportSourceLocationFolder = sItem
    Set fldr = Nothing
End Function

oFile is a Scripting.File object so you need to pass the name properly.

filename = oFile.Path

You will find it easier if you set a reference to Windows.Scripting then

Dim oFSO as Scripting.FileSystemObject
Set oFSO = New Scripting.FileSystemObject
Dim oFile as Scripting.File

As you would then be able to see the properties of the oFile object.

Give this a try , you did some mistake in code but now I am facing the issue with memory maybe it's because I don't have the good .csv file...

I am waiting for your feedbacks !

Public Sub getAllCSVFiles()
Dim oFSO As Object
Dim oFolder As Object
Dim oFile As Object
Dim i As Integer
Dim fileName As String

Set oFSO = CreateObject("Scripting.FileSystemObject")

Set oFolder = oFSO.GetFolder(dataImportSourceLocationFolder())
On Error GoTo ErrorMessage
For Each oFile In oFolder.Files
Debug.Print oFile.Name
    If InStr(oFile.Name, "csv") Then
        MsgBox (oFile)
        fileName = oFile
        If InStr(fileName, "EXTDATA1") <> 0 Then
            Call loadCSVData(fileName, "EXTDATA1")
        ElseIf InStr(fileName, "EXTDATA2") <> 0 Then
            Call loadCSVData(fileName, "EXTDATA2")
        ElseIf InStr(fileName, "EXTDATA3") <> 0 Then
            Call loadCSVData(fileName, "EXTDATA3")
        End If
    End If
Next oFile
Application.StatusBar = "File Processing Completed"
ErrorMessage:
MsgBox Err.Source & vbCrLf & vbCrLf & Err.Description, vbCritical, "Error Importing Data"
End Sub

'This subroutine gets the csv file passed from getAllCSVs()
'
Private Sub loadCSVData(ByVal sourceFile As String, ByVal destinationWorksheet As String)
    Dim destinationCell As Range
    Dim destinationSheet As Excel.Worksheet
    'On Error GoTo errMsg
    'Set destinationSheet = Worksheets("CSVDataImport") 'predefined worksheet.
    Set destinationSheet = Worksheets(destinationWorksheet)
    Debug.Print blankRow(destinationSheet)
    Set destinationCell = destinationSheet.Range("A" & blankRow(destinationSheet))
    With destinationSheet.QueryTables.Add(Connection:="TEXT;" & _
        sourceFile, Destination:=destinationCell)
        .FieldNames = False
        .RowNumbers = False
        .FieldNames = True
        .RefreshOnFileOpen = False
       .RefreshPeriod = 0
        .TextFileStartRow = 2
        .TextFileCommaDelimiter = True
        .TextFileColumnDataTypes = Array(1, 1, 4, 1, 1, 1, 1, 1)
        .Refresh BackgroundQuery:=False
    End With
errMsg:
    MsgBoxErr.Description , vbCritical, Err.Number
End Sub

'This function gets the first blank row in the worksheet provided by the ws Worksheet Argument
Function blankRow(ws As Worksheet) As Long
    With ws
        blankRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
    End With
End Function

'This function gets the data location by allowing the user to select
'the location of the data files
Function dataImportSourceLocationFolder() As String
    Dim fldr As FileDialog
    Dim sItem As String
    Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
    With fldr
        .Title = "Select the location of the CSV Files:"
        .AllowMultiSelect = False
        .InitialFileName = Application.DefaultFilePath
        If .Show <> -1 Then GoTo NextCode
        sItem = .SelectedItems(1) & "\"
    End With
NextCode:
    dataImportSourceLocationFolder = sItem
    Set fldr = Nothing
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM