0

I am trying to loop through a specific directory's sub folders and import specified columns from .CSV files.

I have a coding solution that does not loop through the sub folders.

Instead, it includes a Worksheet with File Path, File Destination and Column Number in three separate columns, but the sub folders are dynamic. They are changing in name and quantity.

File Path sheet:

File Path Sheet

Code:

Dim DL As Worksheet
Dim DFI As Worksheet

Set DL = ThisWorkbook.Sheets("DataList")
Set DFI = ThisWorkbook.Sheets("DataFeedInput")

    DL.Rows("$3:$202").ClearContents

        With DL.QueryTables.Add(Connection:="TEXT;C:\Users\ ... \MQL4\Files\Hist_#Corn_1440.csv", Destination:=Range("$A$3"))
            .Name = "Hist_#Corn_1441"
            .FieldNames = True
            .RowNumbers = False
            .FillAdjacentFormulas = False
            .PreserveFormatting = True
            .RefreshOnFileOpen = False
            .RefreshStyle = xlInsertDeleteCells
            .SavePassword = False
            .SaveData = True
            .AdjustColumnWidth = True
            .RefreshPeriod = 0
            .TextFilePromptOnRefresh = False
            .TextFilePlatform = 866
            .TextFileStartRow = 1
            .TextFileParseType = xlDelimited
            .TextFileTextQualifier = xlTextQualifierDoubleQuote
            .TextFileConsecutiveDelimiter = False
            .TextFileTabDelimiter = True
            .TextFileSemicolonDelimiter = False
            .TextFileCommaDelimiter = True
            .TextFileSpaceDelimiter = False
            .TextFileColumnDataTypes = Array(9, 1, 9, 9, 9, 9, 9, 1, 9, 9, 9, 9, 9, 9, 9)
            .TextFileTrailingMinusNumbers = True
            .Refresh BackgroundQuery:=False
        End With

    Dim i As Integer

    For i = 4 To 642

    Dim FileName As String
    Dim OutputSheet As String
    Dim ColNumber As String

        FileName = DFI.Range("B" & i).Value
        OutputSheet = DFI.Range("C" & i).Value
        ColNumber = DFI.Range("D" & i).Value

            With DL.QueryTables.Add(Connection:="TEXT;" & FileName, Destination:=DL.Range(ColNumber & "3"))
                 .FieldNames = True
                 .RowNumbers = False
                 .FillAdjacentFormulas = False
                 .PreserveFormatting = True
                 .RefreshOnFileOpen = False
                 .RefreshStyle = xlInsertDeleteCells
                 .SavePassword = False
                 .SaveData = True
                 .AdjustColumnWidth = True
                 .RefreshPeriod = 0
                 .TextFilePromptOnRefresh = False
                 .TextFilePlatform = 866
                 .TextFileStartRow = 1
                 .TextFileParseType = xlDelimited
                 .TextFileTextQualifier = xlTextQualifierDoubleQuote
                 .TextFileConsecutiveDelimiter = False
                 .TextFileTabDelimiter = True
                 .TextFileSemicolonDelimiter = False
                 .TextFileCommaDelimiter = True
                 .TextFileSpaceDelimiter = False
                 .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 9, 9, 1, 9, 9, 9, 9, 9, 9, 9)
                 .TextFileTrailingMinusNumbers = True
                 .Refresh BackgroundQuery:=True
             End With

    Next i

        DL.Cells.EntireColumn.AutoFit

The problem with this approach is that if a .CSV file is not downloaded from the external source, I get an error stating that the file is missing.

Another issue is that this approach takes decades to finish the task.

I am looking for a solution that is not dependent on the File Path sheet, loops through the sub folders and extracts solely column 6 from the .CSV file.

sub folders of Directory

In each of these folders I have one .CSV file:

.CSV file in sub folder(s)

I need to loop through each of them and create connection to Excel sheet, while importing solely column 6 from the .CSV.

Edit 1:

This is the File Path to the Sub Folders:

C:\Users\Betty\AppData\Roaming\MetaQuotes\Terminal\B4D9BCD10BE9B5248AFCB2BE2411BA10\MQL4\Files\Export_History

Edit 2:

What I learned so far, with the help of @Jeeped, is that I can loop through the folders with FileSystemObject, probably, go in to each of the folders and import column 6 from the .CSV.

It is quite difficult for me to get into how to merge the loop trough the folders and the .CSV import. If you can give me a hand with an outline procedure, I think I will be able to put it together and add it as edit to this question, if needed.

Edit 3:

I reckon I can use something of such for completing the task:

Code from @Tim Williams' answer to this question -> VBA macro that search for file in multiple subfolders

Sub GetSubFolders()

    Dim fso As New FileSystemObject
    Dim f As Folder, sf As Folder

    Set f = fso.GetFolder("file path")
    For Each sf In f.SubFolders

        'Use a loop to import only column 6 from every .CSV file in sub folders 

    Next

End Sub
Community
  • 1
  • 1
I. Я. Newb
  • 329
  • 1
  • 12
  • 1
    What does your example code have to do with looping through subfolders? –  Feb 23 '18 at 03:15
  • @Jeeped: I'll edit the question, so that is clearer, but generally, I need to replace what I have currently as a solution (i.e. the solution with the File Path sheet) and replace it with a solution hat loops trough the sub folders and imports solely column 6 from the .CSV. – I. Я. Newb Feb 23 '18 at 03:18
  • Ah! So you really just want someone to write subfolder search code for you and you thought an unrelated code dump from the macro recorder would assist you in that. Why didn't you just say so? –  Feb 23 '18 at 03:25
  • @Jepeed: I am sorry If I have insulted you in any way by asking this question. What I did is to present what I am looking for, present the issues and look for a solution of the issue. The "dumped" code from the Macro Recorder is not the best solution, so I am looking for a better one. I have no idea how to loop trough the sub folders, while importing solely column 6 from the .CSV. I am only looking for help. – I. Я. Newb Feb 23 '18 at 03:31
  • [vba loop subfolders](https://www.google.ca/search?q=vba+loop+subfolder) yields 67,000 responses. –  Feb 23 '18 at 03:33
  • @Jeeped: Also, if you look closely in the second part of the code you will see that there are a few modifications of what the Macro Recorder spat out. It is not like going to Stack Overflow without even trying, looking for someone to code it for me. Learner here, not a copy cat. – I. Я. Newb Feb 23 '18 at 03:33
  • @Jeeped: So far, so good. Saw that already, but what about the other part of the code where only column 6 has to be imported from the .CSV file? – I. Я. Newb Feb 23 '18 at 03:35
  • 1
    [QueryTable.TextFileColumnDataTypes Property](https://msdn.microsoft.com/en-us/vba/excel-vba/articles/querytable-textfilecolumndatatypes-property-excel) tells there is an **xlSkipColumn** option. –  Feb 23 '18 at 03:41
  • @Jeeped: Helpful. However I still can't understand how to bond the two pieces together. – I. Я. Newb Feb 23 '18 at 03:52
  • @Jeeped: Got it! https://stackoverflow.com/questions/34485089/vba-only-import-selected-columns-of-a-csv-file?rq=1 – I. Я. Newb Feb 23 '18 at 04:30
  • @Jeeped: Thank you! – I. Я. Newb Feb 23 '18 at 04:31
  • @Jeeped: What I understood so far, is that I need to merge the Loop trough files and the import of the .CSVs. But I need (maybe) one more loop for the import of the .CSV in the next blank column. Can you please give me an outline procedure of how to merge the loop trough folders with `FileSystemObject` and the .CSV import? Please, note that I need to import solely column 6 from the .CSV file and in the next blank column. Thank you in advance. – I. Я. Newb Feb 24 '18 at 13:55
  • 1
    Have you looked at Ron De Bruin's code for looping folders and subfolders? Or explored the FileSystemObject? – QHarr Feb 24 '18 at 15:40
  • @QHarr: I consider `.FileSystemObject` to be simple enough to understand and I think I could put together a code with it. I haven't stumbled on Ron De Brun's approach, but I will get into it and take it under consideration. Thank you. – I. Я. Newb Feb 24 '18 at 15:56
  • @QHarr: I have considered `.FileSystemObject` and currently this is a solution simple enough for me to understand and I think I can put it together with a little help from Stack Overflow Users like you. I have not came across Ron De Brun's aproach, but I will look into it and will take it under consideration. Please, take a look at Edit 3 of the question. – I. Я. Newb Feb 24 '18 at 17:01
  • 1
    https://chandoo.org/forum/threads/vba-to-search-copy-folders-and-subfolders-for-a-specific-worksheet-in-all-macro-enabled-workbooks.21826/ – QHarr Feb 24 '18 at 17:05
  • @QHarr: Looking into it. – I. Я. Newb Feb 24 '18 at 17:28
  • @QHarr: Can't say that I really understand this approach... – I. Я. Newb Feb 24 '18 at 17:49
  • 1
    Ok. There is quite a lot of code to understand. What I thought you might be able to extract from it, is how to get a list of files from a folder, including its subfolders. I think that might be the first thing to try and get a handle on. – QHarr Feb 24 '18 at 17:54
  • @QHarr: I'll spend some more time on your suggestion. I think I found this part in particular in the code that you suggested. I'll think on it. However, just out of curiosity, do you think that the code in **Edit 3** with a `With HDaER.QueryTable. Add(Connection:= "C:\\....."), Destination:= HDaER.Cells(1, o)` Loop trough columns, with `o=HDaER.Cells(1, HDaER.Columns.Count).End (xlToLeft).Columns +1`, will do the work? I want to see if I have the right way of handling this? – I. Я. Newb Feb 24 '18 at 18:09
  • 1
    tbh There is a lot going on in there and I would need to dedicate a block of time to unpicking...Monday is likely the earliest I could devote that sort of time. – QHarr Feb 24 '18 at 18:14
  • @QHarr: No worries! You don't even have to do that. Much appreciation for the effort that you are putting in so far! Some careful guidance and pointers will both get the job done and enhance my VBA knowledge and experience. – I. Я. Newb Feb 24 '18 at 18:29
  • @QHarr: Thank you for the guidance. I managed to get it working with `FileSystemObject`, as you recommended. Unfortunately Ron de Brun's approach was a bit too much of a mouthful for me, and I'm a bit of micro code oriented, so I am always looking to get the optimal goal from a tiny code. However I have saved the literature recommended by you and will look into it further in another point of time. Thank you – I. Я. Newb Mar 05 '18 at 19:35
  • 1
    Well done. I am away from tomorrow but will put some time in to look. Note that working code may be a candidate for the code review site which has some super code gurus who review your code. So that is a really good place to post your code ensuring your read the guidance on posting first. The key thing there is to say what the code does. Then be open to the review. – QHarr Mar 05 '18 at 19:38

1 Answers1

0

@QHarr: Special thanks for the guidance!

After looking in to the FileSystemObject method for the purpose of looping trough Sub Folders and importing column 6 from a .CSV file in each Sub Folder in the next blank column in Worksheet HDaER, I managed to put together this code:

    Dim fso As Object
    Dim folder As Object
    Dim subfolders As Object
    Dim CurrFile As Object
    Dim HDaER As Worksheet

With Application
    .ScreenUpdating = False
    .EnableEvents = False
    .Calculation = xlCalculationManual
End With

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.GetFolder("C:\Users\Betty\AppData\Roaming\MetaQuotes\Terminal\B4D9BCD10BE9B5248AFCB2BE2411BA10\MQL4\Files\Export_History\")
    Set subfolders = folder.subfolders
    Set HDaER = Sheets("HDaER")

'   IMPORT Col 6 FROM EACH .CSV FILE IN EACH SubFolder    
    LastCol = HDaER.Cells(2, HDaER.Columns.Count).End(xlToLeft).Column

    For Each subfolders In subfolders

    Set CurrFile = subfolders.Files
        For Each CurrFile In CurrFile
            With HDaER.QueryTables.Add(Connection:="TEXT;" & CurrFile, Destination:=HDaER.Cells(2, LastCol + 1))
                 .TextFileStartRow = 1
                 .TextFileParseType = xlDelimited
                 .TextFileConsecutiveDelimiter = False
                 .TextFileTabDelimiter = False
                 .TextFileSemicolonDelimiter = False
                 .TextFileCommaDelimiter = True
                 .TextFileSpaceDelimiter = True
                 .TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9)
                 .Refresh BackgroundQuery:=False
                 LastCol = LastCol + 1
            End With
        Next
    Next

'   REMOVE SOURCE CONNECTIONS
    For Each Connection In HDaER.QueryTables
        Connection.Delete
    Next Connection

'   FREE MEMORY 
    Set fso = Nothing
    Set folder = Nothing
    Set subfolders = Nothing

With Application
    .ScreenUpdating = True
    .EnableEvents = True
    .Calculation = xlCalculationAutomatic
End With

The Sub Folders that I currently have in the general Folder (Export_History) are:

Sub Folders in general folder "Export_History"

The output that I get from the code is:

Loop output

@QHarr: Please, let me know if you see anything that can be improved, especially in the QueryTables.Add part.

I. Я. Newb
  • 329
  • 1
  • 12