2

I have a ton of .csv documents that are identical in their setup. They are all .csv and therefore all need simple formatting. My goal is quite simply to:

  1. Format them from .csv to regular columns (e.g., TextToColumns in Excel)
  2. Extract data from each separate file into one Excel sheet for further analysis

I have tried many things in VBA to loop through a folder with a macro, but I have not succeeded yet. In fact, none of the macros have done any changes whatsoever(?) I hope someone can help. One of my attempts is shown below.

Best, Karl

Dim filename As Variant
Dim a As Integer
a = 1

filename = Dir("/Users/karlemilthulstrup/Downloads/Test med kun 1Vp/Files*.csv")

Do While filename <> ""
Columns("A:A").Select
    Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
        Semicolon:=False, Comma:=True, Space:=False, Other:=False, FieldInfo _
        :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), _
        Array(7, 1), Array(8, 1), Array(9, 1), Array(10, 1), Array(11, 1), Array(12, 1)), _
        DecimalSeparator:=".", ThousandsSeparator:=",", TrailingMinusNumbers:= _
        True

Loop

End Sub

Edit:
OPs Eureka! code from comments:

Sub test6()
    Dim filename As Variant
    Dim a As Integer
    Dim MyFiles As String
    a = 1
    filename = Dir("/Users/karlemilthulstrup/Downloads/Test med kun 1Vp/Files.csv")
    Do While filename <> ""
        Workbooks.Open MyFiles
        ActiveWorkbook.Close SaveChanges:=True
        filename = Dir
    Loop
End Sub
Darren Bartrup-Cook
  • 18,362
  • 1
  • 23
  • 45
  • 3
    You have to actually open the file. – BigBen Nov 05 '21 at 14:13
  • 2
    In order to select something, you should open the file and then using `Dir()` to make the loop continuing... Do you try doing something on the csv file or firstly copy data in the existing workbook? If modify it, it should be saved and closed, before processing the next one. Selecting does not help, anyhow. It only consumes Excel resources, not bringing any benefit. – FaneDuru Nov 05 '21 at 14:14
  • 2
    Without opening the file you will never do any changes to it: check out: `application.workbooks.add` – Ike Nov 05 '21 at 14:14
  • 1
    Ah, of course! So then I would need to open all *.csv files in the folder. Something like this? 'Sub test6() Dim filename As Variant Dim a As Integer Dim MyFiles As String a = 1 filename = Dir("/Users/karlemilthulstrup/Downloads/Test med kun 1Vp/Files*.csv") Do While filename <> "" Workbooks.Open MyFiles ActiveWorkbook.Close SaveChanges:=True filename = Dir Loop End Sub' – Karl Emil Thulstrup Nov 05 '21 at 14:23
  • 2
    Power Query would be good for this. Data > Get Data > From File > From Folder – Darren Bartrup-Cook Nov 05 '21 at 14:30
  • 1
    Makes sense! Had not even thought about that. Thank you, will give it a shot @DarrenBartrup-Cook – Karl Emil Thulstrup Nov 05 '21 at 14:36
  • 2
    If you use the VBA route set your workbook to a variable - `Set WrkBk = Workbooks.Open(filename)` and `WrkBk.Worksheets("Sheet1").Columns("A:A").TextToColumns.....` and `WrkBk.Close SaveChanges:=True`. I wouldn't rely on `ActiveWorkbook` being the correct workbook. Obligatory link: [how-to-avoid-using-select-in-excel-vba](https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba) – Darren Bartrup-Cook Nov 05 '21 at 14:40
  • 2
    If the files are identical in format, it might be easier to consolidate them first (https://stackoverflow.com/questions/25596171/merge-multiple-csv-files-using-batch-file) then just import 1 file – Ryan Wildry Nov 05 '21 at 15:25
  • 1
    I concur, Power Query would be really good for this. Especially since everything is structured regularly and in a csv, you could probably use an ODBC connection but then you'd have to code all the manipulations. Once power query was set up, it would just be a matter of updated it with a click once you had new files in the directory. – Dan Nov 05 '21 at 19:25
  • Thanks for your tips! I am currently working on a Mac and I have not yet been succesful at importing from folders with Power Query. I believe I have to go the VBA route but I will certainly take your advise – Karl Emil Thulstrup Nov 08 '21 at 08:56

2 Answers2

0

If you need to import csv files in to Excel ranges, use some Sub like the one below in "Do While.." loop instead of "Workbook.Open"

'' transfer a csv file data to Excel at start of Cell range specified
Public Sub ImportCSV2Excel(csvFilePath As String, atCell As Range)
    Dim Fso As Object, txtFile As Object
    Dim LineTxt As Variant, i As Long
    Set Fso = VBA.CreateObject("Scripting.FileSystemObject")

    Set txtFile = Fso.OpenTextFile(Filename:=csvFilePath, IOMode:=1, Create:=False) ''IOMode Enum (ForReading=1, ForWriting=2, ForAppending=8)
    atCell.CurrentRegion.Clear
    While Not txtFile.atEndofstream
        LineTxt = VBA.Split(txtFile.readline, ",")
        i = i + 1
        atCell.Cells(i, 1).Resize(1, UBound(LineTxt) + 1).Value = LineTxt
    Wend
    txtFile.Close
    Set txtFile = Nothing

End Sub

Sub test_Importcsv()
    ImportCSV2Excel "E:/sales.csv", Sheet1.Range("A1")
End Sub
Leo Sam
  • 83
  • 1
  • 12
0

Import From CSV

Option Explicit

Sub ImportData()
    Const ProcTitle As String = "Import Data"
    
    Const sSubPath As String = "/Downloads/Test med kun 1Vp/Files/"
    Const sFilePattern As String = "*.csv"
    
    Dim sPath As String: sPath = Environ("USERPROFILE") & sSubPath
    
    Dim sfName As String: sfName = Dir(sPath & sFilePattern)
    If Len(fName) = 0 Then
        MsgBox "No files found in '" & sPath & "'.", vbCritical, ProcTitle
        Exit Sub
    End If
    
    Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
    
    'Application.ScreenUpdating = False ' uncomment when you got it right
    
    Do Until Len(sfName) = 0
        Dim swb As Workbook
        Set swb = Workbooks.Open(Filename:=sPath & sfName)
        ' When opening the workbook there are many parameters you can use.
        ' When a 'csv' opens with all the data in one column, I most often
        ' just need to set the `Local` argument to `True` i.e.:
        'Set swb = Workbooks.Open(Filename:=sPath & sfName, Local:=True)
        ' Note that there is also the 'Delimiter' argument which you could
        ' modify to get the workbook open 'properly'. Also, there is
        ' the 'Workbooks.OpenText method'. Using `TextToColumns` should be
        ' your last 'resort'.
        Dim sws As Worksheet: Set sws = swb.Worksheets(1) ' only one per 'csv'
        sws.Copy After:=dwb.Sheets(dwb.Sheets.Count)
        swb.Close SaveChanges:=False
        sfName = Dir
    Loop
    
    'dwb.save
    
    'Application.ScreenUpdating = True ' uncomment when you got it right
    
    MsgBox "Data imported.", vbInformation, ProcTitle
        
End Sub
VBasic2008
  • 44,888
  • 5
  • 17
  • 28
  • Thank you so much! I have a problem with the constants and choosing directory, as I keep getting the error: "No files found in 'XX'". Does the code you provided require a certain syntax? – Karl Emil Thulstrup Nov 08 '21 at 12:42
  • Is `Files` a folder or the starting string of each file? If the latter, then this is the issue. `Environ` works for me, maybe not for you. Before doing anything, you have to get the path right. – VBasic2008 Nov 08 '21 at 12:51
  • Ah, I found out why. I am trying to execute the code on MacOS and Environ is apparently not available. I will try to adjust the code myself. Thank you again – Karl Emil Thulstrup Nov 08 '21 at 15:10