Decimalseperator lost after conversion from csv to excel with vb-script - excel

I have a CSV with semicolon seperators that I would like to convert to a regular Excel sheet. I managed to do this with the code below, but I must have made a mistake because numbers with decimals in the original file that don't start with a zero are shown in Excel as number without the decimal separator. When I open the CSV manually in Excel the result will be fine, so it must be a side-effect of doing it with a script.
For example:
In the CSV there is a line:
2013-03-10 17:00:15; idle; 2,272298;; 0,121860
In the Excel sheet this becomes:
2013-03-10 17:00 | idle | 2.272.298| | 0,121860
Opened manually in excel gives:
2013-03-10 17:00 | idle | 2,272298| | 0,121860
Could somebody please tell me what I could/should change to keep the decimals as decimals in Excel? Possibly a way to tell Excel which symbol represents the decimal separator or an argument to force it into using European formats?
Kind regards, Nico
This is the script I currently have, where csvFile is a string with the full path to the original file and excelFile is a string with the full path to the location where I want to store the new excel sheet.
Set objExcel = CreateObject("Excel.Application") 'use excel
objExcel.Visible = true 'visible
objExcel.displayalerts=false 'no warnings
objExcel.Workbooks.Open(csvFile) 'open the file
objExcel.ActiveWorkbook.SaveAs excelFile, -4143, , , False, False 'save as xls
objExcel.Quit 'close excel

Create a schema.ini file in the folder your csvFile lives in and describe it according to the rules given here.
Further reading: import, text files

There are several approaches possible, I will cover one that I favor:
Start Recording a macro
Create a new workbook
From that workbook go to Data > From Text and there you select the CSV file, then you can do all the required settings regarding Value separators, Decimal separators, Thousands separators. Also the specific data type can be selected for each column.
When the CSV content is added go to Data > Connections and Remove
the connection. The data will stay in the worksheet, but there is no
longer an active connection.
Save the workbook under the xls name
Stop the Recording
Now tweak the script a bit to your liking.

In general Excel honors the system's regional settings. The CSV import, however, sometimes has its own mind about the "correct" format, particularly when the imported file has the extension .csv.
I'd try the following. Rename the file to .txt or .tsv and import it like this:
objExcel.Workbooks.OpenText csvFile, , , 1, 1, False, False, True

I made a work around. I now create a copy of the CSV file where I replace all commas followed by a number by points. While not very effective it does give Excel what it wants and it is simple enough for an inexperienced programmer like me to use.
When doing so a college asked me to also remove white spaces and entries with duplicate values in the first column (the timestamp in this case).
The result was this script
'csvFile is a string with the full path to the file. e.g. "C:\\Program Files\\Program\\data.csv"
'tempFile is a string with the full path to the file. e.g. "C:\\Temp\\temp.csv"
'excelfile is a string with the full path to the file. e.g. "D:\\Data\\sheet.xls"
Set fs=CreateObject("Scripting.FileSystemObject")
Set writeFile = fs.CreateTextFile(tempFile,True)
Set readFile = fs.OpenTextFile(csvFile)
' regular expression to remove leading whitespaces
Set regular_expression = New RegExp
regular_expression.Pattern = "^\s*"
regular_expression.Multiline = False
' regular expression to change the decimal seperator into a point
Set regular_expression2 = New RegExp
regular_expression2.Global = True
regular_expression2.Pattern = ",(?=\d)"
regular_expression2.Multiline = False
'copy the original file to the temp file and apply the changes
Do Until readFile.AtEndOfStream
strLine= readFile.ReadLine
If (StrComp(current_timestamp,Mid(strLine, 1, InStr(strLine,";")),1)<>0) Then
If (Len(previous_line) > 2) Then
previous_line = regular_expression2.replace(previous_line,".")
writeFile.Write regular_expression.Replace(previous_line, "") & vbCrLf
End if
End if
current_timestamp = Mid(strLine, 1, InStr(strLine,";"))
previous_line = strLine
Loop
readFile.Close
writeFile.Close
Set objExcel = CreateObject("Excel.Application") ' use excel
objExcel.Visible = true ' visible
objExcel.displayalerts=false ' no warning pop-ups
objExcel.Workbooks.Open(tempFile) ' open the file
objExcel.ActiveWorkbook.SaveAs excelfile, -4143, , , False, False 'save as excelfile
fs.DeleteFile tempFile ' clean up the temp file
I hope this will also be useful for someone else.

Related

Excel 2010 Macro - Creating txt files with names from ColA and content ColB. Stacko. solutions not work

I have found some answers/examples here on stackoverflow for an issue where in Microsoft Excell 2010, I want to create a txt files for each cell from for e.g. ColumnA which would contain file names, and ColumnB which would contain what is inside certain text file, however one example doesn't work at all, and second bugs after few files created.
You can use the CreateTextFile method which will create your file and provide a TextStream object which you can use to write to the text files. Microsoft Docs
Here's a code example that will do what you asked.
Sub CreateTxt()
Dim my_range As Range
Dim pth As String
Set my_range = Selection
For Each x In my_range.Rows:
pth = "C:\excel_test\" + x.Cells(1) + ".txt" 'file name in column A
Set file_sys = CreateObject("Scripting.FileSystemObject")
Set txt_file = file_sys.CreateTextFile(pth, True)
txt_file.WriteLine (x.Cells(2)) 'content in Column B
txt_file.Close
Next x
End Sub
Just remember, in order to create a file you need adequate permissions on the path you're writing to - I had to run excel as administrator to get the functionality.
Also, the True value in the CreateTextFile method is necessary to overwrite any files with the existing file name, if set to false it will throw an error when trying to write to the file.

VBS, when opening an Excel file, changes number format, destroying data

when try to open an excel file using VBScript, the values/numbers format gets change, destryoing the values.
For example: "0.0" is changed to "__0.0" (with spaces befores), "9000.0" is turned into "__9000.0" (with spaces befores) and "288" is replaced by "288000".
Some knows how to solve this?
Here is my code to open the file:
Dim ExcelFile
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set ExcelFile = objExcel.Workbooks.Open("File Directory")
I need the data as original (functional) in order to be used by another file.

Importing CSV US formatted numbers in Excel with localisation?

I have a .csv file with the following values:
1488201602.653, 8.304700E-04, 3.079498E-03
1488201603.107, 8.677357E-04, 2.856719E-03
1488201821.012, 7.071995E-04, 4.147542E-03
As visible from the snippet, the numbers are in differing format: the first column has a full number, and a period . as a decimal point separator. The second and third columns have numbers in scientific notation, except a capital E is used, and again a period is used for the decimal separator; there are no thousands separator in any of the values.
When I try to import this in a Danish localized version of Excel 2016, what I get is something like this:
So, I'm apparently getting a ton of thousand separators as periods . in the first column, however, if I select the first number, the formula field shows this:
... meaning, the number that was originally 1488201602.653 in the .csv file, now became interpreted as the integer 1488201602653, which is completely wrong.
For the sevcond and third columns, if I select a number, then the formula field shows:
... meaning, the number that was originally 8.304700E-04 in the .csv file, then became 8,30E+02 in the cell, shown as 830,47 in the .csv, which is - again - completely wrong.
How can I persuade Excel to import the data in the .csv file, which in USA or C locale, in its proper numeric values, so they are shown properly under Danish localisation (that is, 1488201602,653 and 8,304700e-04)?
Well, I found a manual way to handle this issue, but it would still be nice to know if there is an automatic one.
First, get and install Notepad++ if you don't already have it.
Then, note that:
Under US (or "C" language) localization, there is no thousands separator (i.e. it is an empty string, "") - under Danish localization, the thousands separator is period "."
Under US (or "C" language) localization, the decimal separator is a period "." - under Danish localization, the decimal separator is comma ","
The Danish localization demands that the E-notation exponent is written as miniscule letter e, not as a capital letter E
Then, open your .csv file in Notepad++, and possibly save it as a copy under a different filename. Then, do the following replacements in this order:
Search for comma , -> replace with semicolon ; (replace all)
Search for period . -> replace with comma , (replace all)
Search for capital E -> replace with miniscule e (replace all)
Then save the file, and import it in Excel. When importing in Excel, remember to specify the semicolon ; as a CSV field separator - and the numbers (at least as per the OP example) should be read-in and interpreted correctly.
I would try like this with VBA (not tested) :
Sub ImportCSVFile()
Dim xFileName As Variant
xFileName = Application.GetOpenFilename("CSV File (*.csv), *.csv", , "Choose CSV", , False)
If xFileName = False Then Exit Sub
Dim wS As Worksheet
Set wS = ThisWorkbook.Sheets.Add
Dim rG As Range
Set rG = wS.Range("A1")
Dim QT As QueryTable
With wS
Set QT = .QueryTables.Add("TEXT;" & xFileName, rG)
With QT
'''Preserve initial format
.PreserveFormatting = True
'''Select the delimiter
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
'''Choose refresh options
.RefreshStyle = xlInsertDeleteCells
.RefreshOnFileOpen = False
.RefreshPeriod = 0
.SaveData = True
'''Import the data
.Refresh BackgroundQuery:=False
End With 'QT
'''Force the formatting
Call .Columns("1:3").Replace(".", ",")
End With 'wS
End Sub

Reverse columns and rows when exporting report to Excel

Exporting an access form to an excel file.
I have code which basically works, but enters all data in one row, instead of one column. Is this an easy fix?
Set fd = Application.FileDialog(msoFileDialogSaveAs)
If fd.Show Then
Me.Filter = "[ID] = " & Me!ID
Me.FilterOn = True
DoCmd.OutputTo acOutputForm, "Checkride", "(*.xls)", fd.SelectedItems(1), True
Me.FilterOn = False
End If
Separate question, based on the same code: If I simply enter a filename, this does not save the file as .xls file. I can type filename.xls, and it works, but that is not optimal. Is there something to change on the DoCmd line?

Trying to convert XLS to CSV and CSV to XLS using VBScript. Receiving error: 800A03EC (Unable to get the Open property of the Workbooks class)

I'm trying to open a CSV then use the SaveAs method to save it as an XLS. Also vice-versa in another script. I accidentally had the file format codes wrong before and was not getting this error. The CSV would in fact open. I accidentally had made the CSV format 2 (which is actually SYLK) and the XLS, 6 (which is actually CSV).
I've looked all over, and most of what I can find has to do with using an incorrect argument (which I have checked multiple times). The rest is for ASP, and suggests changing permissions in Component Services (which probably wouldn't be an issue anyway, since I can get the Open method to work with different formats).
So I'm at a loss as to how to proceed. If I can't even use the Open method, then I'm kind of stuck. If it was as simple as thee SaveAs method not working for this task, I could get around that. But I need to be able to open an XLS using the Open method (since I'm also trying to do XLS to CSV). CSV to XLS can be fixed another way, probably, since the Open method seems to work sometimes.
Anyway, my code for the CSV to XLS is below. The XLS to CSV is essentially identical to this. It just flips the format codes and uses different paths for the files.
strName = "MidCSVTemp.csv"
strSaveName = Month(Now) & "." & Day(Now) & "." & Year(Now) & ".xls"
strPath = "C:\Users\adam\Documents\" & strName
strSavePath = "C:\Users\adam\Documents\" & strSaveName
'Options for Workbook.Open
intUpdateLinks = 0
boolReadOnly = False
intFormat = 6
'Options for SaveAs
intFileFormat = 56
Set objExcel = CreateObject("Excel.Application")
Set objWorkBook = objExcel.Workbooks.Open(strPath,intUpdateLinks,boolReadOnly,intFormat)
Call objWorkBook.SaveAs(strSavePath,intFileFormat)
Call objWorkbook.Close
I think the issue is that you're using the Format parameter of the Workbooks.Open() method like it's the FileFormat parameter. It shouldn't be xlCSV (6), which is a FileFormat constant. According to the docs, Format should be one of the following values:
1 = Tabs
2 = Commas
3 = Spaces
4 = Semicolons
5 = Nothing
6 = Custom
Since you're passing a value of 6, it's expecting that you also include the Delimiter argument. And since you're not including it, you're getting an error.
You should be able to open a CSV without specifying the Format parameter (Excel seemed to guess the delimiter correctly for me without having to specify it). But, to be safe, pass a value of 2 for a comma-delimited (CSV) file.
intFormat = 2
Set objWorkBook = objExcel.Workbooks.Open(strPath,intUpdateLinks,boolReadOnly,intFormat)

Resources