Deleting all excel files in a folder through VB - vbscript

I am new to vb and would like your assistance in deleting all excel files from a specific folder.
Below if my code which is not working as I wanted:
Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists("C:\Users\Desktop\Test\Daily_Reports\*.xlsx") Then
fs.Deletefile "C:\Users\Desktop\Test\Daily_Reports\*.xlsx", true
Else
MsgBox "No"
End If

As far as I know fs.FileExists will only check to see if a single file exists, so you can't use wildcards.
You can use the VBA / VB6 native function Dir to achieve the same thing, and the native function Kill instead of DeleteFile. (DeleteFile will cope with wildcards, but Kill avoids needing the Scripting object.)
If Dir("C:\Users\Desktop\Test\Daily_Reports\*.xlsx") <> "" Then
Kill "C:\Users\Desktop\Test\Daily_Reports\*.xlsx"
Else
MsgBox "No"
End If
If you are using VBScript, you can just use
Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
For Each File In fs.GetFolder("C:\Users\Desktop\Test\Daily_Reports").Files
If fs.GetExtensionName(File) = "xlsx" Then
fs.DeleteFile File
End If
Next

Related

VBScript does not oFS.FileExists a file in oFS.CreateFolder

I'm having a strange problem with VBScript. I'd like to implement some other code with a following test:
If there is a file named like [that] in the [folder], do not copy it into the [folder].
Thing is, I found a strange relation in oFS.FileExists, I'm able to use it in a manually created folder, as long as I manually copy and paste a file into it. Then oFS.FileExists works like a charm.
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
filestr = "C:\where\file\is\file.file"
If (oFS.FileExists(filestr)) Then
WScript.Echo("File exists!")
WScript.Quit()
Else
WScript.Echo("File does not exist!")
End If
But it's not exactly my point. I'd like to test if a file is already in the desired folder, and such folder will be generated automatically with oFS.CreateFolder. But when it comes to testing an automatically generated folder, it's a different story.
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
oFS.CreateFolder(destination & objFoldername)
Initially I thought it might be something wrong with the file I'm looking for. I moved it to some other place and the oFS.FileExists found it. So I figured it might be the case of the folder itself. I can see the folder is a Read Only folder. I tested it in other manually created Read Only folder, also found it.
Finally I manually created the folder exactly like oFS.CreateFolder would do it, pasted manually a file into it and... it also found a file just fine.
As I witnessed, every test I conduct in a generated folder is failed, but done in a manually created one, pass.
Remarkable!
Had anyone such a case? Do you know why oFS.FileExists puts a blind eye on something created itself?
I'm using 64-bit Windows 10 Home, and I wrote both scrips in Visual Studio Code if that would be relevant.
Cheers guys, I can't be the first one.
EDIT for leeharvey1
Thank you leeharvey1 that you took a minute to have a look at this. This is the code that creates the directories:
Dim oFS, oFile, objShell, objFolder, sFolderPathspec, destination, file
Set oFS = CreateObject("Scripting.FileSystemObject")
sFolderPathspec = "C:\folder\where\files\are\"
Set objShell = CreateObject ("Shell.Application")
destination = "C:\folder\where\new\folders\with\files\are\intended\to\be\"
Set objFolder = objShell.Namespace(sFolderPathspec)
For Each file In objFolder.Items
name = file.Name
wykonano = objFolder.GetDetailsOf(file, 12)
If wykonano = "" Then
wykonano = objFolder.GetDetailsOf(file, 3)
End If
arr = Split(wykonano, " ")
brr = Split(arr(0), "-")
rok = brr(0)
miesiac = brr(1)
objFoldername = rok & "-" & miesiac
If CStr(oFS.FolderExists(destination & objFoldername)) >< "Prawda" Then
oFS.CreateFolder(destination & objFoldername)
End If
newdestination = destination & objFoldername & "\" & name
oFS.CopyFile sFolderPathspec & name, newdestination, False
Next
The whole testing for file existence started because I could not have the following to run:
oFS.CopyFile sFolderPathspec & name, newdestination, False
I would love it to copy but not overwrite. False, is however syntax correct, opposing to "Fałsz" (which would be correct in my Windows language). But the code crashes as soon as it hits the file that is already in the destination folder. Maybe should I have some kind of code which will let the sequence of code continue over the crashes caused by already existing files? (Like Python has)
So it took me to the following problem of testing for existence.
I figured I'll use the following method of the Files collection. As mentioned above, I get fails every time I conduct a test in generated folder, but done in a manually created one, pass.
That's the code (so far in a different VBScript file):
filestr = "C:\where\file\is\file.file"
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
If oFS.FileExists(filestr) Then
MsgBox("Jest plik")
Else
MsgBox("Nie ma pliku")
End If
Function FileExists(FilePath)
Set oFS = CreateObject("Scripting.FileSystemObject")
If oFS.FileExists(FilePath) Then
FileExists=CBool(1)
Else
FileExists=CBool(0)
End If
End Function
If FileExists(filestr) Then
WScript.Echo "Does Exist"
Else
WScript.Echo "Does not exist"
End If
If (oFS.FileExists(filestr)) Then
WScript.Echo("File exists!")
WScript.Quit()
Else
WScript.Echo("File does not exist!")
End If
So, there are some details you wanted to know:
No, I am not working against a network shared file. It's all locally on my PC's ssd.
Have you tried disabling your anti-virus? No, if I'll need to do so in order to use it, I don't need the code.
I think I need to look for a file not for a folder, there is some kind of problem to locate the file. Do you think there could be also a problem to locate the folder itself?
Check folder Owner. Well, as far as I can see in Windows folder properties, it looks and have just the same settings as any other folder over there.
Thanks again leeharvey1 for your time!

pasting a value to xlsx using shell

I have a template file in xlsx format and I want to paste a dynamic value in one particular cell i.e based on the flow of program the value in that cell will change which in turn changes conditions in xlsx file for a different process.
I have tried codes like
awk -v value=$value -v row=$row -v col=$col 'BEGIN{FS=OFS="#"} NR==row {$col=value}1' file.csv
but the issue is I cant use this code for xlsx file format. is there any way to do this for xlsx file format, since it's a template file I need to retain xlsx file format.
When I have to extract values from an Excel workbook on my Windows PC I install cygwin and then write a small shell script that does:
cygstart "/path/to/xls2csv.vbs" 'C:/cygwin64/path/to/bookName.xlsx'
awk 'whatever' '/path/to/bookName/sheetName.csv'
and the work of extracting every sheet from the workbook as a separate CSV named based on the sheet name suffixed with ".csv" under a common directory named after the workbook is done by this visual basic script:
$ cat xls2csv.vbs
csv_format = 6
Dim strFilename
Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
strFilename = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If objFSO.fileexists(strFilename) Then
Call Writefile(strFilename)
Else
wscript.echo "no such file!"
wscript.echo strFilename
End If
Set objFSO = Nothing
Sub Writefile(ByVal strFilename)
Dim objExcel
Dim objWB
Dim objws
Set objExcel = CreateObject("Excel.Application")
Set objWB = objExcel.Workbooks.Open(strFilename)
For Each objws In objWB.Sheets
objws.Copy
objExcel.ActiveWorkbook.SaveAs objWB.Path & "\" & objws.Name & ".csv", csv_format
objExcel.ActiveWorkbook.Close False
Next
objWB.Close False
objExcel.Quit
Set objExcel = Nothing
End Sub
That command would fail given blanks in file or directory names so we need to replace those with, say, underscores. In reality I usually copy the Xls file to a temp directory and give it a temp name before running the above on it so I can run the above on it without affecting the original file and without having to care about the path to the original file. It requires an absolute path to the input Excel workbook.
You might need to throw a wait and/or sleep in before the awk command to ensure the VB script is done before the awk command runs. My not shown shell code is kinda convoluted testing for the VB script creating then removing tmp files to ensure the VB script is done and looping trying and then killing Excel if it doesn't start or hangs before calling awk - I wrote it a long time ago, it's a mess, and I doubt if it's really necessary or a good approach which is why I'm not including it here.
To get those values back INTO a multi-sheet workbook you'd have to open any updated/generated CSV with Excel (or copy/paste). There's probably some other VB script could be written to import the CSVs for you just like I export them above but I've never needed that functionality so idk what that'd look like.
I don't know if you need that though - if your awk script writes CSV then you can just double click on the output .csv and Excel will happily open and display it just like it would any .xls or .xlsx Excel file.
So, to do what you want, assuming your original content is in "Sheet1" of single-sheet Excel workbook "MyStuff.xlsx" you'd do this from cygwin:
cygstart "/path/to/xls2csv.vbs" 'C:/cygwin64/path/to/MyStuff.xlsx'
wait; sleep 10 # or similar
awk -v value="$value" -v row="$row" -v col="$col" 'BEGIN{FS=OFS=","} NR==row {$col=value}1' '/path/to/MyStuff/Sheet1.csv' > "/tmp/tmp$$" &&
mv "/tmp/tmp$$" '/path/to/MyStuff/Sheet1.csv'
and then in Windows just double-click on /path/to/MyStuff/Sheet1.csv to open it in Excel (you may need to associate the .csv file suffix with Excel the first time you do that).
Note that the above will only handle simple CSVs, see What's the most robust way to efficiently parse CSV using awk? for how to robustly handle CSVs with awk in general.

VBScript While file exists

This thing is going to kill me, or I'll kill it. I can't tell what I'm doing but I keep getting a file not found after I delete the file in a while statement.
MsgBox FSO.FileExists(file.path)'Returns True as a test
While (FSO.FileExists(file.path))
If objZip.Items.Item(0).Name = FSO.getfilename(file.path) Then
FSO.DeleteFile (file.path)
MsgBox FSO.FileExists(file.path)'Returns False as a test
End If
WScript.Sleep 100
Wend
Can someone point me to what I'm doing wrong? I have similar code in another working script.
When you delete the disk file the reference to it that is stored in the file variable is no longer valid. Store the file.Path value in a variable and change your code to use it.
Dim filePath
filePath = file.Path
While FSO.FileExists( filePath )
FSO.DeleteFile filePath
Wend
Note - Previous code just exposes the approach about how to reference the file. If DeleteFile fails (we are looping to remove the file) both error handling and loop wait are needed.

.VBS called by .BAT to create .zip - run silently (without interface)?

I have a .bat file which I use to back up files, which calls a .vbs and passes it two parameters, as follows:
...
ZipCMD.vbs "C:\Source" "C:\Destination\Data.zip"
...
ZipCMD.vbs contains the following code (Credit to garbb):
Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items
numfolderitems = objShell.NameSpace(InputFolder).Items.count
objShell.NameSpace(ZipFile).CopyHere(source)
' wait until number of items in zip file is the same as in the folder we are zipping up
' also sometimes gets errors when getting folder object for zip file, probably because it is in use? so ignore these
On Error Resume Next
Do while True
numitemsinzip = objShell.NameSpace(ZipFile).Items.count
If Err.Number = 0 and numitemsinzip = numfolderitems Then
Exit Do
ElseIf Err.Number <> 0 then
Err.Clear
End If
wScript.Sleep 10
Loop
On Error Goto 0
When the zipping is occurring, the usual windows 'Compressing files' interface appears, and shows the progress bar ticking along for a few minutes, before closing and disappearing.
Question: Can vbs run a compression silently (i.e. without interface)? -- I've read this article, which shows a flag, however this doesn't appear to work with copying to .zip, for some reason.
Follow-up question: If it's not possible for the .vbs which I'm using to achieve this, then is there an alternative way, which still utilises calling another file/process(?) (.vbs / .js, or other?) and feeding it the two paths from cmd?
Edit: I'm trying to achieve this without the use of third-party software (e.g. 7zip), and simply using native windows code.
Suppose I am almost 3 months late on this, but if you have powershell version 5 or later, you can simply create a powershell script:
Compress-Archive "C:\Source" "C:\Destination\Data.zip"
or from a batch file:
powershell Compress-Archive "C:\Source" "C:\Destination\Data.zip"
Also see this option

VB Do While only works for one iteration

I've never done anything before with VB and am trying to work out a little problem with this script. Basically the script should look for all jpgs in a folder, if the file name exists already remove it from the target folder, add the value to a table and then rename the source file so it exists in the target folder.
This script works to an extent, for example it will rename any file if the file doesn't exist already but for any files that do already exist it processes only one then then ends. I can run it multiple times to clear the rest but would rather it cleared them all in one go. I have done quite a bit of reading but can't see what is going wrong. Can anyone shed any light on this?
Public Function GetLPUFileAddress()
Dim strSourceFolder As String
Dim strFile As String
Dim strTargetFolder As String
Dim dbs As DAO.Database
Dim rstMgr As DAO.Recordset
strSourceFolder = "C:\Users\Images\LPU-HOLDING\"
strFile = Dir(strSourceFolder & "*.JPG")
strTargetFolder = "C:\Users\Images\LPU\"
Do While strFile <> ""
If Dir(strTargetFolder & strFile) <> "" Then Kill strTargetFolder & strFile
CurrentDb.Execute "INSERT INTO TBL_LPU ( File_Name, Import_Date ) VALUES ('" & strFile & "',Date())"
Name strSourceFolder & strFile As strTargetFolder & strFile
strFile = Dir
Loop
End Function
By calling the Dir() function with an appropriate filter, such as "C:\Users\Images\LPU\*.JPG", you start enumeration and get the first file name.
After that, repeatedly calling the Dir() function without any parameters, you will get all *.JPG file names, one for each call.
If you at any point call Dir() with a parameter, this will reset the current enumeration and start a new one.
You therefore can't use Dir() to check existance of a file in a folder while you're enumerating with Dir(). This resets the enumeration.
You have to either use some other way of checking existance of the file, or just try to kill it without checking, ignoring the error.

Resources