Converting xls to csv using VBScript and separate by semicolons - csv

I have a VBScript code snippet which converts my xls and xlsx files into csv files. However, I want each cell to be separated by a semicolon rather than a comma. On my computer, the list separator is set to semicolon instead of comma so when I open up an excel window and do save as csv, it separates by semicolon. However, my VBScript produces a csv file separated by commas. I found the code snippet online as I do not really know VBScript (I'm mainly a Java Programmer) that well. How can I change the code snippet to separate the csv files by semicolon rather than by comma?
if WScript.Arguments.Count < 2 Then
WScript.Echo "Error! Please specify the source path and the destination. Usage: XlsToCsv SourcePath.xls Destination.csv"
Wscript.Quit
End If
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))
oBook.SaveAs WScript.Arguments.Item(1), 6
oBook.Close False
oExcel.Quit
WScript.Echo "Done"

you can keep your original script, only need to give a parameter to indicate local setting must apply. This saves my CSV with a ; separator
if WScript.Arguments.Count < 2 Then
WScript.Echo "Error! Please specify the source path and the destination. Usage: XlsToCsv SourcePath.xls Destination.csv"
Wscript.Quit
End If
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = FALSE 'to avoid prompts
Dim oBook, local
Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))
local = true
call oBook.SaveAs(WScript.Arguments.Item(1), 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, local) 'this changed
oBook.Close False
oExcel.Quit
WScript.Echo "Done"

The use of a comma in delimited text files finds its roots in the regional settings. While the comma is standard in the US, other countries such as Germany use the semicolon instead. You can change the List Separator value in the Regional and Language settings and then choose CSV (Comma delimited) (.csv) from Excel's Save As window. The resulting file will be delimited by whatever value is in the system settings. This script changes default List Separator setting. Then it opens the specified spreadsheet and resaves it. It reverts the system setting to its previous value before finishing.
It accepts two command line parameters. The first is the input spreadsheet; the second is the output filename for the exported file.
strDelimiter = ";"
strSystemDelimiter = "" ' This will be used to store the current sytem value
Const HKEY_CURRENT_USER = &H80000001
' Get the current List Separator (Regional Settings) from the registry
strKeyPath = "Control Panel\International"
strValueName = "sList"
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
objRegistry.GetStringValue HKEY_CURRENT_USER, strKeyPath, strValueName, strSystemDelimiter
' Set it temporarily to our custom delimiter
objRegistry.SetStringValue HKEY_CURRENT_USER, strKeyPath, strValueName, strDelimiter
' Open spreadsheet with Excel and save it in a text delimited format
Const xlCSV = 6
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open(WScript.Arguments.Item(0))
objWorkbook.SaveAs WScript.Arguments.Item(1), xlCSV
objWorkbook.Close vbFalse ' Prevent duplicate Save dialog
objExcel.Quit
' Reset the system setting to its original value
objRegistry.SetStringValue HKEY_CURRENT_USER, strKeyPath, strValueName, strSystemDelimiter
After some testing, it seems that this only works through Excel's Save As dialog and not through command-line or automation. I've changed the script a little to make the Excel window visible and use shortcuts keys to open the Save As dialog through the Excel interface. This should do the trick. It worked for me on Vista x64 with Excel 2007. I hope this works for you.
strDelimiter = ";"
strSystemDelimiter = "" ' This will be used to store the current sytem value
Const HKEY_CURRENT_USER = &H80000001
' Get the current List Separator (Regional Settings) from the registry
strKeyPath = "Control Panel\International"
strValueName = "sList"
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
objRegistry.GetStringValue HKEY_CURRENT_USER, strKeyPath, strValueName, strSystemDelimiter
' Set it temporarily to our custom delimiter
objRegistry.SetStringValue HKEY_CURRENT_USER, strKeyPath, strValueName, strDelimiter
' Open spreadsheet with Excel and save it in a text delimited format
Const xlCSV = 6
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = vbTrue
Set objWorkbook = objExcel.Workbooks.Open(WScript.Arguments.Item(0))
WScript.Sleep 500 ' Delay to make sure the Excel workbook is open
strWorkbookName = objExcel.ActiveWorkbook.Name
strTitlebar = strWorkbookName
Set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate strTitlebar ' Make the workbook active so it receives the keystrokes
WshShell.SendKeys "%fa" ' Keyboard shortcuts for the Save As dialog
WScript.Sleep 500
WshShell.SendKeys "%tc{ENTER}" ' Change the Save As type to CSV
If WScript.Arguments.Count > 1 Then
WshShell.SendKeys "+{TAB}" & WScript.Arguments.Item(1)
WScript.Sleep 500
End If ' This If block changes the save name if one was provided
WshShell.SendKeys "{ENTER}" ' Save the file
WScript.Sleep 500
WshShell.SendKeys "{ENTER}" ' Dismiss the CSV warning dialog
Set WshShell = Nothing
objWorkbook.Close vbFalse ' Prevent duplicate Save dialog
objExcel.Quit
' Reset the system setting to its original value
objRegistry.SetStringValue HKEY_CURRENT_USER, strKeyPath, strValueName, strSystemDelimiter

The Function SaveAs is defined so :
.SaveAs(FileName, FileFormat, Password, WriteResPassword, ReadOnlyRecommended, CreateBackup, AccessMode, ConflictResolution, AddToMru, TextCodepage, TextVisualLayout, Local)
Thas is, to use the semicolon (if your regional language option are correctly set)
ExcelObj.Workbooks(1).SaveAs csvFile, 6,,,,,,,,,,True

You can reopen the file with the FSO object, then do a Replace() on the comma character.
Const OpenAsDefault = -2
Const FailIfNotExist = 0
Const ForReading = 1
Const ForWriting = 2
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set fCSVFile = _
oFSO.OpenTextFile("C:\path\file.csv", ForReading, FailIfNotExist, OpenAsDefault)
sFileContents = fCSVFile.ReadAll
fCSVFile.Close
sFileContents = Replace(sFileContents, ",",";"))
Set fCSVFile = oFSO.OpenTextFile("C:\path\file.csv", ForWriting, True)
fCSVFile.Write(sFileContents)
fCSVFile.Close

I changed the parameter to true, and worked for me.
if WScript.Arguments.Count < 2 Then
WScript.Echo "Erro! Especifique origem e destino. Exemplo: XlsToCsv SourcePath.xls Destination.csv"
Wscript.Quit
End If
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))
call oBook.SaveAs(WScript.Arguments.Item(1), 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, true) --CHANGED
oBook.Close False
oExcel.Quit

Related

VBS - Loop through multiple .csv files in a folder and convert the files to .xlsx

I managed to get the following piece of code put together:
'Constants
Const xlOpenXMLWorkbook = 51 '(without macro's in 2007-2016, xlsx)
Const xlOpenXMLWorkbookMacroEnabled = 52 '(with or without macro's in 2007-2016, xlsm)
Const xlExcel12 = 50 '(Excel Binary Workbook in 2007-2016 with or without macro's, xlsb)
Const xlExcel8 =56 '(97-2003 format in Excel 2007-2016, xls)
' Extensions for old and new files
strExcel = "xlsx"
strCSV = "csv"
' Set up filesystem object for usage
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Get folder name to process off the command line, make sure it's valid
If (WScript.Arguments.Count > 0) Then
strFolder = WScript.Arguments(0)
If Not objFSO.FolderExists(strFolder) Then
WScript.StdErr.WriteLine "Specified folder does not exist."
WScript.Quit
End If
Else
WScript.StdErr.WriteLine "No folder name specified to process."
WScript.Quit
End If
' Access the folder to process
Set objFolder = objFSO.GetFolder(strFolder)
' Load Excel (hidden) for conversions
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
objExcel.DisplayAlerts = False
' Process all files
For Each objFile In objFolder.Files
' Get full path to file
strPath = objFile.Path
' Only convert CSV files
If LCase(objFSO.GetExtensionName(strPath)) = LCase(strCSV) Then
' Display to console each file being converted
WScript.Echo "Converting """ & strPath & """"
' Load CSV into Excel and save as native Excel file
Set objWorkbook = objExcel.Workbooks.Open(strPath, False, True)
objWorkbook.SaveAs Replace(strPath, strCSV, strExcel), xlOpenXMLWorkbook
objWorkbook.Close False
Set objWorkbook = Nothing
End If
Next
'Wrap up
objExcel.Quit
Set objExcel = Nothing
Set objFSO = Nothing
Unfortunately I have 3 issues:
I was instructed to run this in the following manner:
Copy the code above and saved it as csv.vbs
Go to CMD and type in
cscript csv.vbs "C:\Users\Eitel\Desktop\3rd Party\Work Folder"
This is the path where the CSV files are.
I would prefer to have a way of executing the code by clicking on/opening a VBScript.
I received this error:
Input Error: Can not find script file "C:\Users\Eitel\csv.vbs"
I went to "C:\Users\Eitel\csv.vbs" and pasted the csv.vbs file in this location. I ran the command again and this is what was displayed:
"C:\Users\Eitel\Desktop\3rd Party\Work Folder\TestFile.CSV"
C:\Users\Eitel\csv.vbs(44.9) Microsoft Excel: Cannot save as that name. Document was opened as read-only.
I have no clue what this means or why it happens?
I noticed that while most of the files are .csv extensions, some of the files extensions are displayed as .CSV and some are .csv. I am wondering if this will affect the way in which the script is executed?
Here is the solution I needed:
Link: https://www.experts-exchange.com/questions/29088597/Change-Multiple-csv-files-into-xlsx-files.html?notificationFollowed=205599875
'Constants
Const xlOpenXMLWorkbook = 51 '(without macro's in 2007-2016, xlsx)
Const xlOpenXMLWorkbookMacroEnabled = 52 '(with or without macro's in 2007-2016, xlsm)
Const xlExcel12 = 50 '(Excel Binary Workbook in 2007-2016 with or without macro's, xlsb)
Const xlExcel8 =56 '(97-2003 format in Excel 2007-2016, xls)
' Extensions for old and new files
strExcel = "xlsx"
strCSV = "csv"
strXLS = "xls"
' Set up filesystem object for usage
Set objFSO = CreateObject("Scripting.FileSystemObject")
strFolder = "B:\EE\EE29088597\Files"
' Access the folder to process
Set objFolder = objFSO.GetFolder(strFolder)
' Load Excel (hidden) for conversions
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
objExcel.DisplayAlerts = False
' Process all files
For Each objFile In objFolder.Files
' Get full path to file
strPath = objFile.Path
' Only convert CSV files
If LCase(objFSO.GetExtensionName(strPath)) = LCase(strCSV) Or LCase(objFSO.GetExtensionName(strPath)) = LCase(strXLS) Then
' Display to console each file being converted
Wscript.Echo "Converting """ & strPath & """"
' Load CSV into Excel and save as native Excel file
Set objWorkbook = objExcel.Workbooks.Open(strPath, False, True)
strNewPath = objFSO.GetParentFolderName(strPath) & "\" & objFSO.GetBaseName(strPath) & "." & strExcel
objWorkbook.SaveAs strNewPath, xlOpenXMLWorkbook
objWorkbook.Close False
Set objWorkbook = Nothing
End If
Next
'Wrap up
objExcel.Quit
Set objExcel = Nothing
Set objFSO = Nothing
This will scan the directory for any xls or csv file and convert them into xlsx files.

vbscript to convert html files to docx

I have many html files in c:\temp\ which need to be converted in the same directory to .docx files.
I have Office 2013. So i guess it doesnt need any converter but instead only opening html in word in the background and saving it as a .docx.
I found a script which is converting doc to pdf:
vbscript to convert word doc to pdf
Const wdExportAllDocument = 0
Const wdExportOptimizeForPrint = 0
Const wdExportDocumentContent = 0
Const wdExportFormatPDF = 17
Const wdExportCreateHeadingBookmarks = 1
if Wscript.Arguments.Count > 0 Then
' Get the running instance of MS Word. If Word is not running, Create it
On Error Resume Next
Set objWord = GetObject(, "Word.Application")
If Err <> 0 Then
Set objWord = CreateObject("Word.Application")
End If
On Error GoTo 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(WScript.Arguments(0))
Set objDoc = objWord.Documents.Open(WScript.Arguments(0),,TRUE)
'Export to PDF using preferred settings
pdf = objWord.ActiveDocument.ExportAsFixedFormat( _
WScript.Arguments(1), _
wdExportFormatPDF, False, wdExportOptimizeForPrint, _
wdExportAllDocument,,, _
wdExportDocumentContent, _
False, True, _
wdExportCreateHeadingBookmarks _
)
'Quit MS Word
objWord.DisplayAlerts = False
objWord.Quit(False)
set objWord = nothing
set objFSO = nothing
Else
msgbox("You must select a file to convert")
End If
Changing the const wdExportFormatPDF to wdFormatDocumentDefault = 16 throws an error.
Any idea how to open and save as all files in the c:\temp directory?
The ExportAsFixedFormat method saves a document as PDF or XPS format..
Read more about it here.
For saving your file as docx, just use the SaveAs method.
It is available for Office 2013 and later
objWord.ActiveDocument.SaveAs ("C:\SomeDir\yourFileName.docx")

WScript / vbscript check if file in directory

IN THE BOTTOM CODE THAT WORKED
Working on a variation of Convert XLS to CSV on command line that I could use to copy xls as csv.
I just want to copy files that are not yet copied, so need to check if file already exists in my target directory.
Was thinking something like:
Set fso=CreateObject("Scripting.FileSystemObject")
Set sourcefldr=fso.getFolder(sourcepath)
Set targetfldr=fso.getFolder(targetpath)
for each sfile in sourcefldr.files
for each tfile in target
if not file in targetfldr.files then
'create excelfile and save as csv
however file in targetfldr.files not working
How can I avoid looping over all my target files every time?
tks in advance!
EDIT:
Incorporated #Pankaj Jaju and #Ansgar Wiechers answer and below is working!
csv_format = 6
sourcestring ="C:\sourcefolder"
deststring= "V:\destfolder"
Set fso=CreateObject("Scripting.FileSystemObject")
Set sourcefldr=fso.getFolder(sourcestring)
Set destfldr=fso.getFolder(deststring)
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
for each sfile in sourcefldr.files
destname = left(sfile.name,len(sfile.name)-3) & "csv"
fulldest = fso.buildpath(destfldr, destname)
if not fso.FileExists(fulldest) then
Set oBook = oExcel.Workbooks.Open(sfile)
oBook.SaveAs fulldest, csv_format
oBook.Close False
WScript.Echo "Copied " & fulldest
end if
next
oExcel.Quit
Try this !
set fso=createobject("scripting.filesystemobject")
set sourcefldr=fso.getfolder(sourcepath).files
for each sfile in sourcefldr
if not fso.fileexists(fso.buildpath(targetpath, sfile.name)) then
fso.getfile(sfile).copy(fso.buildpath(targetpath, sfile.name))
end if
next
Best bet would be add all of your target folder files into a dictionary. This way you can just use "Exists" to search for it in the dictionary.
Set fso=CreateObject("Scripting.FileSystemObject")
Set filesDic = CreateObject("Scripting.Dictionary")
Set targetfldr=fso.getFolder(targetpath)
'add destination files into dictionary
For Each file in targetfldr.files
filesDic.Add file.name, file.name
Next
This way all you need to do is check the new filename against the dictionary
filesDic.Exists(file.name)
This will just return a true / false
Here is a bit more information about the dictionary http://www.devguru.com/technologies/vbscript/13992

VBS Creating CSV file then adding extra rows to it

Below is my VBS code. I will admit, I am extremely new to this since I was give this as a job at work. I need to create a logon/logoff script that will capture certain information and store it in a csv file. I am able to get the information and store it in the csv file, but when I try to do it again, I want it to create another row and store the updated information there. I keep getting these asian characters. What seems to be the problem.
This is what I get on the second time I click my log off script:
਍潙牵琠硥⁴潧獥栠牥⹥਍
' ******************** Log Off Script **********************************
'Script to write Logoff Data Username, Computername to eventlog.
Dim objShell, WshNetwork, PCName, UserName, strMessage, strContents, logDate, logTime
Dim strQuery, objWMIService, colItems, strIP, rowCount
' Constants for type of event log entry
const EVENTLOG_AUDIT_SUCCESS = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("WScript.Shell")
Set WshNetwork = WScript.CreateObject("WScript.Network")
logDate = Date()
logTime = Time()
PCName = WshNetwork.ComputerName
UserName = WshNetwork.UserName
strMessage = "Logoff Event Data" & "PC Name: " & PCName & "Username: " & UserName & "Date: " & logDate & "Time: " & logTime
If (objFSO.FileExists("test.csv")) Then
WScript.Echo("File exists!")
dim filesys, filetxt
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.OpenTextFile("test.csv", ForAppending, True)
filetxt.WriteLine(vbNewline & "Your text goes here.")
filetxt.Close
Else
rowCount = rowCount + 1
WScript.Echo("File does not exist! File Created!")
Set csvFile = objFSO.CreateTextFile("test.csv", _
ForWriting, True)
objShell.LogEvent EVENTLOG_AUDIT_SUCCESS, strMessage
csvFile.Write strMessage
csvFile.Writeline
End If
WScript.Quit
When in doubt, read the documentation. You're creating the file in Unicode format (3rd argument of CreateTextFile set to True):
Set csvFile = objFSO.CreateTextFile("test.csv", _
ForWriting, True)
but you open an existing (Unicode) file in ASCII format (4th argument of OpenTextFile not specified):
Set filetxt = filesys.OpenTextFile("test.csv", ForAppending, True)
Either open a file in Unicode format all of the time, or never.
Also, it's unnecessary to create more than one FileSystemObject instance. Just use the one you created at the beginning throughout the entire script. You can also use the same variable for the text stream object.
If you want to use Unicode format you need to change the above two lines into this:
Set csvFile = objFSO.CreateTextFile("test.csv", False, True)
...
Set csvFile = objFSO.OpenTextFile("test.csv", ForAppending, False, True)
otherwise into this:
Set csvFile = objFSO.CreateTextFile("test.csv")
...
Set csvFile = objFSO.OpenTextFile("test.csv", ForAppending)

exporting a query output to a text file

I have an access query which I am trying to export to a text file using the following code:
DoCmd.TransferText acExportFixed, "Export Specification", _
"Test Query", "C:\Users\Documents\TestOutput.txt", True
The issue I am having is: The output file "TestOutput.txt" has the data displayed with fixed width but the column headers are comma delimited. I want the column headers to be fixed width too.
What would column headers not be displayed same as the rest of the data?
AFAICT, that is an unavoidable "feature" of TransferText. It seems to lack any kind of built-in intelligence to say "OK, we're exporting as acExportFixed, so let's examine the column widths defined in Export Specification and output the column headers using those same widths". Instead it just gives the column names as a comma-separated list.
As with everything else in Access, when its default behaviors are unsatisfactory, you can write VBA code to do it your way.
Const VB_FORREADING = 1
Const VB_FORWRITING = 2
Const cstrFile As String = "C:\Users\Documents\TestOutput.txt"
Const cstrHeaderRow As String = "col1 col2 etc..."
Dim oFSO As Object
Dim oFile As Object
Dim strContents As String
' do TransferText without the field names '
' (HasFieldNames default = False) '
DoCmd.TransferText acExportFixed, "Export Specification", _
"Test Query", cstrFile
Set oFSO = CreateObject("Scripting.FileSystemObject")
' read file content into strContents string variable '
Set oFile = oFSO.OpenTextFile(cstrFile, VB_FORREADING)
strContents = oFile.ReadAll
oFile.Close
' re-write file using cstrHeaderRow plus strContents '
Set oFile = oFSO.OpenTextFile(cstrFile, VB_FORWRITING)
oFile.write cstrHeaderRow & vbCrLf & strContents
oFile.Close
Set oFile = Nothing
Set oFSO = Nothing