xlsx to csv: unwantedly asks for confirmation, cannot select range - csv

When I want to convert a xlsx file into a csv with the following code:
WorkingDir = "C:\Users\Admin\Documents\example.xlsx"
Dim fso, FileName, SaveName, myFile
Dim objExcel, objWorkbook
Set fso = CreateObject("Scripting.FilesystemObject")
Set myFile = fso.GetFile(WorkingDir)
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
objExcel.DisplayAlerts = True
FileName = Left(myFile, InStrRev(myFile, "."))
Set objWorkbook = objExcel.Workbooks.Open(myFile)
objWorkbook.Sheets(1).Range("A2:C2").Select
SaveName = FileName & "csv"
objWorkbook.SaveAs SaveName, 23
objWorkbook.Close
Set objWorkbook = Nothing
Set objExcel = Nothing
Set fso = Nothing
Set myFolder = Nothing
It works but asks me if i want to save my changes in the example.csv file. The saving should work without confirming and also should overwrite an eventually existing .csv file.
The second problem is that the range command where i select a specific part (rows and coumns) of the example.xlsx file which will be converted into a .csv file doesnt work. But there is no error. It seems that the vbscript jumps over this command.
Thank you in advance.

Try telling Excel that the file is already saved
objWorkbook.Saved = true
objWorkbook.Close
In terms of saving your select range, you could try
objWorkbook.Sheets(1).Range("A2:C2").Copy
dim sheet: set sheet = objWorkbook.Sheets.Add()
' Add()ing should actually activate the sheet
' sheet.Activate
sheet.Paste
' SaveAs will save the active sheet
objWorkbook.SaveAs FileName, 23
In otherwords, you need to duplicate the data in a second worksheet then save that worksheet as your csv. Closing the workbook (xlsx) without saving it will discard that new sheet.

Related

Uploading Records from Excel file to Server - Desktop App

I have requirements as below :
There is a folder named BATCH inside D:// drive of my PC.
Now this D://BATCH contains excel files with any random names. Every excel file has only one record.
I have to create .exe file or any Desktop Application which lets the user to browse the BATCH folder and then can upload the content or data from the excel files to our Server. We have to put the excel data into JSON and then have to upload it to the server.
One more thing is that If I have uploaded data from 3 files and then again user tries to upload by selecting the folder, data which are new or not uploaded only those data should be upload. The data in BATCH folder is generating daily with connected machine.
My background is for Web and Mobile development. So, little bit confused of achieving this thing as explained above.
So, How can I achieve this? Which technology I have to use or which are the tools that can be useful?
Thanks for the support.
There are probably a bunch of ways to skin this cat. Maybe import everything from all Excel files in the folder into one single Excel file, and export this to SQL Server. Just a thought.
Sub InsertInto()
'Declare some variables
Dim cnn As adodb.Connection
Dim cmd As adodb.Command
Dim strSQL As String
'Create a new Connection object
Set cnn = New adodb.Connection
'Set the connection string
cnn.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=Northwind;Data Source=Server_Name"
'Create a new Command object
Set cmd = New adodb.Command
'Open the Connection to the database
cnn.Open
'Associate the command with the connection
cmd.ActiveConnection = cnn
'Tell the Command we are giving it a bit of SQL to run, not a stored procedure
cmd.CommandType = adCmdText
'Create the SQL
strSQL = "UPDATE TBL SET JOIN_DT = '2019-12-10' WHERE EMPID = 2"
'Pass the SQL to the Command object
cmd.CommandText = strSQL
'Execute the bit of SQL to update the database
cmd.Execute
'Close the connection again
cnn.Close
'Remove the objects
Set cmd = Nothing
Set cnn = Nothing
End Sub
Just to embellish my original answer a bit...you can easily import data from multiple excel files in a folder, into one single Excel file, using a concept like the one below.
Sub Basic_Example_1()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
'Fill in the path\folder where the files are
MyPath = "C:\Users\Ron\test"
'Add a slash at the end if the user forget it
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
'If there are no Excel files in the folder exit the sub
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
'Fill the array(myFiles)with the list of Excel files in the folder
Fnum = 0
Do While FilesInPath <> ""
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = FilesInPath
FilesInPath = Dir()
Loop
'Change ScreenUpdating, Calculation and EnableEvents
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
'Loop through all files in the array(myFiles)
If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(Fnum))
On Error GoTo 0
If Not mybook Is Nothing Then
On Error Resume Next
With mybook.Worksheets(1)
Set sourceRange = .Range("A1:C1")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all columns then skip this file
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "Sorry there are not enough rows in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in column A
With sourceRange
BaseWks.cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.Range("B" & rnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
See the link below for some ideas of how to get data from several Excel files/sources, consolidate into one single file/source.
http://www.rondebruin.nl/win/s3/win008.htm
Keep an open mind about this kind of stuff. There are several other ways to do essentially the same kind of thing.
The question is too broad and you can achieve your requirement in many ways.
If you consider using c# you can develop a WPF or Winforms Project.
You will need to follow these basic steps
A function to browse and pick your file like FolderBrowserDialog available in System.Windows.Forms. In case you are using WPF you have to add reference to the library
Read the excel contents. In this case you may need references to any library/nuget package like Epplus, Microsoft.Office.Interop.Excel, LinqToExcel or ExcelLibrary
Convert data to json format using Newtonsoft.Json nuget package
Upload or save data to SQL Server - Here you would need a connection string to the database and save the same in your .config file. you can use ADO, linq to sql etc for that.
Sample Code
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel files (*.xls)|*.csv|All files (*.*)|*.*";
if (openFileDialog.ShowDialog()== DialogResult.OK)
{
//Open file and read contents
var excelFile = new LinqToExcel.ExcelQueryFactory(path);
var query =
from row in excelFile.Worksheet("Sheet1")
let item = new
{
Column1 = row["Column1"].Cast<string>(),
Column2 = row["Column2"].Cast<int>(),
}
select item;
foreach (var item in query)
{
MyCustomClass myClass = new MyCustomClass();
myClass.Column1 = item.Column1;
myClass.Column2 = item.Column2;
//Do something
}
//convert to json
// Save to database
}

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.

Excel Error-The number in this cell is formatted as text or preceded by an Apostrophe

This function will export and format data to excel. However, the spreadsheet output has some data error in green as described above- So I place inside the function a code to clear this up and this does not work. Thanks for your help.
Function frmatEx()
Dim FileName As String
FileName = "C:\FolderName"
'Set xl = New Excel.Application
Set xl = CreateObject("Excel.Application")
Set wb = xl.Workbooks.Open(FileName)
With wb.Sheets(1)
.Columns("E:E").NumberFormat = "m/d/yyyy"
.Columns("A:DA").HorizontalAlignment = xlCenter
.Rows("BE:BE").ErrorCheckingOptions.NumberAsText = False
.Rows("1:1").Columns.AutoFit
End With
wb.Save
wb.Close True
Set wb = Nothing
xl.Quit
Set xl = Nothing
End Function
I will make a guess that this line is the problem:
.Rows("BE:BE").ErrorCheckingOptions.NumberAsText = False
The ErrorCheckingOptions.NumberAsText Property is not a property of a range, but a global Excel option.
So you'd have to do
xl.ErrorCheckingOptions.NumberAsText = False
but of course that will apply to all Excel files from then on.
Perhaps in a new question show how/what you are exporting, so the root problem can be solved.

VBS create a file to each row of .csv

I am a begginer with vbscript and I need to do one but It's not working. I need to create a Vbs that creates files for every row of a .csv file, but that new files have to have the name of the first colunm.
The csv below for example. I need to create a file with each rows content but the name of the new files have to be the name of each first colunm, "File1.txt"..."File4.txt"..."File3.docx".
File1.txt Whatever0
File4.txt Whatever4
File3.docx Whatever3
File7.csv Whatever9
File.xsl Whatever1
This is the .vbs I have up to now
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim destinationFolderName
destinationFolderName = "C:\Vbs_Files\OUT"
Set destinationFolder = objFSO.GetFolder(destinationFolderName)
Dim originalFolderName
originalFolderName = "C:\Vbs_Files\Excel"
Set originalFolder = objFSO.GetFolder(originalFolderName)
Do Until objInput.AtEndOfStream
line = objInput.ReadLine
IF line <> "" Then
Set objFile = objFSO.CreateTextFile(destinationFolder & colunm(0))
Set objFile = objFSO.CreateTextFile("C:\Vbs_Files\Temp" & colunm(1))
FileSystemObject.CopyFile "C:\Vbs_Files\Temp", "C:\Vbs_Files\OUT"
End if
Loop
Could you help me with this?

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