It is my first vbs experience.
I try to keep my Problem short.
This one works, when I run it with my .bat:
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\.....\RunScript.xlsm", 0,
True)
xlApp.Run "Auto_Open"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
And this one works (shows me my corect current directory with my file):
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
sScriptDir = oFSO.GetParentFolderName(WScript.ScriptFullName)
Wscript.Echo sScriptDir & "\RunScript.xlsm"
But if I combine them, it does not work:
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
sScriptDir = oFSO.GetParentFolderName(WScript.ScriptFullName)
Set fileDirectory = sScriptDir & "\RunScript.xlsm"
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open(fileDirectory, 0,
True)
xlApp.Run "Auto_Open"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
Like I said, thank you Dave. That works.
However I found another issue, now with vbA inside the RunScript.xlsm
This code works with the vbS before:
Sub Auto_Open()
Application.DisplayAlerts = False
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.SaveAs Filename:= _
"C:\...\MyCSV.csv" _
, FileFormat:=xlCSV, CreateBackup:=False
Application.DisplayAlerts = True
ThisWorkbook.Saved = True
Application.Quit
End Sub
But if I change here the path, it just works when I run the RunScript.xlsm, but not when I run my vbS:
Sub Auto_Open()
Application.DisplayAlerts = False
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
Dim relativePath As String
relativePath = Application.ActiveWorkbook.path & "\MyCSV.csv"
ActiveWorkbook.SaveAs Filename:=relativePath, FileFormat:=xlCSV, CreateBackup:=False
Application.DisplayAlerts = True
ThisWorkbook.Saved = True
Application.Quit
End Sub
I think it is beacause of the ActiveWorkbook, I tried already ThisWorkbook, and I tried it without Application.
Related
I am trying to get a .vbs to download files from google drive as I have had it working as a macro inside excel. It would just be overall easier without needing to go into excel to run the script. I have tried to Frankenstein the working code within the macro which downloads the file to downloads with some other but have got lost. I am still a rookie so if the code is less than ideal would appreciate some feedback.
As a note: The userprofile was attempted to be set as variable for multiple users with differently mapped download folders to still run it.
Ran macro in excel which achieved downloading the file.
Tried to create .vbs with similar code and failed
Option Explicit
Dim FileNum
Dim FileData
Dim MyFile
Dim WHTTP
Dim strDisplayName
Dim oShell
Dim strHomeFolder
Dim vbDirectory
Dim dir
Set oShell = CreateObject("WScript.Shell")
strHomeFolder = oShell.ExpandEnvironmentStrings("%USERPROFILE%")
'Set strDisplayName = CreateObject("Scripting.FileSystemObject")
'Set objAD = CreateObject("ADSystemInfo")
'Set objUser = GetObject("LDAP://" & objAD.UserName)
'strDisplayName = objUser.DisplayName
On Error Resume Next
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")
If Err.Number <> 0 Then
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
End If
On Error GoTo 0
MyFile = "https://drive.google.com/open?id=1Hx5DymjrhaiM8Rb7NMP_Sde_JU2N2Rau"
WHTTP.Open "GET", MyFile, False
WHTTP.send
'On Error Resume Next
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
If Dir(strHomeFolder & "\Downloads", vbDirectory) = Empty Then MkDir strHomeFolder & "\Downloads"
Dim xlApp, xlBook
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open(strHomeFolder & "\Downloads\External Linking.xlsm", 0, True)
'D:\Users\cdoyle\Desktop\External linking.xlsm
'https://drive.google.com/open?id=1Hx5DymjrhaiM8Rb7NMP_Sde_JU2N2Rau
'"C:\Users\ciara\OneDrive\BayswaterBridge.xlsm"'
xlApp.Run "BridgeHit"
'xlbook.Save False
xlBook.Close False
set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
'WScript.Echo "Finished."
WScript.Quit
Keep getting some errors on If Dir(
line and seem to be chasing my tail.
I'm trying to create a VBS script that will grab all the fonts from the server font location so that the domain user will have the ability to use them. When I run this script I get a line 15 char 1 error: 800A400C.
Not sure what is wrong with it or if this script will do the job I'm wanting it to do.
'On Error Resume Next
'Option Explicit
Dim objShell, objFSO, wshShell
Dim strFontSourcePath, objFolder, objFont, objNameSpace, objFile, strFontsSytem
Set objShell = CreateObject("Shell.Application")
Set wshShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FilesyStemObject")
strFontSourcePath = "\\server\Fonts\"
strFontsSytem = WSHShell.SpecialFolders("Fonts") & "\"
Set objNameSpace = objShell.Namespace(strFontSourcePath)
Set objFolder = objFSO.GetFolder(strFontSourcePath)
For Each objFile In objFolder.Files
If LCase(Right(objFile, 4)) = ".ttf" Or LCase(Right(objFile, 4)) = ".otf" Then
Set objFont = objNameSpace.ParseName(objFile.Name)
If objFSO.FileExists(strFontsSytem & objFile.Name) = False Then
objFont.InvokeVerb("Install")
Set objFont = Nothing
End If
End If
Next
Set objShell = Nothing
Set wshShell = Nothing
Set objFSO = Nothing
Set objNameSpace = Nothing
Set objFolder = Nothing
WScript.Quit
Error code 800A004C means Path not found. Please check the existance of the strFontSourcePath and like Ansgar says also check if the user running this code has access to this share.
Anyway, Here's my code to copy and install fonts from a server share if that is any help
Call AddFonts("\\server\Fonts\")
WScript.Quit
Private Sub AddFonts(strFromPath)
' install fonts from a server location if not already present
Dim appShell, objShell, objFSO, colFiles, objFile, objFolder
Dim strToPath, flags, strFile, strExt
'SpecialFolder. See: https://technet.microsoft.com/en-us/library/ee176604.aspx
Const FONTFOLDER = &H14&
'CopyHere switches
Const FOF_MULTIDESTFILES = &H1&
Const FOF_CONFIRMMOUSE = &H2&
Const FOF_SILENT = &H4&
Const FOF_RENAMEONCOLLISION = &H8&
Const FOF_NOCONFIRMATION = &H10&
Const FOF_WANTMAPPINGHANDLE = &H20&
Const FOF_ALLOWUNDO = &H40&
Const FOF_FILESONLY = &H80&
Const FOF_SIMPLEPROGRESS = &H100&
Const FOF_NOCONFIRMMKDIR = &H200&
Const FOF_NOERRORUI = &H400&
Const FOF_NOCOPYSECURITYATTRIBS = &H800&
Const FOF_NORECURSION = &H1000&
Const FOF_NO_CONNECTED_ELEMENTS = &H2000&
Const FOF_WANTNUKEWARNING = &H4000&
On Error Resume Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = Createobject("Wscript.Shell")
Set appShell = CreateObject("Shell.Application")
'create an object for the systems fonts folder
Set objFolder = appShell.Namespace(FONTFOLDER)
'make sure these paths end in a backslash
strFromPath = FixPath(strFromPath)
'get the name of the system fonts folder (C:\WINDOWS\Fonts)
strToPath = FixPath(objShell.SpecialFolders("Fonts"))
'set flags to install as quiet as possible.
flags = FOF_SILENT Or FOF_NOCONFIRMATION Or FOF_NOERRORUI Or _
FOF_NOCONFIRMMKDIR Or FOF_NOCOPYSECURITYATTRIBS
If (Not objFolder Is Nothing) Then
If objFSO.FolderExists(strFromPath) Then
Set colFiles = objFSO.GetFolder(strFromPath).Files
If colFiles.Count > 0 Then
For Each objFile In colFiles
strExt = objFSO.GetExtensionName(objFile.Name)
Select Case LCase(strExt)
Case "ttf", "otf" ' can also be used for "fon", "pfm", "pfb", "afm"
'get the complete path and filename for this font file and check if already there
strFile = strToPath & objFile.Name
If Not (objFSO.FileExists(strFile)) Then
objFolder.CopyHere strFromPath & objFile.Name, flags
End If
End Select
Next
End If
End If
End If
'cleanup objects
Set appShell = Nothing
Set colFiles = Nothing
Set objFile = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
Set objShell = Nothing
End Sub
Private Function FixPath(sPath)
'small helper function to ensure a path ends in a backslash
If Len(sPath) > 0 And Right(sPath, 1) <> "\" Then
FixPath = sPath & "\"
Else
FixPath = sPath
End If
End Function
I tried to combine a couple different scripts, which works fine until I change the path of strPath. The moment I change it to anything else I get an error message
Invalid Procedure call or argument.
The script is meant to find the latest file in any directory (including subfolders), and copy and paste the file into a folder
Dim strPath, oFSO, oFile, oFolder, dteDate, strName, N
strPath = "C:\Users\parjo16\Documents\Archived"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(strPath)
For Each oFile In oFolder.Files
If oFile.DateLastModified > dteDate Then
dteDate = oFile.DateLastModified
strName = oFile.Name
End If
N = N + 1
Next 'oFile
Call FindTheSubFolderFiles(oFolder, N, dteDate, strNme)
Const strfolder = "C:\SalaryData\"
Const Overwrite = True
Dim oFSOd
Set oFSOd = CreateObject("Scripting.FileSystemObject")
If Not oFSOd.FolderExists(strfolder) Then
oFSOd.CreateFolder strfolder
End If
oFSOd.CopyFile strNme, strfolder & "salaries.xlsx", Overwrite
Set oFSOd = Nothing
Set oFSO = Nothing
Set oFile = Nothing
Set oFolder = Nothing
Function FindTheSubFolderFiles(ByRef oParentFolder, ByRef lngR, ByRef dteDte, ByRef strNme)
Dim oSubFolder
Dim oFile
For Each oSubFolder In oParentFolder.SubFolders
For Each oFile In oSubFolder.Files
If oFile.DateLastModified > dteDte Then
dteDte = oFile.DateLastModified
strNme = oFile.Path
End If
lngR = lngR + 1
Next
FindTheSubFolderFiles oSubFolder, lngR, dteDte, strNme
Next 'oSubFolder
Set oSubFolder = Nothing
Set oFile = Nothing
End Function
Looks like the script was doing two checks, one for the main folder, one for the subfolder. If the result is the other, then it comes back blank.
This seems to be working now:
Function FindTheSubFolderFiles(ByRef oParentFolder, ByRef lngR, ByRef dteDte, ByRef strNme)
Dim oSubFolder
Dim oFile
For Each oSubFolder In oParentFolder.SubFolders
For Each oFile In oSubFolder.Files
If oFile.DateLastModified > dteDte Then
dteDte = oFile.DateLastModified
strNme = oFile.path
End If
lngR = lngR + 1
Next
FindTheSubFolderFiles oSubFolder, lngR, dteDte, strNme
Next 'oSubFolder
Set oSubFolder = Nothing
Set oFile = Nothing
End Function
Dim strPath, oFSO, oFile, oFolder, dteDate, strName, N
strPath = "C:\Users\parjo16\Documents\Archived\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(strPath)
For Each oFile In oFolder.Files
If oFile.DateLastModified > dteDate Then
dteDate = oFile.DateLastModified
strName = oFile.Name
End If
N = N + 1
Next 'oFile
Call FindTheSubFolderFiles(oFolder, N, dteDate, strNme)
Const strfolder = "C:\SalaryData\"
Const Overwrite = True
Dim oFSOd
Set oFSOd = CreateObject("Scripting.FileSystemObject")
If Not oFSOd.FolderExists(strfolder) Then
oFSOd.CreateFolder strfolder
End If
On Error Resume Next
oFSOd.CopyFile strPath & strName, strfolder & "salaries.xlsx", Overwrite
oFSOd.CopyFile strNme, strfolder & "salaries.xlsx", Overwrite
Set oFSOd = Nothing
Set oFSO = Nothing
Set oFile = Nothing
Set oFolder = Nothing
I have been given a task of creating a script that takes a log file (date is in the filename), pulls the data and posts it in event manager. I have a script that works as it should I know the script is ugly so please be gentle. I'm looking for 2 things.
some days nothing has happened and no log for the day was created. when this happens my script causes all kinds of slowness in the PC. I need help with a way for the script to not do its task if no new file has been added to the logs folder.
I would like a little help cleaning up the script.
Like i said i'm very new to this and i used scripts found on the web and fit them to do what i needed them to do.
any help would be greatly appricated.
Option Explicit
Const ForReading = 1
Dim strfolder
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strFileParts
Dim objShell
Dim objFSO
Dim objFolder
Dim strFileName
Dim objFile
Dim objTextFile
Dim strNextLine
Dim arrServiceList
Dim i
strFolder = "C:\Logs\"
Set objShell = CreateObject ("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(strFolder)
Set objShell = CreateObject ("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile ("C:\Logs\logCatchAll.log", ForReading)
For Each strFileName in objFolder.Items
If len(objFSO.GetExtensionName(strFileName)) > 0 Then
Set objFile = objFSO.GetFile(strFolder & strFileName.Name)
If DateDiff("H",objFile.DateLastModified,Now()) > 24 Then
objFSO.DeleteFile(strFolder & strFileName.Name),True
End If
End If
next
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FLD = FSO.GetFolder(strfolder)
For Each fil in FLD.Files
strOldName = fil.Path
If InStr(strOldName, "-") > 0 Then
strFileParts = Split(strOldName, "-")
strNewName = strFileParts(0) & ".log"
FSO.MoveFile strOldName, strNewName
End If
Next
Set FLD = Nothing
Set FSO = Nothing
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
arrServiceList = Split(strNextLine , ",")
For i = 3 to Ubound(arrServiceList)
objshell.LogEvent 4, arrServiceList(i)
Loop
You can block your Dim'd variables
You are reactivating the objShell to many times
You have a for loop at the bottom of your code without a Next statement.
You don't need to iterate through the log file until it reaches AtEndOfStream, just store it in a variable first.
You can use the same objFSO more than once if your not resetting the object.
You need to include error handling so you know where your code breaks.
Revised code.
Option Explicit
'Handle errors manually.
On Error Resume Next
'Set Constants
Const ForReading = 1
'Set Strings
Dim strFolder, strOldName, strNewName, strFileName, strFileParts, strNextLine, TFStrings
strFolder = "C:\Logs\"
'Set Objects
Dim objShell, objFSO, objFolder, objFile, objTextFile
Set objShell = CreateObject ("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objShell.Namespace(strFolder)
TFStrings = split(objFSO.OpenTextFile("C:\Logs\logCatchAll.log", ForReading).ReadAll, vbcrlf)
'Set Other Variables
Dim FLD, fil, arrServiceList, i, executed
executed = false
'Delete file procedure...
For Each strFileName in objFolder.Items
If len(objFSO.GetExtensionName(strFileName)) > 0 Then
Set objFile = objFSO.GetFile(strFolder & strFileName.Name)
If DateDiff("H",objFile.DateLastModified,Now()) > 24 Then
objFSO.DeleteFile(strFolder & strFileName.Name),True
executed = true
End If
End If
Next
If executed then
If err.number <> 0 then
'File was found, but delete was unsuccessful, log failure of delete.
executed = false
err.clear
Else
'Delete file procedure executed successfully. Lets move on.
executed = false
End If
Else
'No file was found within the conditions. log failure of search.
End if
'Move file and rename procedure...
Set FLD = objFSO.GetFolder(strfolder)
For Each fil in FLD.Files
strOldName = fil.Path
If InStr(strOldName, "-") > 0 Then
strFileParts = Split(strOldName, "-")
strNewName = strFileParts(0) & ".log"
objFSO.MoveFile strOldName, strNewName
executed = true
End If
Next
Set FLD = Nothing
Set FSO = Nothing
If executed then
If err.number <> 0 then
'File was found, but move was unsuccessful, log failure of move.
executed = false
err.clear
Else
'Move file procedure executed successfully. Lets move on.
executed = false
End If
Else
'No file was found within the conditions. log failure of search.
End if
For Each line in TFStrings
strNextLine = line
arrServiceList = Split(strNextLine , ",")
For i = 3 to Ubound(arrServiceList)
objshell.LogEvent 4, arrServiceList(i)
Next
Next
Using the following code that I pulled from the web, I'm able to do a search in a single directory for excel files containing a string in a certain row. How would I allow this to be recursive in all the subfolders as well? I've found a few answers but I just don't understand how I would implement them in my code. I only started messing with VBScript yesterday and I'm pretty confused about how to make this work.
strComputer = "CAA-W74109188"
Set objExcel = CreateObject("Excel.Application", strComputer)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set FileList = objWMIService.ExecQuery _
("ASSOCIATORS OF {Win32_Directory.Name='c:\TDRS'} Where " _
& "ResultClass = CIM_DataFile")
For Each objFile In FileList
If (objFile.Extension = "xlsm" or objFile.Extension = "xls") Then
Set objWorkbook = objExcel.Workbooks.Open(objFile.Name)
Set objWorksheet = objWorkbook.Worksheets(1)
If objExcel.Cells(3,10) = "Complete" or objExcel.Cells(3,9) = "Released" Then
Wscript.Echo objFile.FileName
End If
objExcel.DisplayAlerts = False
objworkbook.Saved = False
objWorkbook.Close False
End If
Next
objExcel.Quit
Here is an script that I used to delete files with, which I have modified for your needs. A recursive function is what you need to get the job done and I have always found them to be interesting and kind of hard to wrap my head around.
Dim Shell : Set Shell = WScript.CreateObject( "WScript.Shell" )
Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim objExcel : Set objExcel = CreateObject("Excel.Application")
Dim Paths(0)
Paths(0) = "c:\temp"
For Each Path in Paths
FolderScan(Path)
Next
Sub FolderScan(Folder)
Set base = oFSO.GetFolder(Folder)
If base.SubFolders.Count Then
For Each folder in Base.SubFolders
FolderScan(folder.Path)
Next
End If
Set files = base.Files
If files.Count Then
For Each File in files
If LCase(oFSO.GetExtensionName(File.Path) = "xlsm") or _
LCase(oFSO.GetExtensionName(File.Path) = "xls") Then
Dim objWorkbook : Set objWorkbook = objExcel.Workbooks.Open(File.Path)
Dim objWorkSheet : Set objWorkSheet = objWorkbook.Worksheets(1)
If (objExcel.Cells(3,10) = "Complete" or _
objExcel.Cells(3,9) = "Released") Then
Wscript.echo File.Path
End if
objExcel.DisplayAlerts = False
objExcel.Quit
End If
Next
End If
End Sub
Here's a generic, recursive function that iterates all files and subfolders of a given folder object.
Dim FileSystem
Set FileSystem = CreateObject("Scripting.FileSystemObject")
DoFolder FileSystem.GetFolder("c:\somefolder")
Sub DoFolder(Folder)
Dim SubFolder
For Each SubFolder In Folder.SubFolders
DoFolder SubFolder
Next
Dim File
For Each File In Folder.Files
' Operate on each file
Next
End Sub