I use dos .bat file to run a .vbs file continuously ... If any error occurs the batch file runs the vbscript again and it goes on. The script connects via internet to a site to execute some api calls.
Now when there is connection problem or any other error then the control comes out of the script keeping the excel file open. This way many excel files gets open on each error ... The code is as follows ... please advice me how to close the excel file on error and then come out of the script gracefully.
'{{{{Some coding}}}}
dim objExcel, objWorkbook, objRange
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\temp.xlsx")
objExcel.Visible = True
'{{{{Some coding}}}}
objExcel.Cells(xlrow, 3).Value="Test"
objExcel.Cells(xlrow, 3).Select
objExcel.Activecell.Show
'{{{{Some coding}}}}
objExcel.Workbooks(1).save
objExcel.Workbooks(1).close
objExcel.Quit
Set objExcel = Nothing
Set objWorkbook = Nothing
WScript.Quit
Thanks in advance
One possible approach is to wrap the Excel handling in a custom class:
Class Excel
Private xl
Private Sub Class_Initialize
Set xl = CreateObject("Excel.Application")
End Sub
Private Sub Class_Terminate
For Each wb In xl.Workbooks
wb.Saved = True 'discard unsaved changes
wb.Close 'close workbook
Next
xl.Quit 'quit Excel
End Sub
Public Function OpenWorkbook(filename)
Set OpenWorkbook = xl.Workbooks.Open(filename)
End Function
Public Function NewWorkbook
Set NewWorkbook = xl.Workbooks.Add
End Function
Public Property Get Workbooks
Set Workbooks = xl.Workbooks
End Property
End Class
The procedure Class_Terminate is automatically called whenever a class instance is destroyed. That way you can automatically close the open workbooks and quit Excel.
The class can be used like this:
Set xl = New Excel
Set wb = xl.OpenWorkbook("C:\path\to\your.xlsx")
...
wb.Close
Related
I'm having an VB6 application that opens an excel macro enabled file using workbooks.open method. Inside this file, there is an userform that gonna be automatically opened when the file is opened. The problem is the workbooks.open method in vb6 application keeps running and does not jump to next line even when I close my userform (I do have codes to close workbook, quit excel app when the userform is closed). I can only close the interface of my userform but Excel still running in background. As long as I dont close the Excel app in task manager, my vb6 does not terminate excel process and of course it will not jump to next line either.
Here is my code in vb6 to open excel file that contains the userform above
As I said, workbooks.open method works but it does not terminate and keeps the excel app runnning in background
P/s: don't mind the Japanese characters
Private Sub Form_Load()
Dim xlapp
Dim xlwkb
If Not App.PrevInstance Then
Set xlapp = CreateObject("excel.application")
Me.Hide
On Error Resume Next
Set xlwkb = xlapp.workbooks.open("C:\Users\david\Desktop\sale-system\fixedfile.xlsm", Readonly:= True)
Set xlwkb = Nothing
If Not xlapp Is Nothing Then
xlapp.Visible = True
xlapp.Application.quit
Set xlapp = Nothing
End If
Unload Me
Else
MsgBox "プログラムが既に起動されています!", vbInformation, "売上管理システム"
Unload Me
End If
End Sub
Here is my code in excel file when close the userform
Application.DisplayAlerts = False
ThisWorkbook.Close False
Application.Visible = True
Application.Quit
End
I really need to solve this problem in this week, any solution?
Thank you guys in advance and please pardon for my english
Here is some images. I hope they will help you guys to understand my problem
This happens when I use Thisworkbook.close False statement:
This happens when I dont use Thisworkbook.close False statement:
Inside this file, there is an userform that gonna be automatically opened when the file is opened.
when I close my userform (I do have codes to close workbook, quit excel app when the userform is closed).
You are doing this incorrectly. Do not close/quit it from the UserForm. Do it from VB6 form. This way, vb6 will be able to handle and clear the objects.
Here, try this (I already tried it and it works...). This will not leave an instance of Excel running. I have commented the code. But if you still have questions then simply ask.
Note: Before you try this (Just for testing purpose), close all Excel application. Even from the task manager.
Private Sub Form_Load()
Dim oXLApp As Object
Dim oXLWb As Object
Dim ICreateatedExcel As Boolean
'~~> Establish an EXCEL application object
On Error Resume Next
Set oXLApp = GetObject(, "Excel.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then
Set oXLApp = CreateObject("Excel.Application")
'~~> I created instance of Excel
ICreateatedExcel = True
End If
Err.Clear
On Error GoTo 0
'~~> Check if you have an instance of Excel
If oXLApp Is Nothing Then
MsgBox "Unable to get an instance of Excel.", vbCritical, "Excel is Installed?"
Exit Sub
End If
Me.Hide
'~~> Show Excel
oXLApp.Visible = True
'~~> Open file
Set oXLWb = oXLApp.Workbooks.Open("C:\Tester.xlsm")
'~~> This and other lines below will not run till the
'~~> time you close the userform in Excel
'~~> Close the workbook
oXLWb.Close (False) '<~~ Set this to True if you want to save changes
Set oXLWb = Nothing
'~~> If I created Excel then quit
If ICreateatedExcel = True Then oXLApp.Quit
Set oXLApp = Nothing
Unload Me
End Sub
I have a macro in one XLSM workbook's module that refreshes all the external data, then saves and closes that workbook.
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.Quit
I use a VBScript file to run that macro as part of a scheduled task
objExcel.Workbooks.Open(fname)
objExcel.Visible = True
On error resume next
objExcel.Run "RefreshAllData"
Question: How can I reuse the existing macro in the existing workbook to refresh all the data of multiple other workbooks? (ie. I'm looking for the necessary modifications to the VBScript file, I want to minimise changes to the macro itself. The filenames will be contained in the VBScript file) TIA.
I'd recommend against re-using a trivial macro like that. Instead incorporate the refresh functionality in the VBScript:
Set fso = CreateObject("Scripting.FileSystemObject")
Set xl = CreateObject("Excel.Application")
xl.Visible = True
For Each f In fso.GetFolder("C:\some\folder").Files
If LCase(fso.GetExtensionName(f.Name)) = "xlsx" Then
Set wb = xl.Workbooks.Open(f.Path)
wb.RefreshAll
wb.Save
wb.Close
End If
Next
xl.Quit
I suppose you can do something like this.
Find all the excel file in the given folder
Select Each Excel file and activate
call refreshdata function
code snippet to support this
Sub RefreshAllExcelInFolder()
Dim fso
Dim ObjFolder
Dim ObjFiles
Dim ObjFile
Dim objExcel
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
'Getting the Folder Object
Set ObjFolder = fso.GetFolder("<<C:folder path>>")
'Getting the list of Files
Set ObjFiles = ObjFolder.Files
'On Error Resume Next
For Each ObjFile In ObjFiles
If LCase(Right(ObjFile.Name, 5)) = ".xlsx" Or LCase(Right(ObjFile.Name, 4)) = ".xls" Then
Workbooks.Open(ObjFile).Activate
RefreshAllData
End If
Next
End Sub
Sub RefreshAllData()
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.Close
MsgBox ("Going back In")
End Sub
Hope this will help
If you don't change the macro at all you will have to keep reloading excel, then open the macro workbook followed by the target workbook and then run the macro. If you can remove:
Application.quit
then you can at least keep excel open and just keep opening target workbooks before running the macro each time. Seems to me it'd be simpler to put the macro code into the vbs file though
I have a macro in one XLSM workbook's module that refreshes all the external data, then saves and closes that workbook.
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.Quit
I use a VBScript file to run that macro as part of a scheduled task
objExcel.Workbooks.Open(fname)
objExcel.Visible = True
On error resume next
objExcel.Run "RefreshAllData"
Question: How can I reuse the existing macro in the existing workbook to refresh all the data of multiple other workbooks? (ie. I'm looking for the necessary modifications to the VBScript file, I want to minimise changes to the macro itself. The filenames will be contained in the VBScript file) TIA.
I'd recommend against re-using a trivial macro like that. Instead incorporate the refresh functionality in the VBScript:
Set fso = CreateObject("Scripting.FileSystemObject")
Set xl = CreateObject("Excel.Application")
xl.Visible = True
For Each f In fso.GetFolder("C:\some\folder").Files
If LCase(fso.GetExtensionName(f.Name)) = "xlsx" Then
Set wb = xl.Workbooks.Open(f.Path)
wb.RefreshAll
wb.Save
wb.Close
End If
Next
xl.Quit
I suppose you can do something like this.
Find all the excel file in the given folder
Select Each Excel file and activate
call refreshdata function
code snippet to support this
Sub RefreshAllExcelInFolder()
Dim fso
Dim ObjFolder
Dim ObjFiles
Dim ObjFile
Dim objExcel
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
'Getting the Folder Object
Set ObjFolder = fso.GetFolder("<<C:folder path>>")
'Getting the list of Files
Set ObjFiles = ObjFolder.Files
'On Error Resume Next
For Each ObjFile In ObjFiles
If LCase(Right(ObjFile.Name, 5)) = ".xlsx" Or LCase(Right(ObjFile.Name, 4)) = ".xls" Then
Workbooks.Open(ObjFile).Activate
RefreshAllData
End If
Next
End Sub
Sub RefreshAllData()
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.Close
MsgBox ("Going back In")
End Sub
Hope this will help
If you don't change the macro at all you will have to keep reloading excel, then open the macro workbook followed by the target workbook and then run the macro. If you can remove:
Application.quit
then you can at least keep excel open and just keep opening target workbooks before running the macro each time. Seems to me it'd be simpler to put the macro code into the vbs file though
I have a macro in one XLSM workbook's module that refreshes all the external data, then saves and closes that workbook.
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.Quit
I use a VBScript file to run that macro as part of a scheduled task
objExcel.Workbooks.Open(fname)
objExcel.Visible = True
On error resume next
objExcel.Run "RefreshAllData"
Question: How can I reuse the existing macro in the existing workbook to refresh all the data of multiple other workbooks? (ie. I'm looking for the necessary modifications to the VBScript file, I want to minimise changes to the macro itself. The filenames will be contained in the VBScript file) TIA.
I'd recommend against re-using a trivial macro like that. Instead incorporate the refresh functionality in the VBScript:
Set fso = CreateObject("Scripting.FileSystemObject")
Set xl = CreateObject("Excel.Application")
xl.Visible = True
For Each f In fso.GetFolder("C:\some\folder").Files
If LCase(fso.GetExtensionName(f.Name)) = "xlsx" Then
Set wb = xl.Workbooks.Open(f.Path)
wb.RefreshAll
wb.Save
wb.Close
End If
Next
xl.Quit
I suppose you can do something like this.
Find all the excel file in the given folder
Select Each Excel file and activate
call refreshdata function
code snippet to support this
Sub RefreshAllExcelInFolder()
Dim fso
Dim ObjFolder
Dim ObjFiles
Dim ObjFile
Dim objExcel
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
'Getting the Folder Object
Set ObjFolder = fso.GetFolder("<<C:folder path>>")
'Getting the list of Files
Set ObjFiles = ObjFolder.Files
'On Error Resume Next
For Each ObjFile In ObjFiles
If LCase(Right(ObjFile.Name, 5)) = ".xlsx" Or LCase(Right(ObjFile.Name, 4)) = ".xls" Then
Workbooks.Open(ObjFile).Activate
RefreshAllData
End If
Next
End Sub
Sub RefreshAllData()
ActiveWorkbook.RefreshAll
ActiveWorkbook.Save
ActiveWorkbook.Close
MsgBox ("Going back In")
End Sub
Hope this will help
If you don't change the macro at all you will have to keep reloading excel, then open the macro workbook followed by the target workbook and then run the macro. If you can remove:
Application.quit
then you can at least keep excel open and just keep opening target workbooks before running the macro each time. Seems to me it'd be simpler to put the macro code into the vbs file though
I have a VBScript code to open an excel file, run a macro and close it. Fine.
Now, the only thing I want to change is to leave the file open.
If I remove the 2 lines of code xlApp.activewindow.close and xlApp.Quit, then the workbook and the application are closed anyway, but they remain open in the background (Excel process still active in Task Manager). Hence, it is impossible to re-run the macro later on the same file by calling the script again (which is exactly what I want to do).
Why?
Here is the code:
Option Explicit
On Error Resume Next
MyTest
Sub MyTest()
Dim xlApp
Dim xlBook
Dim fpath
Dim fname
' Excel application running? if not, open Excel
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If xlApp <> "Microsoft Excel" Then
Set xlApp = CreateObject("Excel.Application")
End If
Err.Clear
' correct Excel file open? if not, open it
fpath = "D:\Desktop\"
fname = "MyTest.xls"
xlApp.Workbooks(fname).Activate
If Err = 0 Then
' no error, so it has been possible to activate the workbook
Set xlBook = xlApp.Workbooks(fname)
Else
' unable to activate, so workbook was not open -> open it now
Set xlBook = xlApp.Workbooks.Open(fpath & fname, 0, True)
End If
Err.Clear
' now run the desired macro in the excel file
xlApp.Run "HelloWorld"
' WANT TO CHANGE THIS
xlBook.saved = True
xlApp.activewindow.close
' AND THIS
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
You just need to make your new instance of Excel visible. Do this right after creating it:
xlApp.Visible = True
This line of code will close your current activated workbook (by now, it is D:\Destop\MyTest.xls);
xlApp.activewindow.close
This line will quit Excel application;
xlApp.Quit