All of this is being done in VB.NET using the Excel 14.0 Interop Services
I am at my wits end. I keep getting prompts from windows and excel during the middle of a batch run.
The program i have takes in a workbook with batch records, then runs simulations on each batch record, then writes the results back out to the excel file.
The steps:
Open workbook
check to see if workbook is already in use by another program.
if it is in use. we try to close the workbook. then we wait for a set amount of time before trying again.
if the workbook is not in use we continue.
Get the contents
Mark the records as being processed
save and close the file.
process the records.
do the same process above to open the workbook.
save the results to the workbook.
close the workbook.
loop these processes until all the records have been simulated.
Ok the problems that can occur:
Workbook is already in use or two programs are trying to interact with the save workbook at the same time.
Ok now for the problem that i am having.
When the workbook is being interacted with by two programs at the same time. a prompt will show saying the file is currently in use.
another problem that happens that i can't explain is excel will show a prompt saying that the file is now ready to be modified with the options read-write, notify, cancel.
I need to find a way to handle these prompts programmatically.
If any one can point me in the right direction I would be very greatful.
You can prevent the prompts from appearing by setting:
Dim xlApp As Excel.Application = New Excel.Application
xlApp.DisplayEvents = False
But I've not found a way to actually "catch" the prompts and do something useful. I've noticed that often if Interop cannot get hold of a file then it will throw an exception. The exception rarely contains any way to distinguish what the actual error is, but you can sometimes work it out based on what could happen at that point.
Related
I have an Excel workbook macro that opens another workbook and starts copying data into it and formatting it. At one point in the process, I want the macro to pause and let the user manually enter data into the target workbook and then resume processing.
MsgBox, Application.Wait(), and Sleep are all application modal and will not let the user update anything in the other workbook while they are executing.
I found this while searching for a solution. It gets me halfway there in that I can manipulate the other sheet but only with my mouse. No keyboard presses get sent to the workbook.
Any ideas on getting all the way there?
I was thinking that I could just have two macros. The user would run one, then perform his manual tasks, then run the other. This appears to work but I would have to convert everything to globals so hopefully, someone has a better idea.
Thanks!
Depending on the macro being run to copy and paste, is the main concern with user intervention during execution of the macro getting the active cell/sheet (if being used) back to being active after the user manipulates something.
I'd recommend storing the active cell/sheet address in a variable prior to the Application.Wait() and then setting the active cell to that stored value on resume.
Without a posting of what your macro is doing though, it is hard to know if this suggestion helps your current situation.
Huge problem here. I sent an excel form (a workbook with several sheets, thousands of active x controls and many many macros) to several people that they need to fill and return to me. Only one of the completed form I received is now completely impossible to use. All active X controls have changed name. If I select one I see the old name, but if I click on it the macro doesn't start and if I try to see its code it opens a new empty Macro with the new control name_click (Ex: a button called cmd_button1 opens a Macro called cmd_button2_click). When I start the Macro in VBA, I get the Run-time Error '32809' every time the code wants to unprotect sheets or to change the visible value of a sheet.
I looked on other posts and every solution I found would require a huge amount of work. What happened? Is there an easy solution to this?
Thank you.
I saved the workbook in .xlsx and copy/pasted all my macros back, transfered the forms and modules back then saved it back to .xlsm and now the buttons call the macros and no run time errors occur anymore.
I've written an Excel addin that periodically checks a remote repository for data updates, including a check when the addin loads at Excel start up (during the addin's Workbook_Open event). If new respository data is detected, the addin asks the user for permission to proceed with the update. If the user clicks "yes", the addin successfully updates itself and everything is happy... except...
If Excel is not already running and the user selects an Excel file to open (e.g. via double-click in Windows), this sequence of events occurs and everything works, but the user-requested file opening is interrupted and not re-engaged. The Excel app is running, but with no workbook loaded (the workbook area is an empty frame).
I believe I have two options, neither of which I know how to accomplish:
Prevent the addin from completing its update check until the user-selected file has completed its open sequence and is fully loaded, or
Allow the addin to update itself and then somehow re-engage the user-selected file to complete the file open/load.
I have not been able to discover the filename/path of the user-requested file, so my addin isn't able to direct that file to be loaded.
My current workaround is a MsgBox telling the user to close Excel and re-open the selected file. Ideally, the addin update should occur and the original action should complete without requiring user intervention.
(Building on Option 1, I could start a delay timer for the addin to check for updates XX number of seconds after Excel starts, but this seems kludgy to me.)
Any guidance or ideas are appreciated. My interwebz searches aren't hitting the right combination of keywords for the exact scenario.
Instead of opening the new addin update file immediately you can use OnTime to delay it which should allow the other file to open successfully. See here: Process for updating Excel add-in?
In the answer you'll also see a reference to this package here which does everything you need. Autoupdates are hard so I would recommend going with someone else's solution.
http://www.decisionmodels.com/downloads.htm#addload
(Scroll down to Add-In Loader Version 2)
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)!
Is there a way to have an Excel macro to check what file I double clicked on to open.
When I open that file, the Add-Ins installed load first, then the file I clicked on loads. How can I write code inside one of my Add-Ins to check what the filename is that I am trying to open?
I tackled this by using 2 instances of Workbook_Open inside an excel Addin.
When a file is loaded, the addin starts up, and checks to see if there are any active workbooks. If there is none, then we wait a little bit and check again, looped as many times as you deem necessary, or until there is a valid workbook open. This makes sure your computer has time to load up the excel file. Once there is an active workbook, we process it to make sure it is not the workbook of the addin. If it is, then we exit our code. If it isn't then we Do Stuff.
I solved 2 of my questions on this site with the same code that can be found HERE
Note: I left out the parts where I Do Stuff... because really it's there to do anything you want with it. The code in the link just does what the previous paragraph describes.