This VBScript errs as "unknown runtime error", on the VBScript line that calls the application object's RUN method, which I'm quite sure I'm using correctly, syntactically.
With only one workbook open under the application object, I probably don't even need to prefix it with the Workbookname.
It appears the previous line (which sets the wb variable to the application object's Workbooks.Open method, does not open. Nor does it err, nor does it "eventually" open. The path is correct, the filename is correct, there is no On Error Resume Next in my VBScript.
How can the workbook not open and not error?
I hope I am wrong in thinking there is a "wait/pause" issue. Acting directly on the Excel object model, it seems like the VBScript code waiting until the excelapp object has opened the workbook should be a given?
dim excelapp, wb
set excelapp = createobject("excel.application")
excelapp.enableevents=true
excelapp.visible=true
set wb = excelapp.workbooks.open("C:\Users\John\Desktop\Scheduled Jobs from Isaac\Availability.xlsb")
'MSGBOX "SHOULD BE OPEN"
excelapp.windowstate = -4137 'value for constant xlMaximized acccording to msdn
excelapp.caption = "Running AVAILABILITY - Please WAIT..."
excelapp.run "Availability.xlsb!ChangeAndCopyFile"
final vbscript code i used, for better or worse:
dim excelapp, wb
'set excelapp = createobject("excel.application")
'excelapp.enableevents=true
'excelapp.visible=true
'set wb = excelapp.workbooks.open("C:\Users\John\Desktop\ScheduledJobsfromIsaac\Availability.xlsb")
'although I don't know why the above line is silently failing, i'm going to use an alternate method I read on S.O.:
set wb = GetObject("C:\Users\John\Desktop\ScheduledJobsfromIsaac\Availability.xlsb")
set excelapp = getobject(,"excel.application")
excelapp.enableevents=true
excelapp.visible=true
excelapp.windowstate = -4137 'value for constant xlMaximized acccording to msdn
excelapp.caption = "Running AVAILABILITY - Please WAIT..."
excelapp.run "Availability.xlsb!ChangeAndCopyFile"
wb.close(true)
excelapp.caption = "10 seconds to close - please WAIT..."
wscript.sleep 10000
excelapp.displayalerts=false
excelapp.quit
probably, it helps if you can describe where and how you execute your vbscript above? is this coded in a .vbs file and execute with wscript.exe or cscript.exe, or embedded in a HTML or HTA?
If this is scripted in HTML, what browser are you using to view that? Please take note that almost all modern browsers will just ignore the vbscript silently.
Related
I have some code for exporting subform results to Excel workbook. Code works fine, only one small issue. If I do export, excel file opens If user wants I open. When this Excel file is opened and user wants to do Export again, I receive error 1004.
This error is produced because file is open, and new Excel object want to save a file with same name. What I want is when this happens, just cancel everything and let user know that he must first close this previously created workbook. Here is what I tried:
If Err.Number = 1004 Then
MsgBox "Error. You have opened Excel file, that has same name as this file name should be. Please close that file first !", vbCritical
Cancel = True
Set wb = Nothing ' wb is wb=XcelFile.Workbooks.Add
Set XcelFile = Nothing ' Xcelfile is Xcelfile= New Excel.Application
End If
This code works, when user closes that file, export can be performed - old file is just overwritted. Problem is that Excel application is still opened in Windows Task Manager, so Excel object is not properly closed.
Does anybody have a better solution ?
P.S.: I tried including numbers in file name of Excel, so that It wouldn't be same name, but I can't get It fixed.
EDIT: Here is how I tried changing filename
Dim i as Integer
ExcelFilename = "RESULTS_" & Format(Date, "dd/mm/yyyy") & "_" & i & "_" & ".xlsx"
i = i + 1
"i" doesn't change It's value when I run code once again. How can I make it increment ? This would solve my problem...
I suggest a simple solution: add the time to the file name to prevent conflicts.
ExcelFilename = "RESULTS_" & Format(Now(), "yyyy-mm-dd_hh-nn-ss") & ".xlsx"
For a number that will increment as long as the application is running, try
Static i As Integer
Static variables
You must be very strict in opening the Excel objects and closing them in reverse order - as done in this example:
Public Sub RenameWorkSheet()
Dim xls As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Set xls = New Excel.Application
Set wkb = xls.Workbooks.Open("c:\test\workbook1.xlsx")
Set wks = wkb.Worksheets(1)
wks.Name = "My New Name"
wkb.Close True
Set wks = Nothing
Set wkb = Nothing
xls.Quit
Set xls = Nothing
End Sub
I have a PowerPoint macro that should open an Excel file.
Public Sub SortList()
Dim MyFile as String
Dim xlApp as Object
Dim xlWorkBook as Object
Set xlApp = CreateObject("Excel.Application")
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
MyFile = SelectedItems(1)
End With
xlApp.Visible = True
xlApp.Workbooks.Open MyFile
Set xlWorkBook = xlApp.Workbooks.Open(MyFile)
This code was previously working with no errors. However, I have started receiving the error message
"Run-time error '-2147467259 (80004005)': Method 'Open' of object 'Workbooks' failed."
The error occurs when trying to run the "Set" line of code.
The issue is that I can see that the code is successfully opening the Excel file!
Things I have tried (in about every possible combination):
-Changing the code to this (I thought maybe the program was trying to open the file twice):
xlApp.Visible = True
Set xlWorkBook = xlApp.Workbooks.Open(MyFile)
-Adding ReadOnly:= True to both or either .Open command, at one point this gave me an "Automation error- unspecified error" message which I have never seen before...
-Changing the Set line to this (and variations thereof):
xlApp.Workbooks.Open MyFile
Set xlWorkBook = xlApp.Workbooks(Dir(MyFile))
-Ensuring Excel is completely closed prior to running the code
The frustrating aspect is that this code worked perfectly last week, so I'm also at a loss as to why it would suddenly stop working. Any assistance would be greatly appreciated.
Workbooks.Open can cause issues if you call it on an already open workbook.
So, don't open twice. Remove the following line:
xlApp.Workbooks.Open MyFile
I have a xlsx macro enabled file . How can I set it in the task manager so that everyday at 9 AM task manager would open the workbook, fire the macro and close the workbook.
So far i am using
Application.OnTime . . .
But i realize that keeping the xlsm file open is inconvenient
Better to use a vbs as you indicated
Create a simple vbs, which is a text file with a .vbs extension (see sample code below)
Use the Task Scheduler to run the vbs
Use the vbs to open the workbook at the scheduled time and then either:
use the Private Sub Workbook_Open() event in the ThisWorkbook module to run code when the file is opened
more robustly (as macros may be disabled on open), use Application.Run in the vbs to run the macro
See this example of the later approach at Running Excel on Windows Task Scheduler
sample vbs
Dim ObjExcel, ObjWB
Set ObjExcel = CreateObject("excel.application")
'vbs opens a file specified by the path below
Set ObjWB = ObjExcel.Workbooks.Open("C:\temp\rod.xlsm")
'either use the Workbook Open event (if macros are enabled), or Application.Run
ObjWB.Close False
ObjExcel.Quit
Set ObjExcel = Nothing
Three important steps - How to Task Schedule an excel.xls(m) file
simply:
make sure the .vbs file is correct
set the Action tab correctly in Task Scheduler
don't turn on "Run whether user is logged on or not"
IN MORE DETAIL...
Here is an example .vbs file:
`
' a .vbs file is just a text file containing visual basic code that has the extension renamed from .txt to .vbs
'Write Excel.xls Sheet's full path here
strPath = "C:\RodsData.xlsm"
'Write the macro name - could try including module name
strMacro = "Update" ' "Sheet1.Macro2"
'Create an Excel instance and set visibility of the instance
Set objApp = CreateObject("Excel.Application")
objApp.Visible = True ' or False
'Open workbook; Run Macro; Save Workbook with changes; Close; Quit Excel
Set wbToRun = objApp.Workbooks.Open(strPath)
objApp.Run strMacro ' wbToRun.Name & "!" & strMacro
wbToRun.Save
wbToRun.Close
objApp.Quit
'Leaves an onscreen message!
MsgBox strPath & " " & strMacro & " macro and .vbs successfully completed!", vbInformation
'
`
In the Action tab (Task Scheduler):
set Program/script: = C:\Windows\System32\cscript.exe
set Add arguments (optional): = C:\MyVbsFile.vbs
Finally, don't turn on "Run whether user is logged on or not".
That should work.
Let me know!
Rod Bowen
I referred a blog by Kim for doing this and its working fine for me. See the blog
The automated execution of macro can be accomplished with the help of a VB Script file which is being invoked by Windows Task Scheduler at specified times.
Remember to replace 'YourWorkbook' with the name of the workbook you want to open and replace 'YourMacro' with the name of the macro you want to run.
See the VB Script File (just named it RunExcel.VBS):
' Create a WshShell to get the current directory
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
' Create an Excel instance
Dim myExcelWorker
Set myExcelWorker = CreateObject("Excel.Application")
' Disable Excel UI elements
myExcelWorker.DisplayAlerts = False
myExcelWorker.AskToUpdateLinks = False
myExcelWorker.AlertBeforeOverwriting = False
myExcelWorker.FeatureInstall = msoFeatureInstallNone
' Tell Excel what the current working directory is
' (otherwise it can't find the files)
Dim strSaveDefaultPath
Dim strPath
strSaveDefaultPath = myExcelWorker.DefaultFilePath
strPath = WshShell.CurrentDirectory
myExcelWorker.DefaultFilePath = strPath
' Open the Workbook specified on the command-line
Dim oWorkBook
Dim strWorkerWB
strWorkerWB = strPath & "\YourWorkbook.xls"
Set oWorkBook = myExcelWorker.Workbooks.Open(strWorkerWB)
' Build the macro name with the full path to the workbook
Dim strMacroName
strMacroName = "'" & strPath & "\YourWorkbook" & "!Sheet1.YourMacro"
on error resume next
' Run the calculation macro
myExcelWorker.Run strMacroName
if err.number <> 0 Then
' Error occurred - just close it down.
End If
err.clear
on error goto 0
oWorkBook.Save
myExcelWorker.DefaultFilePath = strSaveDefaultPath
' Clean up and shut down
Set oWorkBook = Nothing
' Don’t Quit() Excel if there are other Excel instances
' running, Quit() will shut those down also
if myExcelWorker.Workbooks.Count = 0 Then
myExcelWorker.Quit
End If
Set myExcelWorker = Nothing
Set WshShell = Nothing
You can test this VB Script from command prompt:
>> cscript.exe RunExcel.VBS
Once you have the VB Script file and workbook tested so that it does what you want, you can then use Microsoft Task Scheduler (Control Panel-> Administrative Tools--> Task Scheduler) to execute ‘cscript.exe RunExcel.vbs’ automatically for you.
Please note the path of the macro should be in correct format and inside single quotes like:
strMacroName = "'" & strPath & "\YourWorkBook.xlsm'" &
"!ModuleName.MacroName"
Code below copied from -> Here
First off, you must save your work book as a macro enabled work book. So it would need to be xlsm not an xlsx. Otherwise, excel will disable the macro's due to not being macro enabled.
Set your vbscript (C:\excel\tester.vbs). The example sub "test()" must be located in your modules on the excel document.
dim eApp
set eApp = GetObject("C:\excel\tester.xlsm")
eApp.Application.Run "tester.xlsm!test"
set eApp = nothing
Then set your Schedule, give it a name, and a username/password for offline access.
Then you have to set your actions and triggers.
Set your schedule(trigger)
Action, set your vbscript to open with Cscript.exe so that it will be executed in the background and not get hung up by any error handling that vbcript has enabled.
I found a much easier way and I hope it works for you. (using Windows 10 and Excel 2016)
Create a new module and enter the following code:
Sub auto_open()
'Macro to be run (doesn't have to be in this module, just in this workbook
End Sub
Set up a task through the Task Scheduler and set the "program to be run as" Excel (found mine at C:\Program Files (x86)\Microsoft Office\root\Office16). Then set the "Add arguments (optional): as the file path to the macro-enabled workbook. Remember that both the path to Excel and the path to the workbook should be in double quotes.
*See example from Rich, edited by Community, for an image of the windows scheduler screen.
I have been working with this issue for days. I tried multiple different ways. I am attempting to append multiple files into an Access linked table or even a temp table or even into a single excel file. At first EVERY SINGLE TIME on the first attempt the program works perfectly, then after that it stops functioning for a period of time and then starts operating again. When it stop functioning I get an Subscript out of range run-time error 9.I open the proper excel file but for some reason it won't let me set it... How can it OPEN THE FILE but in the next line CAN'T FIND IT??? It is driving me insane, it works, it stops working, then it works again... Any advice or hints would be very much appreciated.
This is just one way I tried to do this but they all end the same.
i = 2 'i is created through another loop previously.
j = 0
With MyXL
.Visible = True
.DisplayAlerts = True
End With
Do
Set MyXL = CreateObject("Excel.Application")
MyXL.Workbooks.Open Directory & fileArray(j), Notify:=False, ReadOnly:=False 'Tried True previously but changed since i was making changes to the file.
Set wb = Workbooks(fileArray(j)) 'DING DING DING!!! WHY??? You WORKED before!!!
If wb.Sheets("Sheet1").Range("A1") = "System Status" Then
wb.Sheets("Sheet1").Range("A1") = "PO System Status"
wb.Save
End If
wb.Close True
Set wb = Nothing
MyXL.Quit
Set MyXL = Nothing
Set wb = Nothing
j = j + 1
Loop Until j = i
Previously I thought I wasn't closing the workbook correctly, but I have closed the MyXL and previous wb but i still run into the error. I was wondering if this is something that Access/vba just can't do in succession as well. I changed the ReadOnly to true and it still ends up the same way.
Set your workbook to the return value from the Open method:
Set wb = MyXL.Workbooks.Open(Directory & fileArray(j), Notify:=False, ReadOnly:=False)
If wb.Sheets("Sheet1").Range("A1") = "System Status" Then
wb.Sheets("Sheet1").Range("A1") = "PO System Status"
wb.Save
End If
You don't need to/shouldn't create a new Excel application instance for every file - set that up before you enter the loop, and close it once you're done updating files. Check your Task Manager and make sure you don't have a bunch of Excel instances hanging around.
I am getting an Automation error, when Catia is trying to write values in a selected Excel sheet. It's a bit confusing because on the first try of the code there was no error and the values were in the Excel sheet.
I didn't change the code, but on the second try I get:
Run-time error '-2147417846 (8001010a)': Automation error
"The Message filter indicated that the application is busy."
on the line: Set MyXL = GetObject(FPath)
Sub CATMain()
FPath = CATIA.FileSelectionBox("Select the Excel file you wish to put the value in", "*.xlsx", CatFileSelectionModeOpen)
If FPath = "" Then
Exit Sub
End If
Set xlApp = CreateObject("Excel.Application")
Set MyXL = GetObject(, "Excel.Application")
Set MyXL = GetObject(FPath)
MyXL.Application.Visible = True
MyXL.Parent.Windows(1).Visible = True
Dim oSelection As Selection
Set oSelection = CATIA.ActiveDocument.Selection
Dim oProduct As AnyObject
On Error Resume Next
Set oProduct = oSelection.FindObject("CATIAProduct")
If (Err.Number <> 0) Then
MsgBox "No selected product"
Else
On Error GoTo 0
Dim oInertia As AnyObject
Set oInertia = oProduct.GetTechnologicalObject("Inertia")
Dim dMass As Double
dMass = oInertia.Mass
Dim dDen As Double
dDen = oInertia.Density
MsgBox oProduct.Name & ": Masse = " & CStr(dMass) & " KG" & ": Dichte = " & (CStr(dDen) / 1000) & " "
MyXL.Application.Cells(1, 1).Value = "Masse"
MyXL.Application.Cells(2, 1).Value = dMass
MyXL.Application.Cells(1, 2).Value = "Dichte"
MyXL.Application.Cells(2, 2).Value = "dDen"
MsgBox "Werte wurden in Excel eingetragen"
End If
End Sub
It appears you did not set Option Explicit - put it on the first line and it will help you avoid errors. (With it, the compiler will force you to declare all your variables. This will also mean that when you put it in, your code will not work unless you declare all variables.)
The first problem:
Set xlApp = CreateObject("Excel.Application")
Set MyXL = GetObject(, "Excel.Application")
You first create a new instance of Excel with CreateObject and store a reference to it in xlApp (which you subsequently do not use). Then you try to get a reference to an existing Excel instance with GetObject and store its reference in MyXL. This only works reliably because you first create a new instance. Otherwise you could not guarantee that there always is an Excel instance available.
A related problem is, that you don't release/close these instances. If you create an Excel instance, you need to close it with xlApp.Quit after you're done using it, otherwise it will linger around.
Be careful though with instances you took over with GetObject - calling MyXL.Quit will close the instance regardless of what other workbooks are open at that time.
Similarly, if you open a file this way, you need to make sure to close it afterwards. Otherwise you'll run into the problem you experience: Write protected files.
So, to mend your problem: Close all open instances of Excel (best done via Task Manager, as some of them might be invisible). Then adjust your code to only use one reference to an Excel.Application. And finally make sure to .Close the workbook after you've saved it and .Quit your Excel instance. This should hopefully prevent the error from reappearing.
'Dim xlApp As Excel.Application ' early-bound declaration
'Set xlApp = New Excel.Application ' early-bound assignment
Dim xlApp As Object ' late-bound declaration
Set xlApp = CreateObject("Excel.Application") ' late-bound assignment
'Dim wb As Workbook ' early-bound declaration
Dim wb as Object
Set wb = xlApp.Workbooks.Open(FPath)
' stuff you want to do with the workbook
wb.Close SaveChanges:=True
xlApp.Quit
If you can add a reference to the Excel object model in you Catia VBA project (not sure about that), you can comment out the late-bound lines and use the early-bound lines instead. That way you gain the very useful IntelliSense for the Excel objects. Which makes it so much easier to code.
Thank you guys! I've solved the Problem with simply adding the code:
Workbook.Close SaveChanges:=True