1st, what i want to do:
I have a main UserForm, on that form i have a button to show secondary UserForm. When i click on that button, i want main form to be hidden. When i'm done with with work on the secondary form, i want to close it and show the main form again.
2nd, what i have so far (relevant code):
Main form code:
Private Sub createFastButton_Click()
Me.Hide
formSec.Show
End Sub
Secondary form code:
Private Sub cancelButton_Click()
Me.Hide
formMain.Show
End Sub
Private Sub UserForm_Terminate()
formMain.Show
End Sub
3rd, the problem:
If i use ControlButtons to navigate between forms, all works as intended. But if i use the "X" close window button on the secondary form and try to open it again from main form, it loses all functionality (main form works fine). It just shows the secondary form as i see it, when i use "View Object" in VBA editor. None of the buttons work and none of the intended boxes and labels are filled. Even the "X" button doesn't work. For me it seems obvious, that the problem is with unloading of secondary form. I tried to replace Me.Hide in secondary form with Unload Me and exactly same thing happens, as if i press the "X" button. So i need to do something with Sub UserForm_Terminate(), i tried to add Me.Hide there and as expected, it did nothing.
I there a solution to my problem?
Thx in advance.
main routine, calling Main Form:
With New formMain
.Show
End With
main form, calling secondary form
Private Sub createFastButton_Click()
Me.Hide
With New formSec
.Show
End With
Me.Show
End Sub
secondary form
Private Sub cancelButton_Click()
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = VbQueryClose.vbFormControlMenu Then Cancel = True
End Sub
no need for UserForm_Terminate() in secondary form, unless for unsaid needs
Clicking the "X" raises a QueryClose event that you need to handle, e.g.:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = VbQueryClose.vbFormControlMenu Then
Cancel = True
Me.Hide
' Add more code here to respond to form close event
End If
End Sub
See here for a very helpful explanation.
Related
I trying to use this add in https://www.excelcampus.com/wp-content/uploads/2022/02/The_List_Search_Add-in_for_Excel.zip
but problem if i select down
and post some fields and press close button, form appears multiple times equals to posted previous fields.
So how to prevent toggle form show and just close form on closee button instead of multiple time fire onchange event?
This code also just ignoring by vba
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
'Cancel = True
Unload Me
Exit Sub
End If
End Sub
Unload Me do nothing, and form not closing
I have 2 Userforms, Userform1 and Userform2. I would to like to code Userform2 so that when the user closes it using the X button on the top right corner, it closes and Userform1 is automatically opened. The user can go from Userform1 to Userform2 with a CommandButton that has the following code:
Private Sub CommandButton1_Click()
Unload Me
UserForm2.Show
End Sub
After closing Userform2, I managed to automatically open Userform1 with the following code in it:
Private Sub UserForm_Terminate()
UserForm1.Show
End Sub
The problem is that this only works once. The second time the user clicks CommandButton1, Userform1 is closed and Userform2 showed, but Excel hangs up. The only way to fix it is to stop all the code from the developer environment or force quit Excel.
Using the UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) event isn't possible because that way, Userform2 never reaches the Unload part and is just kept in the background while Userform1 launches again, like this:
There is no need to unload UserForm1. Simply hide it. Also there is no need to show UserForm1 from UserForm2. It will automatically get shown when UserForm2 unloads. Is this what you are trying?
In a module
Option Explicit
Sub Sample()
Dim frmOne As New UserForm1
frmOne.Show
End Sub
In Userform1
Option Explicit
Private Sub CommandButton1_Click()
Me.Hide '<~~ Hide the form
Dim frmTwo As New UserForm2
'~~> Show the form in Modal(default)
frmTwo.Show
'~~> Show UserForm1 when UserForm2 unloads
Me.Show
End Sub
EDIT
Thank you for taking the time to help me! Unfortunately this is not what I am looking for. I'm specifically trying to unload Userform1 when showing Userform2 and viceversa because I don't want/need to preserve any data. I know manually clearing the form would also work, but the other thing is that this is only an example. My real code has many forms and I don't want all of them to remain loaded in the memory. That could potentially cause some performance issues. – Fernanda 10 mins ago
This doesnt crash for me
In a module
Option Explicit
Sub Sample()
Dim frmOne As New UserForm1
frmOne.Show
End Sub
In Userform1
Option Explicit
Private Sub CommandButton1_Click()
Unload Me
Dim frmTwo As New UserForm2
frmTwo.Show
End Sub
In Userform2
Option Explicit
Private Sub UserForm_Terminate()
Dim frmOne As New UserForm1
frmOne.Show
End Sub
I created two forms. Pressing the button 1 opens the form number 2. By closing the form number 2, the form number 1 is displayed. But this action is only done once and it stops for the second time and almost does not work. Where does the code have a problem?
code Userform1:
Private Sub ShowUserform2_Click()
UserForm1.Hide
Unload UserForm1
UserForm2.Show
End Sub
Code userform2:
Private Sub UserForm_Terminate()
UserForm2.Hide
Unload UserForm2
UserForm1.Show
End Sub
Skip the formName.Hide lines. They are unnecessary.
After the Unload formName statements add:
Set formName = Nothing
Also, make the otherForm.Show line precede the above two lines.
Try this code:
code Userform1:
Private Sub ShowUserform2_Click()
UserForm1.Hide
UserForm2.Show
End Sub
Code userform2:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
UserForm1.Show
End Sub
I have two forms, a login form to authenticate users to enter the system and a main form to work with if the authentication is successful. I work with an access database to search for the valid users and also to populate lists in the main form.
And here is the code for that:
Private Sub CancelCommandButton_Click()
CloseDatabase
Unload Me
End Sub
Private Sub ConfirmCommandButton_Click()
...
End Sub
Private Sub UserForm_Initialize()
ConnectDatabase
End Sub
Private Sub OpenMainForm()
Unload Me
MainForm.Show
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
End If
End Sub
And here is the code for managing main form load-up and close:
Public Sub UpdateControls()
PopulateUserList
End Sub
Private Sub UserForm_Activate()
sTag = Split(Me.Tag, "|")
If sTag(0) <> "1" Then
Me.MainFormMultiPage.Pages(0).Enabled = False
Me.MainFormMultiPage.Value = 1
Else
Me.MainFormMultiPage.Pages(0).Enabled = True
Me.MainFormMultiPage.Value = 0
UpdateControls
End If
UserLabel1.Caption = sTag(1)
UserLabel2.Caption = sTag(1)
UserLabel3.Caption = sTag(1)
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
' Tip: If you want to prevent closing UserForm by Close (×) button in the right-top corner of the UserForm, just uncomment the following line:
' Cancel = True
Dim answer As Integer
answer = MsgBox("ÂíÇ ãØãÆäíÏ ˜å ãí ÎæÇåíÏ ÇÒ ÓÇãÇäå ÎÇÑÌ ÔæíÏ¿", vbYesNo + vbQuestion, "ÎÑæÌ ÇÒ ÓÇãÇäå")
If answer = vbYes Then
CloseDatabase
Else
Cancel = True
End If
End If
End Sub
Private Sub UserForm_Terminate()
loginForm.Show
End Sub
When I close the main form by clicking 'X' button, the login form reappears and the main form is closed; But when I login again (preferably using the same credentials) the main form is displayed but totally unresponsive (No list population, 'X' button doesn't work or any other controls in the form).
What should I do? Does the code in the UserForm_CloseQuery() unload the main form and all of its macros and I can't get the required events back to function or am I missing something?
It's not a time I started coding VBA and I can't make the head or tail of it easily when new problems arise. Any help would be appreciated. Thanks
Assuming your forms are modal, change the login form code to:
Private Sub OpenMainForm()
Me.Hide
MainForm.Show
Me.Show
End Sub
and remove the Userform_Terminate code from the main form. That will mean that the login form automatically shows when the main form is closed.
Where should I put Load and Unload frm1 (Userform name is frm1) and where should I put Me.Show and Me.Hide?
The (x) button within the UserForm doesn't work.
My Load and Unload is within the Active-X command button code on Sheet1:
Private Sub cmdb1_Click()
Load frm1
Unload frm1
End Sub
This way my UserForm is initialized and I can run the code
Private Sub Userform_Initialize()
'Some other code that Works...
frm1.Show
End Sub
that shows my Userform. Now I have a command button in my Userform that has the code
Private Sub cmdbClose_Click()
Me.Hide
End Sub
which I use to hide the sub, upon which the last line within cmdb1_Click() is executed and UserForm is unloaded. This Works.
However when I press the (x) button in my UserForm, the following error appears
Debugger says error lies within cmdb1_Click(). I've tried adding a sub called UserForm_QueryClose(), but the error persists. If I'd have to guess, I'd say the error is caused by the way I handle Load and Unload, thus by cmdb1_Click().
EDIT:
My problem is solved. ShowUserform and cmdbClose_Click contain the code CallumDA suggests. My command button now has:
Private Sub cmdb1_Click()
Load frm1
Call ShowUserform
End Sub
I recommend that you create an instance of your userform:
Dim MyDialog As frm1
Set MyDialog = New frm1 'This fires Userform_Initialize
You can then easily check whether the form is loaded before attempting to unload it:
If Not MyDialog Is Nothing Then
Unload MyDialog
End If
I also recommend that you don't call the Show method from the form's Initialize event. Think of your userform as just another object in Excel and manage it from your main code body.
Also, I wouldn't unload it in the cmdbClose_Click event as suggested by CallumDA (though that works fine to solve the current issue). Often you will need to be able to refer to values on your form from your main code body, and if you unload it they won't be available. Instead, keep it like you had it in the first place:
Private Sub cmdbClose_Click()
Me.Hide
End Sub
So your main code body (in your activeX button) will look something like this:
Dim MyDialog as frm1
Set MyDialog = New frm1 'This fires Userform_Initialize
'Place any code you want to execute between the Initialize and Activate events of the form here
MyDialog.Show 'This fires Userform_Activate
'When the close button is clicked, execution will resume on the next line:
SomeVariable = MyDialog.SomeControl.Value
'etc.
If Not MyDialog Is Nothing Then
Unload MyDialog
End If
You can also catch the event that fires when a user clicks the "X" on the form, and prevent the form from being unloaded:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = VbQueryClose.vbFormControlMenu Then
Cancel = True
Me.Hide
End If
End Sub
Lastly, often you need a Cancel button on the form. The way I handle this is to create a "Cancelled" property in the form's code-behind:
Public Cancelled as Boolean
'(Note You can create additional properties to store other values from the form.)
In the Cancel button's click event:
Private Sub cmdbCancel_Click()
Me.Cancelled = True
Me.Hide
End Sub
And in the main code body:
Dim MyDialog as frm1
Set MyDialog = New frm1
MyDialog.Show
If Not MyDialog.Cancelled Then
SomeVariable = MyDialog.SomeControl.Value
SomeOtherVariable = MyDialog.SomeOtherProperty
'etc.
End If
If Not MyDialog Is Nothing Then
Unload MyDialog
End If
(I know the above is not strictly the correct way to declare a property, but this will work fine. You can make it read-only in the usual way if you wish.)
Put this in a standard module and link it up to the button you use to show the userform
Sub ShowUserform
frm1.Show
End Sub
And then in the userform
Private Sub cmdbClose_Click()
Unload Me
End Sub
I struggled for years with forms in Excel. I could never understand how an object (a form) could be destroyed but still have it's code running.
I now use this code on every form that has [OK] and [Cancel] buttons, as it allows you to control the [OK], [Cancel] and [X] being clicked by the user, in the main code:
Option Explicit
Private cancelled As Boolean
Public Property Get IsCancelled() As Boolean
IsCancelled = cancelled
End Property
Private Sub OkButton_Click()
Hide
End Sub
Private Sub CancelButton_Click()
OnCancel
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = VbQueryClose.vbFormControlMenu Then
Cancel = True
OnCancel
End If
End Sub
Private Sub OnCancel()
cancelled = True
Hide
End Sub
You can then use the form as an instance as follows:
With New frm1
.Show
If Not .IsCancelled Then
' do your stuff ...
End If
End With
or you can use it as an object (variable?) as noted above such as:
Dim MyDialog As frm1
Set MyDialog = New frm1 'This fires Userform_Initialize
Then similar instance noted above.
This is all based on an excellent article by RubberDuck which goes into more detail and explains the code given above.