I'm running into an instance error when trying to run 2 VBO Excel macros in a process.
My process is as follows (please note I'm running 2 macros back to back): Create Instance - Open Workbook - Activate Worksheet - Run Macro - Create Instance - Open Workbook - Activate Worksheet - Run Macro
Error Received for the second pass:
Workbook Not Found : Workbook named: Select Clients.xls not found in instance: 0
Any thoughts?
The reason you're seeing this error is due to the way Excel "instances" are logically laid out when launched by Blue Prism. TL;DR: Don't use the Create Instance action more than once, instead open all your workbooks in the same instance.
When creating an Excel instance, Blue Prism assigns a numeric handle variable to that instance. Using that handle, you'll only be able to access workbooks created in that instance. Logically, each instance would have it's own separate workbooks, worksheets, etc.:
Because Create Instance creates a completely separate instance of Excel, you won't be able to access workbooks created within the first instance. Instead of spamming Create Instance, use Open Workbook and pass in the same handle you were originally assigned. From there, you'll be able to access whatever you've opened previously.
Related
I would like a global solution every time I start Excel365 with my key add-in also firing up.
I defined several LAMBDA custom functions, saved them in my add-in, and I would like to make them available globally - not just only for the current workbook. Is it possible? I tried saving a workbook with definition as an add-in (.xlam) but the formulas are not available. The don't seem to be available when as an add-in. When I am in the add-in parent file on the desktop, all is good and everything is running. But once I post the file back for your as an add-in, The Lambda(s) and the defined name space go away.
You might try creating a template for excel to load when it is opened.
Customizing how Excel starts so it utilized the template.
My additional work around is also simple. If the LAMBDAs were saved in the original Workbook with "Workbook" as the saved parameter. Then each of those worksheets in the original LAMBDA workbook is "infected" with all of the workbook LAMBDAs. Therefore, I simply copy a blank worksheet from the original Workbook to the "new" workbook. Then by virtue of "infection" the new workbook is also newly infected with all of the new LAMBDAs. It works just like COVID, who knew?
I previously created a VBA program that launched the form from a command button. Sheet 1 was the command button and Sheet 2 was the data that the program referenced. I want to put the data into a separate workbook so that I can put it in a shared drive that can be run on other machines, as well as giving me the option to update the data in the workbook (all separate from the original program). I also think this would make the program faster and much more lightweight, so it doesn't have to open up all the data in Sheet 2 along with it. How could I open the data workbook in the background and be able to reference it in my code?
I have made a Visual Basic program in Visual Studio (NOT VBA) that creates an instance of Excel and uses it throughout the program to open existing/create Workbooks. The problem I'm encountering is that any time after the instance of Excel is created, I am unable to completely open a workbook normally (from within windows explorer). I say 'completely' because Excel DOES appear open, but the menus and workbook itself don't actually populate. The Excel border just sits there and the busy cursor is shown when I hover over it.
Once the VB program is closed and that object is released, Excel returns to 'normal' functionality. Additionally, when I quit the VB program, the partially opened workbook also goes closes, almost as though it was attached to the instance of Excel I created in code.
The instance of excel created should be totally silent and the user should never even know it's being used. To that end, I'd like the user to be able to open other workbooks as though Excel isn't already being used elsewhere. This is important because other Excel workbooks might need to be opened for reference by the user during runtime.
I declare the object this way because there are many sub routines in various modules that all might want to use the instance of Excel.
Public Shared XLapp As New Excel.Application
The following code runs when the first form opens in the applicaion. Once this bit runs and the XLapp object gets set to a new Excel.Application, I lose the ability to open a workbook normally, as described above.
If IsNothing(XLapp) Then XLapp = New Excel.Application
XLapp.Visible = False
XLapp.DisplayAlerts = False
XLapp.EnableEvents = False
XLapp.ScreenUpdating = False
After creating a workbook object, I'll later in the code, and in various places throughout, open a workbook typically as below:
Dim OpenedWorkbook as Excel.Workbook = Nothing
[...]
OpenedWorkbook = XLapp.Workbooks.Open(workbook_filepath)
I've always been under the impression that if I'm opening workbooks using this particular object (XLapp) that when a workbook is opened in windows explorer that a new instance of Excel would be created. That is to say, the instance of Excel my program creates should be isolated from other instances of Excel, but that doesn't seem to be the case here.
Is there something else I need to do (or have I done something wrong?) to allow the user to use Excel normally while my program is running?
Thanks in advance for the help and for having patience with this VB newbie!
(Sorry, too long for a comment.)
You might be using the wrong tool for the job. You write:
The instance of excel created should be totally silent and the user should never even know it's being used. To that end, I'd like the user to be able to open other workbooks as though Excel isn't already being used elsewhere.
The purpose of Excel interop is to remote-control Excel, just like a user would interact with it. However, users don't interact with silent, non-visible Excel windows. It's just not what Excel interop is made for.
I suspect that you don't really want to remote-control a locally installed Excel instance. What you really want to do is to open and manipulate Excel workbooks. Then do just that: Use one of the Excel libraries for .NET and modify the Excel files directly (personally, I like SpreadsheetLight, but others are fine as well). Additional bonus: Your users don't need to have Excel installed.
You should refer to this post ... How do I properly clean up Excel interop objects?
Basically, when you create the Excel object, and don't dispose of it correctly, it hangs around sucking up legitimate Excel file open requests but not acting on them!
Fixing this type of error is time consuming, because the worksheet/cell/etc references all need to be disposed of correctly.
Furthermore, if you use more than one '.' in an instruction (eg Parent.Child.GrandChild) then you are in even more trouble since you create a reference to Child, but don't store it anywhere, and thus can't dispose of it!
As #Heinzi mentions, you could well fare better by using a different library rather than Excel interop if all you are doing is reading/writing values. I've used EPPlus with no issues so far (add via Nuget)!
I am currently trying to create an export tool to push data into Excel. However after the first push, Excel is left open, and sometimes a user may want to leave Excel open while they push more data to another page in the same excel sheet. I usually just release the COM objects once the export is done. The way my methods work right now involves opening a new instance of excel every time I export...
would it be beneficial to create a global instance of the application to use continuiously from the point I begin exporting until the point of the Excel application being closed?
Should I be using event handlers to detect when Excel has been closed so I know when to release the COM objects?
If I do try to make a global instance of an Excel Application, I can instantiate it and wait to release it, that way I don't need to try and find open instances of excel again.. but if I needed to find, and assign to a variable, an open instance of Excel (that has previously existed in code but had the COM objects released), how would I do this?
I have used this in the past. tPath is the path to my excel file that should be opened/reused.
Dim exApp As New Excel.Application
'finds the workbook. If it is already open, then it uses that. Otherwise, it opens in new instance
Dim wb As Excel.Workbook
wb = System.Runtime.InteropServices.Marshal.BindToMoniker(tPath)
exApp = wb.Parent
You can use the Interop Library to point to the open excel-app
(This code is written in C# so there could be some minor change for VB.Net)
oExcel = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
I have a complex project in `Microsoft Office Excel 2007' which utilises a large number of UDFs. Through VBA in a Workbook_Open Event, I set Excel Automatic calculation to OFF and a strategically placed Calculate method to manually calculate the cells whenever I need it so that the UDF doesn't perform recalculation unintentionally.
If the workbook is the ONLY one opened (or the first to open) in an Excel instance, everything works perfect. Only when it's opened AFTER another workbook (within the same instance), my project will inherit the Automatic calculation setting from the FIRST workbook and perform endless calculation on my UDFs. The disable code placed in the Workbook_Open event isn't executed until the UDF finishes the calculation (which can take forever). This only happens if my project is NOT the one opened first.
Through http://www.decisionmodels.com/calcsecretse.htm, I discover that it is the nature of Excel to perform the calculation process BEFORE the Workbook_Open event is executed.
So the question I have obviously relates to the project being opened AFTER another workbook is opened with automatic calculation turned ON:
How do I force my project to disable automatic calculation
without it performing recalculation first (remember, problem only
occurs when the project not the first one to be opened since it will
follow settings from previously opened workbook) OR...
How do I get the project to open in ANOTHER INSTANCE (when double clicked) to avoid
inheriting automatic calculation setting from the previous workbook.
Either way, the answer I'm seeking is for the project to open without performing the calculation first.
Thanks
One way is to use a different workbook (Opener.xls) to initiate opening the UDF workbook (udf.xls)
in Opener.xls the Workbook_Open code
- sets calculation to manual
- opens udf.xls
In your question I don't recognize the way you use to change and inherit that option to your workbooks, But I answer it as a solution:
Use VBA and running VBA macros to change that option for just your active sheet as soon as you need to calculate; by using it like this:
With ActiveSheet
.EnableCalculation = False
.EnableCalculation = True
.Calculate
End With
In another ways that may you need, you can read this part of MSDN article.