Sub ExportDataTSV()
Dim BCS As Worksheet
Dim Ctrl As Worksheet
Dim ws As Worksheet
Dim FName As String
Dim insertValues As String
Application.ScreenUpdating = False
Set BCS = ThisWorkbook.Sheets(Sheet2.Name)
Set Ctrl = ThisWorkbook.Sheets(Sheet1.Name)
#If Mac Then
NameFolder = "documents folder"
If Int(Val(Application.Version)) > 14 Then
'You run Mac Excel 2016
folder = _
MacScript("return POSIX path of (path to " & NameFolder & ") as string")
'Replace line needed for the special folders Home and documents
folder = _
Replace(SpecialFolder, "/Library/Containers/com.microsoft.Excel/Data", "")
Else
'You run Mac Excel 2011
folder = MacScript("return (path to " & NameFolder & ") as string")
End If
FName = folder & "bcs_output.tsv"
#Else
folder = Environ$("userprofile")
Debug.Print folder
FName = folder & "Documents\bcs_output.tsv"
#End If
If Ctrl.Range("D9") = "" Or Ctrl.Range("D10") = "" Then
MsgBox "Please enter the Scenario Year and Scenario you wish to save and click again", vbOKOnly
Exit Sub
End If
Ctrl.Range("D9").Copy
BCS.Range("AS2").PasteSpecial Paste:=xlPasteValues
Ctrl.Range("D10").Copy
BCS.Range("AT2").PasteSpecial Paste:=xlPasteValues
With BCS
numrows = .Cells(.Rows.Count, 1).End(xlUp).Row
numcol = .Cells(2, Columns.Count).End(xlToLeft).Column
.Range("AS1").Value = "scenario_year"
.Range("AS2:AS" & numrows).FillDown
.Range("AT1").Value = "scenario"
.Range("AT2:AT" & numrows).FillDown
.Range("AU1").Value = "save_date"
.Range("AU2").Formula = "=NOW()"
.Range("AU2:AU" & numrows).FillDown
.Range("AU2:AU" & numrows).NumberFormat = "yyyy-mm-dd hh:mm"
For x = 2 To numrows
Set rng1 = .Range("A" & x & ":R" & x)
Set rng2 = .Range("AC" & x & ":AF" & x)
Set rng3 = .Range("AH" & x & ":AK" & x)
Set rng4 = .Range("AN" & x & ":AO" & x)
Set rng5 = .Range("AS" & x & ":AU" & x)
Set Data = Union(rng1, rng2, rng3, rng4, rng5)
insertValues = Join2D(ToArray(Data), Chr(9))
Debug.Print insertValues
Call ConvertText(FName, insertValues)
Next x
End With
With BCS
.Activate
.Range("A1").Select
End With
Ctrl.Activate
Application.ScreenUpdating = True
MsgBox "Cluster Data saved to your documents folder, please upload the file here: ", vbOKOnly
End Sub
Function ToArray(rng) As Variant()
Dim arr() As Variant, r As Long, nr As Long
Dim ar As Range, c As Range, cnum As Long, rnum As Long
Dim col As Range
nr = rng.Areas(1).Rows.Count
ReDim arr(1 To nr, 1 To rng.Cells.Count / nr)
cnum = 0
For Each ar In rng.Areas
For Each col In ar.Columns
cnum = cnum + 1
rnum = 1
For Each c In col.Cells
arr(rnum, cnum) = c.Value
rnum = rnum + 1
Next c
Next col
Next ar
ToArray = arr
End Function
Public Function Join2D(ByVal vArray As Variant, Optional ByVal sWordDelim As String = " ", Optional ByVal sLineDelim As String = vbNewLine) As String
Dim i As Long, j As Long
Dim aReturn() As String
Dim aLine() As String
ReDim aReturn(LBound(vArray, 1) To UBound(vArray, 1))
ReDim aLine(LBound(vArray, 2) To UBound(vArray, 2))
For i = LBound(vArray, 1) To UBound(vArray, 1)
For j = LBound(vArray, 2) To UBound(vArray, 2)
'Put the current line into a 1d array
aLine(j) = vArray(i, j)
Next j
'Join the current line into a 1d array
aReturn(i) = Join(aLine, sWordDelim)
Next i
Join2D = Join(aReturn, sLineDelim)
End Function
Function ConvertText(myfile As String, strTxt As String)
Dim objStream
Set objStream = CreateObject("ADODB.Stream")
With objStream
'.Charset = "utf-8"
.Open
.WriteText strTxt
.SaveToFile myfile, 2
'.Close
End With
'Set objStream = Nothing
End Function
I attempted the above to write the non-contiguous ranges to a tab delimited file. I get a 3004 error - Unable to write file from that code. I am not sure why it can't write the file and since I can't even write the file I can't tell if it will write each row of data until there are no more. Can anyone assist with at least helping me get the file to write?
You need to separate folder and "Documents\bcs_output.tsv" with a backslash. In MacOS I believe the path separator is ":" (colon), not "\" (backslash).
Related
I have 2 macros that I would like to combine. Both work fine separately:
Macro to merge all csv files in the folder (found somewhere online):
Sub ImportCSV()
Dim strSourcePath As String
Dim strDestPath As String
Dim strFile As String
Dim strData As String
Dim x As Variant
Dim Cnt As Long
Dim r As Long
Dim c As Long
Application.ScreenUpdating = False
'Change the path to the source folder accordingly
strSourcePath = "\\lcwfsv1\users\e668714\Desktop\Workings\10. Merge Files\PathToMerge"
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
'Change the path to the destination folder accordingly
strDestPath = "\\lcwfsv1\users\e668714\Desktop\Workings\10. Merge Files"
If Right(strDestPath, 1) <> "\" Then strDestPath = strDestPath & "\"
strFile = Dir(strSourcePath & "*.csv")
Do While Len(strFile) > 0
Cnt = Cnt + 1
If Cnt = 1 Then
r = 1
Else
r = Cells(Rows.Count, "A").End(xlUp).Row + 1
End If
Open strSourcePath & strFile For Input As #1
If Cnt > 1 Then
Line Input #1, strData
End If
Do Until EOF(1)
Line Input #1, strData
x = Split(strData, ";")
For c = 0 To UBound(x)
Cells(r, c + 1).Value = Trim(x(c))
Next c
r = r + 1
Loop
Close #1
'Name strSourcePath & strFile As strDestPath & strFile
strFile = Dir
Loop
Application.ScreenUpdating = True
If Cnt = 0 Then _
MsgBox "No CSV files were found...", vbExclamation
End Sub
Macro to merge only csv files after specified date and time (last modified):
Sub Merge()
Call ExtractUserInfo
Call OpenCSVFiles
End Sub
Sub ExtractUserInfo()
Set mWB = ThisWorkbook
uPath = BackSlash(Main.Range("uPath").Text)
uDate = Main.Range("uDate").Value
uHour = Main.Range("uHour").Value
End Sub
Sub OpenCSVFiles()
Call OnStart
Dim arr, f
arr = AllFilesNewestFirst(uPath & "*.csv")
For Each f In arr
If Len(f) > 0 Then
If DateValue(FileDateTime(uPath & f)) < uDate Or (DateValue(FileDateTime(uPath & f)) = uDate And TimeValue(FileDateTime(uPath & f)) < uHour) Then Exit For
Set uFile = Workbooks.Open(fileName:=uPath & f, UpdateLinks:=False, Local:=True)
Call CopyData(uFile)
uFile.Close SaveChanges:=False
End If
Next f
Call OnEnd
MsgBox "Reports have been merged!"
End Sub
Function AllFilesNewestFirst(pattern)
Dim s As String
Dim oShell As Object
Dim oExec As Object, cmd
Set oShell = CreateObject("WScript.Shell")
cmd = "cmd /c dir """ & pattern & """ /A-D-H-S /b /o-d"
s = oShell.Exec(cmd).StdOut.readall()
AllFilesNewestFirst = Split(s, vbCrLf)
End Function
Sub CopyData(wb As Workbook)
Dim tRow As Double
Dim mRow As Double
tRow = wb.Sheets(1).UsedRange.Rows.Count
If tRow > 1 Then
mRow = mWB.Sheets(2).UsedRange.Rows.Count
Set rcop = Nothing
Set rng = Nothing
For Each rng In wb.Sheets(1).Range(Cells(2, 1), Cells(tRow, 32))
If Not rng Is Nothing Then
If Not rcop Is Nothing Then
Set rcop = Union(rng, rcop)
Else
Set rcop = rng
End If
Else
Set rcop = rng
End If
Next
If Not rcop Is Nothing Then
Intersect(rcop.EntireRow, wb.Sheets(1).Columns("A:AF")).Copy
mWB.Sheets(2).Range("a" & mRow + 1).PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
mWB.Sheets(2).Range("ag" & mRow + 1 & ":ag" & mWB.Sheets(2).UsedRange.Rows.Count) = wb.Name
End If
End If
End Sub
The reason why I want to do it is that first macro is many times faster even though it merges all files by default.
Here's what I have so far (only edited sub OpenCSVFiles, rest stay the same), I am now stuck:
Sub OpenCSVFiles()
Call OnStart
Dim arr, f
arr = AllFilesNewestFirst(uPath & "*.csv")
Dim Cnt As Long
Dim r As Long
Dim c As Long
Dim x As Variant
Dim strData As String
For Each f In arr
If DateValue(FileDateTime(uPath & f)) < uDate Or (DateValue(FileDateTime(uPath & f)) = uDate And TimeValue(FileDateTime(uPath & f)) < uHour) Then Exit For
If Len(f) > 0 Then
Cnt = Cnt + 1
If Cnt = 1 Then
r = 1
Else
r = Cells(Merged.Rows.Count, "A").End(xlUp).Row + 1
End If
Open uPath & f For Input As #1
If Cnt > 1 Then
Line Input #1, strData
End If
Do Until EOF(1)
Line Input #1, strData
x = Split(strData, ";")
For c = 0 To UBound(x)
Merged.Cells(r, c + 1).Value = Trim(x(c))
Merged.Cells(r, c + 2).Value = f
Next c
r = r + 1
Loop
Close #1
End If
Next f
Call OnEnd
MsgBox "Reports have been merged!"
End Sub
The problem is:
It starts merging in correct time spot (ex. 1 June 2021, 17:05), however it stops after few days for some reason.
It creates 8 blank rows in the sheet between first and next row, which I could not have spotted in the code why it happens.
Any suggestions?
Many thanks!
I have an external workbook from which I need to get data into my main workbook.
In the past i did this using A LOT of vlookups - and as a result the calculation was extremely slow. In order to speed things up, I have tried to convert the data from the external workbook into an array(arr2), and then doing the lookups into this. The result is that it's even more slow now..
The lookup value is composed of the values from two cells. I roughly have 1000 rows which, the way i do it, needs to be looped through in 44 columns. While it is actually working on a limited amount of rows, after one hour it is still processing when listing all 1000 rows.
What can be done to speed things up?
Dim arr1() As Variant, arr2() As Variant, arr3() As Variant
Dim sup1 As Long, sup2 As Long, sup3 As Long, sup4 As Long, sup5 As Long, sup6 As Long, sup7 As Long,
sup8 As Long, sup9 As Long, sup10 As Long, sup11 As Long, sup12 As Long, sup13 As Long, sup14 As
Long, sup15 As Long
Dim i As Long, WS1 As Worksheet
Dim Book1 As Workbook, book2 As Workbook
Dim book2Name As String
book2Name = "SupportTables.xlsx"
Dim book2NamePath As String
book2NamePath = ThisWorkbook.Path & "\" & book2Name
Dim lastrow As Long
lastrow = Sheets("sheet1").Range("T" & Rows.Count).End(xlUp).Row
Set Book1 = ThisWorkbook
If IsOpen(book2Name) = False Then Workbooks.Open (book2NamePath)
Set book2 = Workbooks(book2Name)
Set WS1 = book2.Worksheets("pricediscinfo")
sup1 = Range("AN12")
sup2 = Range("AQ12")
...
sup15 = Range("CD12")
arr1 = Range("T15:T" & lastrow)
ReDim arr3(1 To UBound(arr1), 1 To 44)
arr2 = WS1.Range("a1").CurrentRegion.Value
For i = 1 To UBound(arr1)
arr3(i, 1) = Application.VLookup(arr1(i, 1) & sup1, arr2, 12, False)
arr3(i, 2) = Application.VLookup(arr1(i, 1) & sup1, arr2, 9, False)
...
arr3(i, 43) = Application.VLookup(arr1(i, 1) & sup15, arr2, 12, False)
arr3(i, 44) = Application.VLookup(arr1(i, 1) & sup15, arr2, 9, False)
Next i
Range("AN15:CE" & lastrow).Value = arr3
Any input appriciated!
Dictionaries are just a collection of key, value pairs like an 1 dimension array but with a string allowed as the key rather than just numbers. In this case because you want to look up 2 columns, the value that a key refers to I chose to be a 2 element array. For more complex cases you might just store the row number as the dictionary value and use it to get the value of any column on the lookup sheet (or array). See Dictionary Object
Update : (ws2.Cells(1, "I") corrected to (ws2.Cells(i, "I")
Option Explicit
Sub FasterLookUp()
Const WB2_NAME = "SupportTables.xlsx"
Const WS2_NAME = "pricediscinfo"
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim iLastrow As Long, i As Long
Dim arr1, arr2, arr3, sPath As String, s As String
Dim isOpen As Boolean, t0 As Single
Dim dict As Object, k
Set dict = CreateObject("Scripting.Dictionary")
Set wb1 = ThisWorkbook
Set ws1 = wb1.Sheets("Sheet1")
sPath = wb1.Path & "\"
' configuration
Dim sup(15) As String, supCol
supCol = Array("AN", "AQ", "AR", "AS", "AT", _
"AU", "AV", "AW", "AX", "AY", _
"AZ", "BA", "BB", "BC", "CD")
For i = 1 To 15
sup(i) = ws1.Cells(12, supCol(i - 1))
s = s & "sup(" & i & ") = " & sup(i) & vbCr
Next
MsgBox s ' for checking code
' open workbook if not already open
isOpen = False
For Each wb2 In Application.Workbooks
If wb2.Name = WB2_NAME Then
isOpen = True
Exit For
End If
Next
If isOpen = False Then
Set wb2 = Workbooks.Open(sPath & "\" & WB2_NAME, True, True) ' update links, read only
End If
Set ws2 = wb2.Sheets(WS2_NAME)
iLastrow = ws2.Cells(Rows.Count, "A").End(xlUp).Row
' build dictionary as lookup table
t0 = Timer
For i = 1 To iLastrow
k = Trim(ws2.Cells(i, "A")) ' key
If Len(k) > 0 Then
If dict.exists(k) Then
MsgBox "Duplicate key " & k, vbCritical, "Row " & i
Exit Sub
Else
' col I and col L
dict.Add k, Array(ws2.Cells(i, "I"), ws2.Cells(i, "L")) ' lookups
End If
End If
Next
MsgBox dict.Count & " Items scanned into dictionary from " & ws2.Name, _
vbInformation, "Took " & Int(Timer - t0) & " seconds"
' update this workbook
t0 = Timer
iLastrow = ws1.Cells(Rows.Count, "T").End(xlUp).Row
arr1 = ws1.Range("T15:T" & iLastrow)
ReDim arr3(UBound(arr1), 1 To 44)
For i = 1 To UBound(arr1)
s = arr1(i, 1)
k = s & sup(1)
If dict.exists(k) Then
arr3(i, 1) = dict(k)(1) ' col L
arr3(i, 2) = dict(k)(0) ' col I
Else
'Debug.Print "No match '" & k & "'"
End If
''
k = s & sup(15)
If dict.exists(k) Then
arr3(i, 1) = dict(k)(1) ' col L
arr3(i, 2) = dict(k)(0) ' col I
Else
'Debug.Print "No match '" & k & "'"
End If
Next i
If isOpen = False Then wb2.Close False ' close if opened
ws1.Range("AN15:CE" & iLastrow).Value = arr3
MsgBox "Udate done", vbInformation, "Took " & Int(Timer - t0) & " seconds"
End Sub
Sub ExportDataTSV()
Dim BCS As Worksheet
Dim Ctrl As Worksheet
Dim ws As Worksheet
Dim FName As String
Dim insertValues As String
Application.EnableEvents = False
Application.ScreenUpdating = False
Set BCS = ThisWorkbook.Sheets(Sheet2.Name)
Set Ctrl = ThisWorkbook.Sheets(Sheet1.Name)
fileDate = Year(Now) & "_" & Month(Now) & "_" & Day(Now) & "_" & Format(Now, "hh")
#If Mac Then
NameFolder = "documents folder"
If Int(Val(Application.Version)) > 14 Then
'You run Mac Excel 2016
folder = _
MacScript("return POSIX path of (path to " & NameFolder & ") as string")
'Replace line needed for the special folders Home and documents
folder = _
Replace(SpecialFolder, "/Library/Containers/com.microsoft.Excel/Data", "")
Else
'You run Mac Excel 2011
folder = MacScript("return (path to " & NameFolder & ") as string")
End If
FName = folder & ":bcs_output.txt"
#Else
folder = Environ$("userprofile")
FName = folder & "\Documents\bcs_output_" & fileDate & ".txt"
#End If
If Ctrl.Range("D9") = "" Or Ctrl.Range("D10") = "" Then
MsgBox "Please enter the Scenario Year and Scenario you wish to save and click again", vbOKOnly
Exit Sub
End If
Ctrl.Range("D9").Copy
BCS.Range("AS2").PasteSpecial Paste:=xlPasteValues
Ctrl.Range("D10").Copy
BCS.Range("AT2").PasteSpecial Paste:=xlPasteValues
Call ClearFile(FName)
With BCS
.AutoFilter.ShowAllData
numrows = .Cells(.Rows.Count, 1).End(xlUp).Row
numcol = .Cells(2, Columns.Count).End(xlToLeft).Column
.Range("AS1").Value = "scenario_year"
.Range("AS2:AS" & numrows).FillDown
.Range("AT1").Value = "scenario"
.Range("AT2:AT" & numrows).FillDown
.Range("AU1").Value = "save_date"
.Range("AU2").Formula = "=NOW()"
.Range("AU2:AU" & numrows).FillDown
.Range("AU2:AU" & numrows).NumberFormat = "yyyy-mm-dd hh:mm"
For x = 2 To numrows
Set rng1 = .Range("A" & x & ":R" & x)
Set rng2 = .Range("AC" & x & ":AF" & x)
Set rng3 = .Range("AH" & x & ":AK" & x)
Set rng4 = .Range("AN" & x & ":AO" & x)
Set rng5 = .Range("AS" & x & ":AU" & x)
Set Data = Union(rng1, rng2, rng3, rng4, rng5)
insertValues = Join2D(ToArray(Data), Chr(9))
Call ConvertText(FName, insertValues)
Next x
End With
With BCS
.Activate
.Range("A1").Select
End With
Ctrl.Activate
Application.ScreenUpdating = True
MsgBox "Cluster Data saved to " & FName & ", please upload the file here: https://awsfinbi.corp.amazon.com/s/dcgs_abv/submit", vbOKOnly
Application.EnableEvents = True
End Sub
Function ToArray(rng) As Variant()
Dim arr() As Variant, r As Long, nr As Long
Dim ar As Range, c As Range, cnum As Long, rnum As Long
Dim col As Range
nr = rng.Areas(1).Rows.Count
ReDim arr(1 To nr, 1 To rng.Cells.Count / nr)
cnum = 0
For Each ar In rng.Areas
For Each col In ar.Columns
cnum = cnum + 1
rnum = 1
For Each c In col.Cells
arr(rnum, cnum) = c.Value
rnum = rnum + 1
Next c
Next col
Next ar
ToArray = arr
End Function
Public Function Join2D(ByVal vArray As Variant, Optional ByVal sWordDelim As String = " ", Optional ByVal sLineDelim As String = vbNewLine) As String
Dim i As Long, j As Long
Dim aReturn() As String
Dim aLine() As String
ReDim aReturn(LBound(vArray, 1) To UBound(vArray, 1))
ReDim aLine(LBound(vArray, 2) To UBound(vArray, 2))
For i = LBound(vArray, 1) To UBound(vArray, 1)
For j = LBound(vArray, 2) To UBound(vArray, 2)
'Put the current line into a 1d array
aLine(j) = vArray(i, j)
Next j
'Join the current line into a 1d array
aReturn(i) = Join(aLine, sWordDelim)
Next i
Join2D = Join(aReturn, sLineDelim)
End Function
Public Function ClearFile(myfile)
Open myfile For Output As #1: Close #1
End Function
Public Function ConvertText(myfile As String, strTxt As String)
Open myfile For Append As #1
Write #1, strTxt
Close #1
End Function
The above functions are what I have strung together from various SO post and googles. It works to a large degree, but when it creates the txt file with the tab delimiter it gives an output where in the text separator is a single quote. However, the entire line is wrapped in double quotes. So the output looks something like "'Field1'\t'Field2'\t'Field3'" . That is not a valid TSV format for loading into a database like Redshift due to the double quotes. I need the double quotes to not be in the file, can anyone identify why it is adding them? Is there a way to prevent it or a better way to create a tab delimited file output for loading to Redshift?
For further information it MUST be a txt with tab delimiter, I have no control over that requirement.
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/writestatement
Unlike the Print # statement, the Write # statement inserts commas
between items and quotation marks around strings as they are written
to the file. You don't have to put explicit delimiters in the list.
Write # inserts a newline character, that is, a carriage
return-linefeed (Chr(13) + Chr(10) ), after it has written the final
character in outputlist to the file.
To not add quotes switch to Print:
Print #1, strTxt
my code seems to compile, and run correctly, but for some reason the Inputbox does not seems to be evaluated at all. The Inputbox is in the middle of the code, what I am trying to accomplish is to have a cells data evaluated against a MonthName, and if its a match then spit out a Inputbox to the User. The function it is evaluating is:
=IFERROR(VLOOKUP($A3,'G:\Financial\Facility Work Papers and Financials\1.
Operating Entities\Arbors\2. Financials\2018\5. May\[Arbors May 2018.xls]Trial
Balance'!$A$30:$H$100,8,FALSE),0)
Here is the code:
Sub Date1()
Dim r As Range
Dim s As String
Dim UserInput As String
Dim Curdate As Date
Dim newDate As String
Dim newDate1 As String
Dim newDate2 As String
Dim newDate3 As String
Dim LastCol As Integer
Dim LastRow As Integer
Dim j As Integer
Dim i As Integer
Dim k As Integer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
With ActiveSheet
For k = 1 To 12
Curdate = CDate(k & " " & "01," & " " & "2018")
newDate1 = MonthName(Month(Curdate), False)
newDate2 = MonthName(Month(Curdate), True)
newDate3 = Month(Curdate)
newDate = newDate3 & "." & newDate2
Debug.Print newDate
Debug.Print newDate1
'Defining the loops parameteres
For Each r In ActiveSheet.Range("D3:D6").Cells.SpecialCells(xlCellTypeFormulas)
s = LCase(r.Formula)
If InStr(1, r, newDate1) > 0 Then
UserInput = Application.InputBox(prompt:=newDate1 & "is the current data, if this is the data you want", Title:="please click cancel, otherwise click OK", Default:=newDate1)
End If
Next r
Next k
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 1 To LastCol
For j = 1 To LastRow
With ActiveWorkbook.Sheets("Data")
.Range(.Cells(j, 1), .Cells(1, i)).Replace What:=oldDate3 & "." & " " & oldDate2, replacement:=newDate, LookAt:=xlPart, MatchCase:=False
.Range(.Cells(j, 1), .Cells(1, i)).Replace What:=oldDate1, replacement:=newDate1, LookAt:=xlPart, MatchCase:=False
End With
Next j
Next i
End With
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Debug.Print Curdate
Debug.Print newDate3 & "." & newDate2
Debug.Print newDate1
Debug.Print newDate
End Sub
Ok, this gonna be long.
I have a csv file that I want to import in a excel.
This is the CSV file.
"NIP";"Date start";"Date end";"Reason";"coment"
"1";"06/06/17 09:55";"";"test";"asdasd ad ,a dasds asd;asdfasfasdfad ,
asdfasdfda a
asffasd , asdf asf asfad; asfasfasfa ;sadfdasds
,adasdsa ,asdassda,adadasddasd, asd asdasdad
;;;;adasdasdsa ,,,,sfdafas"
This is how looks on excel.
When this CSV is imported on excel using VB (the excel will import a lot of csv files), this is how it looks.
This is my VB code to import CSV
Option Explicit
Sub ImportFiles()
Dim sPath As String
sPath = ThisWorkbook.Path & "\data\1.csv"
'copyDataFromCsvFileToSheet sPath, ";", "1"
sPath = ThisWorkbook.Path & "\data\2.csv"
'copyDataFromCsvFileToSheet sPath, ";", "2"
sPath = ThisWorkbook.Path & "\data\3.csv"
'copyDataFromCsvFileToSheet sPath, ";", "3"
sPath = ThisWorkbook.Path & "\data\4.csv"
'copyDataFromCsvFileToSheet sPath, ";", "4"
sPath = ThisWorkbook.Path & "\data\5.csv"
'copyDataFromCsvFileToSheet sPath, ";", "5"
sPath = ThisWorkbook.Path & "\data\6.csv"
'copyDataFromCsvFileToSheet sPath, ";", "6"
sPath = ThisWorkbook.Path & "\data\7.csv"
'copyDataFromCsvFileToSheet sPath, ";", "7"
sPath = ThisWorkbook.Path & "\data\8.csv"
'copyDataFromCsvFileToSheet sPath, ";", "8"
sPath = ThisWorkbook.Path & "\data\9.csv"
'copyDataFromCsvFileToSheet sPath, ";", "9"
sPath = ThisWorkbook.Path & "\data\10.csv"
'copyDataFromCsvFileToSheet sPath, ";", "10"
sPath = ThisWorkbook.Path & "\data\11.csv"
'copyDataFromCsvFileToSheet sPath, ";", "11"
sPath = ThisWorkbook.Path & "\data\12.csv"
copyDataFromCsvFileToSheet sPath, ";", "12"
sPath = ThisWorkbook.Path & "\data\13.csv"
'copyDataFromCsvFileToSheet sPath, ";", "13"
Dim aux As String
aux = FindReplaceAll()
End Sub
Private Sub copyDataFromCsvFileToSheet(parFileName As String, _
parDelimiter As String, parSheetName As String)
Dim Data As Variant
Data = getDataFromFile(parFileName, parDelimiter)
If Not isArrayEmpty(Data) Then
If SheetExists(parSheetName) Then
With Sheets(parSheetName)
.Range("A1:OO2000").ClearContents
.Cells(1, 1).Resize(UBound(Data, 1), UBound(Data, 2)) = Data
End With
Else
Dim warning
warning = MsgBox("no existing sheet'" & parSheetName, vbOKOnly, "Warning")
End If
End If
End Sub
Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
SheetExists = Not sht Is Nothing
End Function
Function FindReplaceAll()
Dim sht As Worksheet
Dim fnd As Variant
Dim rplc As Variant
For Each sht In ActiveWorkbook.Worksheets
sht.Cells.Replace what:=Chr(34), Replacement:="", _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Next sht
End Function
Public Function isArrayEmpty(parArray As Variant) As Boolean
If IsArray(parArray) = False Then isArrayEmpty = True
On Error Resume Next
If UBound(parArray) < LBound(parArray) Then
isArrayEmpty = True
Exit Function
Else
isArrayEmpty = False
End If
End Function
Private Function getDataFromFile(parFileName As String, _
parDelimiter As String, _
Optional parExcludeCharacter As String = "") As Variant
Dim locLinesList() As Variant
Dim locData As Variant
Dim i As Long
Dim j As Long
Dim lim As Long
Dim locNumRows As Long
Dim locNumCols As Long
Dim fso As Variant
Dim ts As Variant
Const REDIM_STEP = 10000
Set fso = CreateObject("Scripting.FileSystemObject")
On Error GoTo error_open_file
Set ts = fso.OpenTextFile(parFileName)
On Error GoTo unhandled_error
ReDim locLinesList(1 To 1) As Variant
i = 0
Do While Not ts.AtEndOfStream
Dim aux As String
aux = ts.ReadLine
If i Mod REDIM_STEP = 0 Then
ReDim Preserve locLinesList _
(1 To UBound(locLinesList, 1) + REDIM_STEP) As Variant
lim = UBound(Split(aux, parDelimiter)) + 1
End If
locLinesList(i + 1) = Split(aux, """+parDelimiter+""")
j = UBound(locLinesList(i + 1), 1)
If locNumCols < j Then locNumCols = j
i = i + 1
Loop
ts.Close
locNumRows = i
If locNumRows = 0 Then Exit Function
ReDim locData(1 To locNumRows, 1 To locNumCols + 1) As Variant
If parExcludeCharacter <> "" Then
For i = 1 To locNumRows
For j = 0 To UBound(locLinesList(i), 1)
If Left(locLinesList(i)(j), 1) = parExcludeCharacter Then
If Right(locLinesList(i)(j), 1) = parExcludeCharacter Then
locLinesList(i)(j) = _
Mid(locLinesList(i)(j), 2, Len(locLinesList(i)(j)) - 2)
Else
locLinesList(i)(j) = _
Right(locLinesList(i)(j), Len(locLinesList(i)(j)) - 1)
End If
ElseIf Right(locLinesList(i)(j), 1) = parExcludeCharacter Then
locLinesList(i)(j) = _
Left(locLinesList(i)(j), Len(locLinesList(i)(j)) - 1)
End If
locData(i, j + 1) = locLinesList(i)(j)
Next j
Next i
Else
For i = 1 To locNumRows
For j = 0 To UBound(locLinesList(i), 1)
locData(i, j + 1) = locLinesList(i)(j)
Next j
Next i
End If
getDataFromFile = locData
Exit Function
error_open_file:
unhandled_error:
End Function
I want that in the excel to look like when you open the csv in excel.
This was my solution.
First I added two new functions.
Public Function mergeArrays(arr1 As Variant, arr2 As Variant) As Variant
Dim i As Integer
Dim sizeArr1 As Integer
Dim arr3() As String
ReDim arr3(UBound(arr1) + UBound(arr2) + 1)
sizeArr1 = UBound(arr1) + 1
For i = 0 To UBound(arr1)
arr3(i) = arr1(i)
Next i
For i = 0 To UBound(arr2)
arr3(i + sizeArr1) = arr2(i)
Next i
mergeArrays = arr3
End Function
Public Function DeleteElementAt(inArray As Variant) As Variant
Dim index As Integer
Dim aux() As String
ReDim aux(UBound(inArray) - 1)
For index = 1 To UBound(inArray)
aux(index - 1) = inArray(index)
Next index
DeleteElementAt = aux
End Function
Also I modified getDataFromFile
Private Function getDataFromFile(parFileName As String, _
parDelimiter As String, _
Optional parExcludeCharacter As String = "") As Variant
Dim locLinesList() As Variant
Dim locData As Variant
Dim linea() As String
Dim i As Long
Dim j As Long
Dim lim As Long
Dim locNumRows As Long
Dim locNumCols As Long
Dim fso As Variant
Dim ts As Variant
Const REDIM_STEP = 10000
Set fso = CreateObject("Scripting.FileSystemObject")
On Error GoTo error_open_file
Set ts = fso.OpenTextFile(parFileName)
On Error GoTo unhandled_error
ReDim locLinesList(1 To 1) As Variant
i = 0
Do While Not ts.AtEndOfStream
Dim aux As String
aux = ts.ReadLine
aux = Replace(aux, Chr(34) & ";" & Chr(34), Chr(34) & "###" & Chr(34))
linea = Split(aux, "###")
If i Mod REDIM_STEP = 0 Then
ReDim Preserve locLinesList _
(1 To UBound(locLinesList, 1) + REDIM_STEP) As Variant
lim = UBound(linea) + 1
locNumCols = lim
locLinesList(i + 1) = linea
i = i + 1
Else
locLinesList(i + 1) = linea
If UBound(locLinesList(i)) + 1 < lim Then
locLinesList(i)(UBound(locLinesList(i))) = locLinesList(i)
(UBound(locLinesList(i))) & vbCrLf & linea(0)
linea = DeleteElementAt(linea)
locLinesList(i) = mergeArrays(locLinesList(i), linea)
Else
If UBound(linea) + 1 = 1 Then
locLinesList(i)(UBound(locLinesList(i))) = locLinesList(i)
(UBound(locLinesList(i))) & vbCrLf & linea(0)
Else
'Linea es un salto de linea a secas
If UBound(linea) = -1 Then
locLinesList(i)(UBound(locLinesList(i))) = locLinesList(i)
(UBound(locLinesList(i))) & vbCrLf
Else
i = i + 1
End If
End If
End If
End If
Loop
Dim endVector() As Variant
ReDim endVector(i)
Dim index As Integer
For index = 0 To i - 1
endVector(index) = locLinesList(index + 1)
Next index
ts.Close
locNumRows = i
If locNumRows = 0 Then Exit Function
ReDim locData(1 To locNumRows, 1 To locNumCols) As Variant
If parExcludeCharacter <> "" Then
For i = 1 To locNumRows
For j = 0 To UBound(endVector(i), 1)
If Left(endVector(i)(j), 1) = parExcludeCharacter Then
If Right(endVector(i)(j), 1) = parExcludeCharacter Then
endVector(i)(j) = _
Mid(endVector(i)(j), 2, Len(endVector(i)(j)) - 2)
Else
endVector(i)(j) = _
Right(endVector(i)(j), Len(endVector(i)(j)) - 1)
End If
ElseIf Right(endVector(i)(j), 1) = parExcludeCharacter Then
endVector(i)(j) = _
Left(endVector(i)(j), Len(endVector(i)(j)) - 1)
End If
locData(i, j + 1) = endVector(i)(j)
Next j
Next i
Else
For i = 0 To locNumRows - 1
For j = 0 To UBound(endVector(i), 1)
locData(i + 1, j + 1) = endVector(i)(j)
Next j
Next i
End If
getDataFromFile = locData
Exit Function
I know that this code can optimized but for now It works