1

wondering if you can help out with a VBA issue. I pieced together the following without really knowing what I was doing:

Sub Import_Raw_Stripe_data()

    Dim fileDialog As fileDialog
    Dim strPathFile As String
    Dim strFileName As String
    Dim strPath As String
    Dim dialogTitle As String
    Dim Tworkbook As Workbook
    Dim Sworkbook As Workbook


dialogueTitle = "Select File to Import"
Set fileDialogue = Application.fileDialog(msoFileDialogFilePicker)
With fileDialogue
    .InitialFileName = "L:\Downloads"
    .AllowMultiSelect = False
    .Filters.Clear
    .Title = dialogueTitle

    If .Show = False Then
        MsgBox "No file selected."
        Exit Sub
    End If
    strPathFile = .SelectedItems(1)
End With

Set Sworkbook = Workbooks.Open(fileName:=strPathFile)
Set Tworkbook = ThisWorkbook



End Sub

Which, as far as I can tell opens a file dialog in excel, allows a user to choose a document and then opens it.

What I would like to do is the following:

1) Open a file dialogue and select a .csv file to import data from (complete?) into a .xlsm master file (with multiple sheets).

2) Select certain columns from the .csv (column A, Q, R and S in this case), copy them and import them into the second sheet of the master excel file entitled "Raw Stripe Data".

Any help in the matter would be greatly appreciated.

Update: I managed to find the following code:

Sub load_csv()
    Dim fStr As String

    With Application.fileDialog(msoFileDialogFilePicker)
        .Show
        If .SelectedItems.Count = 0 Then
            MsgBox "Cancel Selected"
            Exit Sub
        End If
        'fStr is the file path and name of the file you selected.
        fStr = .SelectedItems(1)
    End With

    With ThisWorkbook.Sheets("Stripe Raw Data").QueryTables.Add(Connection:= _
    "TEXT;" & fStr, Destination:=ThisWorkbook.Sheets("Stripe Raw Data").Range("$A$1"))
        .Name = "CAPTURE"
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .TextFilePromptOnRefresh = False
        .TextFilePlatform = 437
        .TextFileStartRow = 1
        .TextFileParseType = xlDelimited
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileConsecutiveDelimiter = False
        .TextFileTabDelimiter = True
        .TextFileSemicolonDelimiter = False
        .TextFileCommaDelimiter = True
        .TextFileSpaceDelimiter = False
        .TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
        ActiveWorkbook.Save



    End With

End Sub

This works great - but is there anyway to have it not override the data already imported? (for example, if i use it twice, the second import overrides the first).

Spnkmyr
  • 35
  • 1
  • 1
  • 8

1 Answers1

2

ThisWorkbook.Sheets("Stripe Raw Data").Range("$A$1") specifies where the imported data is written to, that is the first cell of the sheet Stripe Raw Data.

Adapt this to your liking if you want the next import at another location.

As mentioned in the comments, you could change load_csv() to take the output destination as a parameter. If you also change it from Sub to Function, you can return the number of rows imported:

Function load_csv(rngDestination As Range) As Long
    '...

    With ThisWorkbook.Sheets("Stripe Raw Data").QueryTables.Add(Connection:= _
    "TEXT;" & fStr, Destination:=rng)

        '...

        .Refresh BackgroundQuery:=False
        load_csv = .ResultRange.Rows.Count

        '...

End Function

Now you can repeatedly call load_csv and provide it with the range where the output should begin for example:

Dim rngOutput As Range
Dim lngRows As Long

Set rngOutput = ThisWorkbook.Sheets("Stripe Raw Data").Range("$A$1")

lngRows = load_csv(rngOutput) ' load first file
lngRows = lngRows + load_csv(rngOutput.Offset(lngRows)) ' load second file
lngRows = lngRows + load_csv(rngOutput.Offset(lngRows)) ' load third file
lngRows = lngRows + load_csv(rngOutput.Offset(lngRows)) ' load fourth file

There is still much room for improvement:

  • Removing duplicate headers
  • Creating a loop instead of explicitly calling load_csv four times
  • Better control for the user to select files (multiselect)
  • Disconnecting the imported data from the QueryTable to reduce dependencies even after the import
  • Not importing in ThisWorkbook but afterwards saving ActiveWorkbook - they may not always be the same
  • ...

But that's not part of this question. After all, all you wanted to know was:

is there anyway to have it not override the data already imported?

I hope I could sufficiently answer this with the above.

Leviathan
  • 2,468
  • 1
  • 18
  • 24
  • Yeah, I understand that's what needs to happen, but the problem is, I don't know how to implement it. I would assume there needs to be a loop of some kind, but again, literally my second day using VBA. – Spnkmyr Feb 18 '17 at 17:22
  • If you expand the procedure to take `ThisWorkbook.Sheets("Stripe Raw Data").Range("$A$1")` as a parameter like this: `load_csv(rng As Range)` - then you can change the import to this: `ThisWorkbook.Sheets("Stripe Raw Data").QueryTables.Add(Connection:= _ "TEXT;" & fStr, Destination:=rng)` - Now you can repeatedly call `load_csv()` with varying parameters. – Leviathan Feb 19 '17 at 00:25
  • Hey, thanks for your help. In your example, can you elaborate on the steps needed to implement this (specifically load_csv(rng As Range)? Can you declare Worksheet.Range = rng and then call rng("$B$1") or something similar? The other question I had is related to where the data gets imported. I basically want each data set to load above the last (as opposed to the same cell which pushes all previous data laterally). If you say Destination:= rng, how do you specify the initial range and then the subsequent import range? – Spnkmyr Feb 19 '17 at 07:36
  • Yeah that's fantastic, thanks for the clarification and your patience! – Spnkmyr Feb 19 '17 at 14:10
  • Great, glad I could help! In this case you should upvote this answer and mark it as the accepted answer by clicking the check mark below the vote buttons. This will reward both of us with reputation points. You probably should also do this for your previous questions that are listed in your profile: https://stackoverflow.com/users/5308865/spnkmyr – Leviathan Feb 19 '17 at 14:32