plugin error missing when opening excel file with VB script - excel

I try to write a piece of code with VB script to open an excel file, take a print screen and send it by email.
This is on my professional laptop and I have several plugin installed on excel.
The excel file in question has a macro inside which run on each opening but does nothing fancy (mostly formatting data).
When I open the workbook normally, everything works fine.
When I launch the VB script, I have a error with a missing xla file (refer to file attached)
The code is quite simple:
Dim Xl 'as Excel.Application\par
Dim wk 'as Excel.workbook\par
set Xl = createobject("Excel.application")
Xl.Visible = True
Xl.enableevents = True
set Wk = Xl.workbooks.open("XXX")

Try to open workbook via shell:
Option Explicit
Dim oExcelApp, oWorkbook
CreateObject("Shell.Application").ShellExecute "C:\Test\Test.xlsm"
Do
On Error Resume Next
Set oExcelApp = GetObject(, "Excel.Application")
WScript.Sleep 5
Loop While Err
On Error Goto 0
Set oWorkbook = oExcelApp.Workbooks("Test.xlsm")
oWorkbook.Sheets(1).Cells(1, 1).Value = Now()

Related

VBA does not suppress save option prompt for online files

I'm using Access VBA to auto update a shared Excel file - create XL object, open the shared file by sharepoint path, make necessary updates and close the file. In the codes, the displayalerts is set to False
Most of the time it works ok, but occasionally upon closing the file, it gives this prompt, even if the displayalerts is set to false.
When this happens, how do I auto select "Discard my change" by vba code?
Here's the code:
Dim XL As Excel.Application
Dim wkb As Excel.Workbook
Set XL = CreateObject("Excel.Application")
XL.Visible = False
XL.DisplayAlerts = False
Set wkb = XL.Workbooks.Open(SharePointFilePath)
'do stuff
wkb.Save
wkb.Close
XL.Quit
Set XL = Nothing

Edit a workbook, whether open or closed, from Word VBA

I am trying to write a macro in Word so that I can save some information into an Excel file somewhere else in my computer. For this reason I wrote this:
Dim exlApp As Object
Dim exlWbk As Object
Set exlApp = CreateObject("Excel.Application")
Set exlWbk = exlApp.Workbooks.Open(FileName:="D:\database.xlsx")
exlWbk.ActiveSheet.Cells(1, 1).Value = "some info"
exlWbk.Close SaveChanges:=True
Set exlWbk = Nothing
exlApp.Quit
Set exlApp = Nothing
The code works perfectly fine for me, except when the Excel file in question (database.xlsx) is already opened by the user. In that case, running the macro will prompt me to save the new changes into a new copy of my excel file, which is not what I want. I want the new changes to be included in the current Excel file without creating a second copy of it.
Since the above code presented some problems, I wrote this:
Dim exlApp As Object
Dim exlWbk As Object
Set exlApp = CreateObject("Excel.Application")
Set exlWbk = exlApp.GetObject("D:\database.xlsx")
exlWbk.ActiveSheet.Cells(1, 1).Value = "some info"
exlWbk.Save
Set exlWbk = Nothing
exlApp.Quit
Set exlApp = Nothing
But nothing changed. I know there are some ways to figure out whether my Excel file is open or not, but the problem is that I don't know how to change my code if I find out that file is open.
How can I determine whether a workbook is open in Excel so that it can be edited, or open the file in order to edit it if it's closed?
According to the documentation, GetObject(filename) will pick up the existing file if it's already open or, optionally, open the file if it is not open:
When this code is executed, the application associated with the
specified pathname is started, and the object in the specified file is
activated.
If Excel is not running, by default nothing will be visible when GetObject(filename) executes. Excel will be opened, the file will be opened and changed. There's a real danger, therefore, that the instance of Excel and the workbook will "hang" in memory, which could be seen in the Windows "Task Manager". Repeated running of such code can eventually crash Windows, so care must be taken to clean things up correctly on each iteration.
Since the question also stipulates that the file could be opened already by a user, it's necessary to determine that, as well as whether the Excel application is already running.
The following code sample demonstrates how this can be done. The assumption is that neither the applicaton nor the file is open. Then it tests whether Excel is already running.
Set xlApp = GetObject(, "Excel.Application")
Notice the difference in the syntax: instead of the fileName there's a comma, followed by the name of the application. This will check whether the application is available; if it's not, an error will be triggered. Therefore, On Error Resume Next precedes GetObject, which means the error will be ignored.
Since ignoring errors is dangerous, the next line Or Error GoTo 0 turns errors back on.
If GetObject is not successful, the variable xlApp could not be instantiated and its "value" is Nothing. If Not xlApp Is Nothing executes if xlApp could be instantiated and the Boolean appAlreadyOpen is set to true so that we know to not quit Excel when the code finishes. It also checks whether the required workbook is already open. If it is, xlWb can be instantiated and fileAlreadyOpened set to true.
If xlWb could not be instantiated, either because the Excel application was not running or the workbook was not yet open, GetObject(fileName) is executed. The workbook will be opened, in the existing instance of Excel if already running or in a new instance of Excel. At the end of this code block two lines are commented: should the newly started Excel application be made visible and remain open when the code ends, uncomment them.
The workbook can then be edited.
Lastly, things need to be cleaned up. The Booleans are checked and if not true, the workbook and possibly the application are closed. Very important are the last two lines that release these objects from memory. If the code creates any other objects, such as Ranges, these should also be released, in the reverse order they are instantiated.
Sub GetFileOpenedOrClosed()
Dim xlApp As Object ' Excel.Application
Dim xlWB As Object, wb As Object ' Excel.Workbook
Dim fileName As String
Dim fileAlreadyOpen As Boolean, appAlreadyOpen As Boolean
fileName = "C:\Test\SampleChart.xlsx"
fileAlreadyOpen = False
appAlreadyOpen = False
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
On Error GoTo 0
If Not xlApp Is Nothing Then
appAlreadyOpen = True
For Each wb In xlApp.Workbooks
If wb.FullName = fileName Then
Set xlWB = wb
fileAlreadyOpen = True
Exit For
End If
Next
End If
If xlWB Is Nothing Then
Set xlWB = GetObject(fileName)
Set xlApp = xlWB.Application
xlWB.Windows(1).Visible = True 'So that the window is not hidden when file is opened again
'xlApp.Visible = True
'xlApp.UserControl = True
End If
xlWB.Worksheets(1).Cells(7, 1).value = "some other info"
If Not fileAlreadyOpen Then
xlWB.Save
xlWB.Close
End If
If Not appAlreadyOpen Then
xlApp.Quit
End If
Set xlWB = Nothing
Set xlApp = Nothing
End Sub

Why do I get this error every few iterations? 'ActiveX Component Can't Create Object'

I am running a program where I have to open .xls files in a folder one by one and get information from them. At the beginning of my function I run this code below for each .xls file I want to open.
However, every once in a while, I get this error on the fourth line of code: 'ActiveX Component Can't Create Object'.
After clicking debug on the error window, I am able to just click continue and the code starts running fine. It opens the file and gets the info I want.
Why does this error come up? I don't want to keep clicking to progress this process.
Thanks in advance.
Function getPerfumeName(file)
Dim XL As Excel.Application
Dim WBK As Excel.Workbook
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(file)
phrase = Split(WBK.Sheets(1).Cells(3, 1).Value, ":")
If phrase(0) = "PERFUME GCAS" Then
getPerfumeName = phrase(UBound(phrase))
Else
getPerfumeName = ""
End If
WBK.Close
Set XL = Nothing
End Function
I run this code below for each .xls file I want to open.
Maybe becuase you are creating too many of them? Outside the loop, use that only once and then inside the loop use Set WBK = XL.Workbooks.Open(file) to open the file and then close the file before the loop ends... Also since you ar eusing Early Binding, you may use Dim XL As New Excel.Application once outside the loop and it will work. No need to use both the lines...
Sub Sample()
Dim XL As New Excel.Application
Dim WBK As Excel.Workbook
For i = 1 To whatever
Set WBK = XL.Workbooks.Open(file)
'
'~~> Do Something
'
WBK.Close (False) 'or WBK.Close(True)
Set WBK = Nothing
Next i
XL.Quit
Set XL = Nothing
End Sub

VBA to get open Excel Binary Workbook

I have an MS Access form that opens an Excel binary file (.xlsb) from another website. I am trying to check all the user's open Excel files so that I work on the correct workbook.
By running the loop below on the opened, but not saved Excel file, the GetObject does not find the just opened workbook. This code does find other Excel files that I might already have open.
But, if I save the Excel file that I opened from the network, close and reopen it before I try to find the open Excel files with the code below, the code finds that file too.
Is there a better way for me to capture the just-opened file name? On the new Excel file, I need to filter data from particular Excel tabs and add that data to Access tables.
Dim xlApp As Excel.Application
Dim strWBList As String
strWBList = ""
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err.Number = 0 Then
Dim xlWB As Excel.Workbook
For Each xlWB in xlApp.Workbooks
If Len(strWBList) > 0 Then
strWBList = strWBList & ","
End If
strWBList = strWBList & xlWB.Name
Next xlWB
Set xlApp = Nothing
Set xlWB = Nothing
End If
MsgBox strWBList

VBScript code to keep Excel file open

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

Resources