Excel AddIn - Keeping windows form always visible while w/in Excel - vb.net

First of all, thank you for your time and assistance in reviewing this!...
I'm trying to upgrade an Excel VBA workbook to a VSTO Excel Add-in in VB.NET using VS 2010. In the original (i.e.- VBA) version I have a modeless UserForm (called frmMain) that floats on top and is visible at all times while the user is still within the Excel application, but is not visible if the user moves to another window outside of Excel.
For example, within Excel the user can click on any worksheet tab, select any cell, etc. and the UserForm is still visible. This is exactly how I'd like it.
The problem is, that in the new VSTO add-in, I can not get the Windows form to mimic this same behavior.
I use frmMain.Show() to show the form as a modeless form, but the moment the user clicks an Excel worksheet (i.e.- activates a worksheet) the form becomes hidden behind the worksheet.
I can manually Alt-Tab to bring the form back into view, but I need it to always remain in view - floating on top of the Excel worksheets so long as the user hasn't left the Excel application.
I tried various things, including setting the form to TopMost, however, that causes the form to be TopMost everywhere - including outside of Excel. Worse than that, if the user does anything that would normally result in Excel's launching a dialog box (e.g.- closing an open workbook, raising the alert "Do you want to save the changes...") the alert dialog box itself is hidden and inaccessible behind the frmMain form (since the frmMain is TopMost).
How can I get my form to behave in the desired way (i.e.- the same way it did in VBA)?
Thanks!!!
Rob

You should take a look at Custom Task Panes which can be docked or floated within the Excel application. You could also look into the COM interfaces for a lower level connection (see related SO Post) - although Task Panes are really what this type of behavior was intended for.

This method might work (worked for me):
Create a worksheet_selectionChange event handler inside your form class
Put these lines in this event handler:
Dim FormHandle As IntPtr = Me.Handle
Me.Visible = False
Me.Show(NativeWindow.FromHandle(FormHandle))

Related

How do I make a userform appear on demand in Microsoft Word?

I can make it popup on opening the document, but what if I close the userform and want to it to show up again in the same document? I know in excel you can add a button onto a worksheet directly and make it show the userform on click, but this button is unavailable for microsoft Word. Is there a solution besides initiating the script by hand?
To display a VBA userform, you can trigger it from a macrobutton field, from a form field, from a shape, from a QAT button or from an ActiveX button. There are probably a couple of other methods I'm not remembering at the moment. Each is a little different in the exact steps, but all will run the command:
UserFormName.Show

Close form on "lose focus" in VBA?

I have a VBA application that shows a form with controls on it.
I'm trying to find a way to close the form if the user clicks anywhere outside of it.
My VBA application is not in Excel, so I can't use Worksheet.SelectionChange Event
I found a brilliant solution to this dilemma here:
https://sites.google.com/site/msaccesscode/forms-1/howtoclosepopupnonmodalformwhenitlosesfocus
This method uses the pop-up form's Timer event to keep checking whether the pop-up form is the active form. If so, the form stays open. If not, it closes.

Prevent excel from closing when closing userform

I hope you can help me with this issue, I couldn't find any answer nor on google nor here. So here's the point:
I have to userforms. One of them opens on Worksheet_Open. In the Background I can still see the worksheet and the excel application. But when I click outside of the userform or close it, the application window disapears too. But in the open processes I can still see excel open.
My intention is to have the Excel window always open (in the background) so that when I close the UserForm the Excel Tables will be visible.
What do I have to code for that? To hide the userform didn't work for me...
Thanks in advance.
Hi there if you want to use both excel and your Userform at the same time then go to your Userform property and make ShowModal = False

Invalidate ribbon control in Excel 2013 for multiple workbooks

I have a customized ribbon where I added a tab containing a toggle button. This toggle button has a getPressed attribute which is linked to a callback function returning the pressed state of the toggle button. The purpose of the toggle button is to display/hide a custom task pane. This works fine.
However, my issue is that in Excel 2013, if I have two or more workbooks open, when I invalidate the toggle button, only the one of the active workbook is updated. I also want to update the pressed state of the toggle buttons on the other workbooks as the custom task pane is either visible or invisible in all workbooks.
Anyone knows how to do invalidate a control in the ribbon of all workbooks in Excel 2013?
I am using vb.net and excel-dna.
The toggle button is defined like that:
<toggleButton id="toggleButtonInputData" size="large" onAction="rxToggleButton_onAction" getPressed="rxToggleButton_getPressed" getImage="rxButton_GetImage" getLabel="rxbutton_GetLabel" getEnabled="rxGenericControl_GetEnabled" visible="true"/>
The callback function is:
Function rxToggleButton_GetPressed(ctl As CustomUI.IRibbonControl) As Object
Select Case ctl.Id
Case "toggleButtonInputData"
Return CTP_InputData.IsToggleButtonPressed
End Select
End Function
To invalidate the toggle button I use :
Public Sub CTP_InputData_VisibleStateChange() Handles CTP_InputData.VisibleStateChange
XLRibbon.myRibbon.InvalidateControl("toggleButtonInputData")
End Sub
The Invalidation is only processed for the active workbook's ribbon. But when you then switch to another workbook, the callbacks will fire again and will now be applied to the ribbon of the new workbook.
There's a bug and some quirks in Excel 2013 related to this switching:
If you click on the title bar or the ribbon of the workbook you want to activate, everything works as expected. But if you click on a cell in the workbook you're activating, you get two callbacks - the first is applied to the deactivating workbook's ribbon, and the second is applied to the activating workbook's ribbon. The problem is that you cannot distinguish (in your callback) whether you are getting called for the deactivating book. (Using COM events doesn't help either, both callbacks happen after all the COM Workbook- and Window- (De)Activate events have fired.
Apart from this quirky behaviour, one clear bug in Excel 2013 is that the IRibbonControl.Context is not set to the correct window - in both of the callbacks it reflects the activating window, though the first callback will be applied to the deactivating window.
Here's a detailed discussion on the issue: https://social.msdn.microsoft.com/Forums/windowsserver/en-US/a3dade87-1df7-46ec-8876-437194d7553e/how-to-reference-the-correct-workbook-from-a-control-in-a-ribbon-callback?forum=exceldev
In summary, you don't have good control over the state of deactivated ribbons. But if you are only worried about the active ribbon, Invalidate works fine, but you must expect the callback only upon activation.

Event when VBA code module is reset?

I am developing an excel sheet which has lots of ActiveX elements in it.
I am not using UserForm and all the data is loaded when an activeX button is pressed.
At this point a hidden excel app is created where various actions are performed.
This new app is then combined with other data etc etc.. based on what the user is doing on the front-end with the provided ActiveX controls.
My problem comes when the "project is reset", where all the objects are released from memory and everything.
If this was a user form I would have implemented "on terminate" event where I would close hidden all workbooks that I have used, basically clean after myself.
However this is not a userform and there is no way to detect when the "project is reset"(as far as I know) so the hidden excel app that I've created remain open but nothing points to it.
If I go to the task manager i see various "EXCEL.EXE" and the number of those is basically the number of times I have run the tool.
So, is there any way for me to detect when VBA is about to "stop the project" in the same was as there is "terminate" for user forms so I can delete unsused stuff and reset elements in the spreadsheet?
Thank you!
I have found that there is no corresponding event to catch this.
Best way to handle this is to create a hidden userform object which will "hold" all global variables and objects that I define. I can then implement a UserForm_Deactivate event to catch when the form is exiting and clean up after myself.