Closing any open userform - vba

After a good search and some (over)thinking I came to the conclusion that I have no answer on what seems to be a simple question.
I have an excel document with many (20+) userforms in it. If you press a button (that is not in the userform, but just on the excel sheet) to start over again it should close any userform that's open at that moment.
I tried with unload me but of course I got an error when there wasn't any open userform.
Then I tried to add on error resume next thinking it would skip the line if there was no userform and therefore not giving an error but just continue what I want it to do. (opening a new userform).
It did indeed not give me the error anymore but it doesn't close any open userform as well (when there is one open).
So here I am, hoping someone here can help me as I don't know what to do. I could list up all of the userforms I suppose but it should be possible to go faster and automatically I suppose?
Some more info: It is never possible to have more than one userform open at the same time. // The button I want to create closes all the userforms if there are any and leads the user back to the main menu.
Thanks in advance!
KawaRu

Try calling the following when you want to unload all forms
Sub UnloadAllForms(Optional dummyVariable As Byte)
'Unloads all open user forms
Dim i As Long
For i = VBA.UserForms.Count - 1 To 0 Step -1
Unload VBA.UserForms(i)
Next
End Sub

This is hopefully the worst code that I have written in the last 5 years, but it will close any breathing form in Excel that you may have (and will kill any variables etc) :
Public Sub CloseAll()
End
End Sub
Use with caution!
From the MSDN End Statement:
The End statement stops code execution abruptly, without invoking the Unload, QueryUnload, or Terminate event, or any other Visual Basic code.
Code you have placed in the Unload, QueryUnload, and Terminate events offorms and class modules is not executed.
Objects created from class modules are destroyed, files opened using the Open statement are closed, and memory used by your program is freed.
Object references held by other programs are invalidated.
The End statement provides a way to force your program to halt. For normal termination of a Visual Basic program, you should unload all forms.
Your program closes as soon as there are no other programs holding references to objects created from your public class modules and no code executing.

Related

In Excel VBA are public variables declared in a module cleared from memory once a subroutine is completed, if a modeless form remains open?

Right now I am trying to automate the building of a form that needs data collection from multiple sources. This is a question that will influence my design so no code is available for reference yet.
General setup
In a module "Module1"
Public infoArray As Variant
Sub Main()
'info array initialized to some value here
'insert various lines of code here
formA.show (vbModeless)
End Sub
Sub afterComments()
'called by an action done in the modeless FormA
'insert code that accesses infoArray() here
End Sub
My question:
If a variable is declared as public in a module, so that it exists outside the bounds of a subroutine, and a modeless form is called before the main subroutine ends. Will the value for that variable, set in the main subroutine, be available for the "afterComments" subroutine to access? Since the main subroutine will continue to its end because the form is modeless, I do not know if the values for those public variables will be cleared once that happens, or remain in memory since a form is still technically active.
(yes I realize I could probably find out quickly by running a test piece of code, but i don't have access to excel right now and I need to continue designing, also I apologize for the formating and any typos, this was written from my phone.)
So far I've only been able to find info on modeless form implementation, public variable access rules and that public variables are cleared when the code stops running, I just don't know if this counts as the code finishing or not because while the main subroutine finishes execution, the modeless form is still active. A simple yes or know would be sufficient, but any help would be greatly appreciated.

excel vba remove controls

I currently have a form with a couple of buttons, text boxes and a AcroPDF. AcroPDF is an additional control I have added to my toolbox and I get it from "Adobe PDF Reader".
This macro is being used on various computers and I have found out that, for some reason, the macro does not work on all computers. But when I delete the AcroPDF control from the form, it works for all computers. For the computers that do get an error, it happens when I first open the file I automatically get an error msg and the form does not automatically show up (like how I programmed it to).
Is there a way I can program this into my "Thisworkbook.open" so that if there is an error, I can somehow delete or disable this additional control? something similar to how you are able to turn on and off references? (see below)
ThisWorkbook.VBProject.References.AddFromFile ("libraryName")
UPDATED: the error message I get from the computers that don't work is the following:
system error &H80004005 (-2147467259). unspecified error
Thanks.
UserForm.Controls.Remove -- but this only works for controls added at runtime (dynamically). You cannot use the Remove method on a control that was added from the Designer.
Probably you need to reverse this logic, and only add the control when the reference exists on the user's machine.
Dim ctrl
If Len(Dir("libraryname")) <> 0 Then
Set ctrl = UserForm1.Controls.Add ...
End If
You would also then want to use the Remove method when closing the form, that way the form remains in a state that could be opened on either computer.
HOWEVER, the error message you get on the other machines may shed additional light on the source of the problem. Depending on what the error is, there may be other solutions that don't involve removing the control.
If you don't mind creating a duplicate form without the AcroPDF control you might be able to use labels and the GoTo statement.
Sub Workbook_Open()
' do stuff
On Error GoTo AcroPDFError
ThisWorkbook.VBProject.References.AddFromFile ("libraryName")
' load your form with the AcroPDF control here.
Continue:
On Error GoTo 0
' the rest of your Workbook_Open sub is here
Exit Sub
AcroPDFError:
' load your form without the AcroPDF control here.
GoTo Continue
End Sub

Application.OnTime in Add-In Workbook_Open

I've built a custom Excel add-in and I'm currently trying to figure out a way to prompt users via VBA when new versions of the add-in are available.
I tried just using the workbook_open event to check for the latest version and then prompt the user with a userform, but I discovered that when Excel loads an add-in that trigger a userform, Excel stops loading the workbook the user actually tried to open and reloads the add-in. So while the userform works like I wanted, the user gets a blank (read no sheets) Excel shell with a loaded add-in.
So I considered using Application.OnTime to postpone the VBA until after the add-in and target file were both open. I got the impression both here and here that this is possible, but I am only able to make it work in an .xlsm file and not a .xlam file.
Here's the code I'm testing with:
Sub Workbook_Open()
Application.OnTime Now() + TimeValue("00:00:05"), "Test_Addin.xlam!Versioning.Notify_User"
End Sub
And in a regular code module:
Sub Notify_User()
MsgBox "Hello"
End Sub
So, my question: Am I doing something wrong here?
I'm wondering if there's something about how an add-in is loaded/designed that keeps it from allowing this type of action to be performed.
Alternatively, is there a different way to do this that you can think of?
I read an interesting blog post (and comments) by Dick Kusleika on this topic, but it sounded like some people put a version check in each sub procedure... I have a lot of procedures, so this doesn't sound like a good alternative, although I may have to resort to it.
Well, time is of the essence so I resorted to the least desirable option: a check at the beginning of each procedure.
To the interested parties, here's how I did it:
Somewhere towards the beginning of each sub procedure I put this line of code:
If Version_Check Then Call Notify_User
And in my Versioning module I put this function and procedure:
Function Version_Check() As Boolean
Installed = FileDateTime(ThisWorkbook.FullName)
Available = FileDateTime("\\NetworkDrive\Test_AddIn.xlam")
If Installed < Available Then Version_Check = True
End Function
Sub Notify_User()
Update_Check.Show
End Sub
So each time a procedure is run this code checks for a version on our corporate network with a modified datetime greater than the datetime of the installed add-in.
I'm still very open to alternative ways of checking for new versions so feel free to post an answer.

Closing a userform or window by condition

I work with a software which has no loading window/picture, so when I run it, I don't know exactly when it starts to run. Though I can monitor the running .exe task in taskmanager I want to create a 'loading window' in VBA to make the loading process more visible. I think a possible way to achieve this is to write a simple macro which contains the shell(.) command and a testing condition (eg. if a counter counts to 130 then close the form automatically end if). The problem is when I try to use Unload Me, it can not be used unless it is a part of a click event. Here is my code which opens my form:
Sub Loadpic()
LPic.Show
End Sub
you can use this
Unload LPic
Do Events
You can find the formname in the properties dialog ( Press F4 when looking at the form)

Closing a Userform with Unload Me doesn't work

I need to close an Excel userform using VBA when a user has clicked a submit button and operations have been carried out.
How can I close a Userform from itself?
I have tried this but it returns a 361 error.
Unload Me
As specified by the top answer, I used the following in the code behind the button control.
Private Sub btnClose_Click()
Unload Me
End Sub
In doing so, it will not attempt to unload a control, but rather will unload the user form where the button control resides. The "Me" keyword refers to the user form object even when called from a control on the user form. If you are getting errors with this technique, there are a couple of possible reasons.
You could be entering the code in the wrong place (such as a
separate module)
You might be using an older version of Office. I'm using Office 2013. I've noticed that VBA changes over time.
From my experience, the use of the the DoCmd.... method is more specific to the macro features in MS Access, but not commonly used in Excel VBA.
Under normal (out of the box) conditions, the code above should work just fine.
Without seeing your full code, this is impossible to answer with any certainty. The error usually occurs when you are trying to unload a control rather than the form.
Make sure that you don't have the "me" in brackets.
Also if you can post the full code for the userform it would help massively.
Unload Me only works when its called from userform self. If you want to close a form from another module code (or userform), you need to use the Unload function + userformtoclose name.
I hope its helps
It should also be noted that if you have buttons grouped together on your user form that it can link it to a different button in the group despite the one you intended being clicked.