Scanning multiple CSV files to append a single output file - csv

Starting with this as the code:
Const ForReading = 1
Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objSourceFile = objFSO.OpenTextFile("Path\file.csv", ForReading)
Set objDestinationFile = objFSO.OpenTextFile("Path\Database.csv", ForAppending)
'Loop start files in dir
Do Until objSourceFile.AtEndOfStream
strLine = objSourceFile.ReadLine
arrFields = Split(strLine, ",")
If arrFields(0) <> """""" Then
strContents = strContents & arrFields(1) & ","
End If
Loop
strContents = strContents & vbCrLf
objSourceFile.Close
objDestinationFile.Write strContents
'Move source file to processed directory
'Loop end files in dir
objDestinationFile.Close
Which is fine for one file at a time, but I'm trying to append many files into the single file.
Appreciate any tips.
Thanks.
Edit: So this was a request that started with a single file which turned into having to migrate many files. The original CSV needed to have its format changed and then placed into another easier to use CSV.
The issue is that there many files and each source file has to be modified before placing it into the destination file. I am new to VB Scripting and I was trying to be concise with my text. Thanks.
I appreciate the help.

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.

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?

Copy file that is updated every 15 minutes

I have an client the writes a file with data every 15 min. The name of the file is the date of that day.
So in the folder I can have for example:
2015-06-01.csv
2015-06-02.csv
2015-06-03.csv
What I want is that is to run a script every 15 minutes or if it’s possible to loop the script to see file changes.
I have been looking around an found one script that might work. But don’t get the copy file to work.
I only want to copy the file that’s been change last.
Option Explicit
Dim fso, path, file, recentDate, recentFile, filePath
Set fso = CreateObject("Scripting.FileSystemObject")
Set recentFile = Nothing
For Each file in fso.GetFolder("C:\CSV\Test\CSVOriginal").Files
If (recentFile is Nothing) Then
Set recentFile = file
ElseIf (file.DateLastModified > recentFile.DateLastModified) Then
Set recentFile = file
End If
Next
If recentFile is Nothing Then
WScript.Echo "no recent files"
Else
WScript.Echo "Recent file is " & recentFile.Name & " " & recentFile.DateLastModified
filePath = fso.GetFile(recentFile.Name)
WScript.Echo "Recent file is " & filepath
fso.CopyFile "C:\CSV\Test\CSVOriginal" +recentFile.Name,"C:\CSV\Test\CSVFlytt\"
End If
Here's one way. Loop through your folder to find the most-recently-modified file:
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFile, strNewestFile, dtmMax
For Each objFile In objFSO.GetFolder("C:\CSV\Test\CSVOriginal").Files
If objFile.DateLastModified > dtmMax Then
dtmMax = objFile.DateLastModified
strNewestFile = objFile.Path
End If
Next
objFSO.GetFile(strNewestFile).Copy "C:\CSV\Test\CSVFlytt\"

FileSystemObject - new object added to dir during the middle of a For loop

I have a VBA function that creates a FileSystemObject instance, and uses it to read the contents of a directory and perform some stuff based on conditional logic.
In the function, I use a loop that reads the contents of the dir. My question is: What happens when a new file is added to the dir after the loop has been opened but before it is closed? Does the operating system know to include this file in the collection of files? Or is a 'snapshot' of sorts taken of the dir when the loop is opened, causing the newly-added file to be overlooked?
Please correct me on any improper terminology I may have used above.
My code is below:
Function fn_FileCheckType()
'load INI data
fn_ReadINI
'does filename end with .xls or .xlsx?
'read files from iDumpFolder
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")
Dim objFolder As Object
Set objFolder = fs.GetFolder(iDumpFolder)
Dim objFile As Object
For Each objFile In objFolder.files
If (objFile.Name Like "*.xls" Or objFile.Name Like "*.xlsx") Then
'do nothing
Debug.Print objFile.Name & " is valid."
Else
'copy to invalid file archive and delete from inbox
objFile.Copy (iInvalidArchive & "\" & objFile.Name)
MsgBox (objFile.Name & " is not saved as .xls or .xlsx. Please modify and re-import.")
objFile.Delete
End If
Next 'objFile
'Cleanup
Set objFolder = Nothing
Set objFile = Nothing
Set fs = Nothing
End Function
The following VBA code indicates that the .Files collection is a "snapshot" of the files in a folder at the moment that the collection is referenced. Before running the code I placed two files in the test folder: b.txt and c.txt. The Debug.Assert statement suspends the code immediately after entering the loop for the first time. While paused, I added the files a.txt and d.txt and then hit F5 to resume execution. The code only lists the two files that were originally in the folder.
Option Compare Database
Option Explicit
Public Sub FilesCollectionTest()
Dim fso As New FileSystemObject, objFolder As Folder, objFile As File, i As Long
Set objFolder = fso.GetFolder("C:\__tmp\zzzTest")
i = 1
For Each objFile In objFolder.Files
Debug.Assert i > 1
Debug.Print objFile.Name
i = i + 1
Next
Set objFile = Nothing
Set objFolder = Nothing
Set fso = Nothing
End Sub
The way you have your example written objFolder.files is re-evaluated on every iteration and would thus pick up any change. But, I was a little surprised to see that if you so something like
Dim fso As New FileSystemObject
Dim files, f
Set files = fso.GetFolder("C:\~\My test Folder").files
For Each f In files
debug.print f.name
Next f
Debug.Print ' break point here
Debug.Print
That even if you are not in the loop Files is refreshed. I put a breakpoint on the firs Print after the loop, added a file to my folder then hit F8, and Files updated to the right file count.

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