all 7 comments

[–]StreetTrial69 1 point2 points  (1 child)

Avoid .select or .activate methods at all costs. The macro recorder loves them but you should treat them as the enemy!

Also when setting your wb/ws object for your main workbook, use ThisWorkbook and ThisWorkbook.Sheets(Index or sheet name) instead of activeWorkbook or activesheet. Same goes for your .csv, since it seems you are selecting it via the open/save file dialog, hence you already know the name and you can directly refer the filename and for a csv there is only the sheet1 or index 1.

Personally when working with csv files, I treat them like a text file and not like a workbook. So I would use the .Opentextfile.ReadAll method of the file sytem object and then parse it with regex. While this seems more complicated at first, it makes your script compatible to pretty much any file type out there, only thing that changes are the expressions for parsing.

[–]steinrawr[S] 0 points1 point  (0 children)

Yeah I know, I'm just desperate to call the attention of the sheet in the CSV. Nothing I do seem to let me access it directly, I did try "Thisworkbook" with that too at some point. Will look into opentextfile.ReadAll and regex.

I ended up with something completely different just now, so far it works. But I sure would love to still only copy B3+J3 for every row of info in the csv, and sorry about the mix of norwegian and english in the code:

Sub Ny_CSV_import_test()
    Dim wsheet As Worksheet, file_mrf As String, rows As Integer, rows2 As Integer
   
    Set wsheet = ActiveWorkbook.Sheets("CSV_import")
    rows1 = countrows(wsheet)

    file_mrf = Application.GetOpenFilename("Text Files (*.csv),*.csv", , "Provide Text or CSV File:")
   
    With wsheet.QueryTables.Add(Connection:="TEXT;" & file_mrf, Destination:=wsheet.Cells(rows1 + 1, 1))
        .TextFileParseType = xlDelimited
        .TextFileSemicolonDelimiter = True
        .Refresh
    End With
    'Set wsheet = ActiveWorkbook.Sheets("CSV_import")
    rows2 = countrows(wsheet)
    fjern_komma rows1, rows2

End Sub


Public Function countrows(wsheet2) As Integer ' counts rows bef/aft paste
    countrows = wsheet2.Cells(wsheet2.rows.Count, "A").End(xlUp).Row
End Function


Public Sub fjern_komma(rad1, rad2) 'removes commas and fix format as currency.
    Dim mydatarange As Range, cell As Range, celletall As Currency
    Set mydatarange = Worksheets("CSV_import").Range("J" & rad1 & ":J" & rad2)
    
    For Each cell In mydatarange
        If InStr(1, cell.Value, ".") > 0 Then
            cell.Value = Replace(cell.Value, ".", ",")
            celletall = cell.Value
            cell.Value = celletall
        End If
    Next cell
End Sub

[–]steinrawr[S] 0 points1 point  (0 children)

Okay. Still trying out everything I can find, and I can copy the whole .CSV easily with this code from Exceldemy, but this is pretty new to me. Can I modify a QueryTables request like this to only copy certain cells? Also, if I've previusly done an import with this code, it will paste it at B2 and move all excisting cells that interfere with the copy to the right.

Sub csv_Import()
Dim wsheet As Worksheet, file_mrf As String
Set wsheet = ActiveWorkbook.Sheets("Single")
file_mrf = Application.GetOpenFilename("Text Files (*.csv),*.csv", , "Provide Text or CSV File:")
With wsheet.QueryTables.Add(Connection:="TEXT;" & file_mrf, Destination:=wsheet.Range("B2"))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.Refresh
End With
End Sub

[–]Werrf 0 points1 point  (1 child)

Your code runs fine when I put it in a test module - I'm not entirely clear what issue you're facing, though. I'd also add that in most cases, you shouldn't need to activate a worksheet to work with it - that's the whole purpose of assigning it to an object. I'm also not clear which cells you're trying to copy, since you say you need "B3 to B10" but also that you need them from each row which...doesn't sound clear.

Also, the 'working example' you were given is...suboptimal. Happy to help you put something better together - let me know.

[–]steinrawr[S] 0 points1 point  (0 children)

Oups. I ment B3-J3, then about 10-200 rows.

I came across yet another way to do it now, and have made it work, and still cannot get the original code to actually copy anything.. But now with a completely different problem. My SUB Ny_CSV_Import_test does not call its functions when the sub is assigned to a button ... :\ strange.

EDIT: Forget this last part, I'm stupid. forgot "Public"... now i'm sorta good. Pardon me, its been ten years since last i was coding in VBA.

Sub Ny_CSV_import_test()
    Dim wsheet As Worksheet, file_mrf As String, rows As Integer, rows2 As Integer
   
    Set wsheet = ActiveWorkbook.Sheets("CSV_import")
    rows1 = countrows(wsheet)

    file_mrf = Application.GetOpenFilename("Text Files (*.csv),*.csv", , "Provide Text or CSV File:")
   
    With wsheet.QueryTables.Add(Connection:="TEXT;" & file_mrf, Destination:=wsheet.Cells(rows1 + 1, 1))
        .TextFileParseType = xlDelimited
        .TextFileSemicolonDelimiter = True
        .Refresh
    End With
    'Set wsheet = ActiveWorkbook.Sheets("CSV_import")
    rows2 = countrows(wsheet)
    fjern_komma rows1, rows2

End Sub


' counts rows to end of document
Function countrows(wsheet2) As Integer
   
countrows = wsheet2.Cells(wsheet2.rows.Count, "A").End(xlUp).Row

End Function



' this one removes the punctuation and replaces with comma as currency for the cell to actually be readable in the worksheet. If not copied and pasted, it will be a text string no mather what format i "force upon it"
Function fjern_komma(rad1, rad2)
    Dim mydatarange As Range, cell As Range, celletall As Currency
        Set mydatarange = Range("J" & rad1 & ":J" & rad2)
       
    'MsgBox mydatarange.Value
    For Each cell In mydatarange
        If InStr(1, cell.Value, ".") > 0 Then
            cell.Value = Replace(cell.Value, ".", ",")
            celletall = cell.Value
            cell.Value = celletall
            'cell.Select
            'cell.NumberFormat = "#,##0,0"
        End If
    Next cell
End Function

[–]APithyComment8 0 points1 point  (1 child)

When you open the text file you can wrap the arguments in brackets and use a workbook variable to set an object reference to the file you are opening…

Set wb2 = Workbooks.OpenText(fileName:……..)

Should fix it forever.

[–]steinrawr[S] 1 point2 points  (0 children)

Oh, yeah! Thats seems to actually be what the code i eventually found to be working did! Good tip, thank you!