Reset a userform to blank on button click - vba

I have a dynamic Userform. When loaded only a Combobox is visible, and user selects one option and accordingly some Labels and Textboxes with values are populated. But when I choose another option from Combobox and click on the button, all labels disappears but Textboxes remains there. Is there any way to clear or reset the Userform completely before loading?

I am not entirely sure how you set up your routines, I just based this answer on assumption. From what I understand, you want to reload the Userform using the same CommandButton in it. If that is the case, you can try this:
In a module, write a procedure that loads your form. Something like:
Sub marine()
Load Userform1
Userform1.Show
End Sub
In your CommandButton, create a routine that will call the load procedure and at the same time unloads the form. Something like:
Private Sub CommandButton1_Click()
'/* call the marine procedure after 0.5s */
Application.OnTime DateAdd("s", 0.5, Now), "marine"
Me.Hide
Unload Me '/* unloads the userform
End Sub
Your Userform will be invisible momentarily (like it flickers) but it will be reloaded just like the way you want it to be. HTH.

Related

Get value from command button VBA

I have created A userform with few command buttons.
I can't seem to figure out how do I get the information from them.
I want to open this userform from another one and then I want the user to choose an option from one of the buttons which will change a specific cell in the table itself
the userform I created
I did not write anything on this userform therefor there is no code from it to show only the design.
how do get the information from the buttons to be written in A specific cell on a specific worksheet?
double click on one of the buttons, in the code menu a new sub should appear. this looks something like:
Sub CommandButton1_onClick()
End sub
Alongside this event method, it also has a few properties. The one that is usefull here is the CommandButton1.Value, this represents the state of the button (either true or false iirc).
So build for each button (I strongly advice giving them custom names to prevent getting lost in the trouble) as sub like this:
Sub CommandButton1_onClick()
if CommandButton1.Value then
ThisWorkBook.WorkSheets("WorksheetName").Range("YourRange").Value = "Some value"
else
ThisWorkBook.WorkSheets("WorksheetName").Range("YourRange").Value = ""
end if
End sub

How to close a userform when another userform or a blank space is selected in excel VBA?

Whenever people clicks on the Debit Account or Credit Account fields on the userform, another userform with a Treeview will pop-out. However, the user will always have to press cancel in order to close the userform. Is there a way for the userform to automatically close when the Voucher Entry Form userform's area is selected?
If the question is "How to unload a user-form if it is not more the active object?" then the user-form in question must be modeless. Because else it cannot be deactivated without closing it's window. And because it is not possible opening a modeless user-form from a modal userform, the main user-form also must be modeless.
Example:
Do having two user-forms:
First user-form is named "MainForm" and has one button control and the following code applied:
Private Sub CommandButton1_Click()
Load SubForm
SubForm.Show vbModeless
SubForm.Left = Me.Left + 100
SubForm.Top = Me.Top + 100
End Sub
Second user-form is named "SubForm" and can be empty but has following code applied:
Private Sub UserForm_Deactivate()
Unload Me
End Sub
Then following Sub within a default module shows the main form:
Sub test()
MainForm.Show vbModeless
End Sub
Now after MainForm is shown, SubForm can be opened by button click. And if MainForm get the active form again (gets the focus again), the SubForm will unload.

Determining when the user clicks the x - VBA

I would like to programmatically decide if the user has clicked the top right "x" button while using a form in visual basic.
I have tried:
Private Sub nameOfForm_Exit()
'code goes here
End Sub
Which has been unsuccessful. Any help would be much appreciated.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
MsgBox "Good bye"
'/ To prevent user from closing the form
'/ Set cancel to True
Cancel = True
MsgBox "You can't close me!"
End Sub
You can't invent your own terms like "Exit". You have to take them in the combo boxes above (known as Events). Since your event pertains to the Userform itself, you need to choose Userform in the left combo box. You will also see all the controls your userform has, they each have a set of events.
As has been said QueryClose will refer to the red X in the top right corner. You also have Deactivate, which will happen whenever the UserForm loses focus (if it is ModeLess, meaning that a user can click the sheet behind the userform without closing it, this will trigger Deactivate) and Terminate, which occurs after the Userform closes with QueryClose.

Automatically execute some code after the UserForm is drawn

I have created a UserForm where the user is required to fill-in three fields. The macro attempts to auto-detect these fields' values in the UserForm_Initialize() event, then displays the found values in the three fields, but the user can change them. The auto-detection takes a few seconds, though, and delays the appearance of the UserForm. I'd like the UserForm to appear with its fields blank before the auto-detection procedure, then have the auto-detection procedure fill the fields automatically. What would be the best way to do this? Making the UserForm non-modal makes the macro run without waiting for the user's input, which is problematic. I don't want to have an "auto-detect" button: this has to be done automatically.
Use the Activate() event instead of Initialize() :)
Private Sub UserForm_Activate()
End Sub
FOLLOWUP
Thanks! It works, but there seems to be a bug: the dialog is drawn all white until the macro completes. screenshot (the dialog should be gray)
No. It is not a bug :) Try This. Add Doevents as shown below.
Private Sub UserForm_Activate()
UserForm1.ProgressBar1.Value = 0
starttime = Timer
While Timer - starttime < 1
UserForm1.ProgressBar1.Value = (Timer - starttime) * 100
DoEvents
Wend
End Sub
HTH
Sid
There is a simpler way to do this...
1) On your userform create a new 'CommandButton' that will execute the macro you wish to trigger.
2) Set the height and the width of the button to 0
3) Make sure the 'TabIndex' parameter for the button is 0... This will create an 'invisible' CommandButton that will receive the focus as soon as the form opens.
4) In the calling routine, immediately before the command that 'shows' the userform enter the line - 'Application.SendKeys "~"'
How it works...
The commandbutton created in (1) is a valid control just like any other wxcept that you can't see it or click it with the mousebutton. The 'SendKeys' command replicates a left mouse key click which is stored in the keyboard buffer until the form displays when it will be read. This has exactly the same effect as a mouse click and will run the required macro.
Incidentally, if you are calling the macro from more than one location and wish to have different actions dependant on the source of the call, you can add more than one 'invisible' button and add "{Tab}" before the "~" character to tab the focus through the available controls. e.g. 'Application.SendKeys "{Tab}~"' will activate the button with the 'TabIndex' parameter set as 1. 'Application.SendKeys "{Tab}{Tab}{Tab}{Tab}~" ' will activate the button with the 'TabIndex' parameter set as 4 etc.
RF
I'd suggest using a timer. Open the form with the input fields disabled and empty, and set the timer to fire within a couple of hundred milliseconds. This should allow the form to be displayed immediately. Do your auto-detection within the timer's tick event (disable the timer first), then enable the fields and fill in the detected values.

Save record in subform

I have a main form with a tab control containing multiple subforms. I need to be sure that the data in a subform is saved when the user switches tabs. The problem is that DoCmd.RunCommand acCmdSaveRecord seems only applies to the current form so it doesn't save the data in the subform.
I have tried different events on the subform such as deactivate, OnLostFocus etc but they don't fire until another field somewhere else gets the focus.
The ideal solution would seem to be to put something on the OnChange event of the tab control to be sure that all the data is saved. That is my question, how to do I save the record in a subform?
In Access, the default is to save, so unless you have done something pretty complicated to prevent this, moving the focus from a subform will automatically save the record. You can test this by adding a record, moving from the subform, and then checking the table.
You don't have to do anything at all, as the subform is saved as soon as it loses focus (when the tab control changes).
But as an exercise, I've outlined the code you'd write if you needed to.
You can save any form by setting it's .Dirty property to False. For something like this that's going to run a lot, I think I'd write a sub to walk through the subforms, check if any are dirty, and save the dirty ones. Something like this:
Public Sub SaveSubFormsOnTab()
Dim pge As Control
Dim ctl As Control
For Each pge In Me!ctlTab.Pages
Debug.Print pge.Name
For Each ctl In pge.Controls
If ctl.ControlType = acSubform Then
If ctl.Form.Dirty Then
ctl.Form.Dirty = False
End If
Debug.Print ctl.Name
End If
Next ctl
Next pge
Set ctl = Nothing
Set pge = Nothing
End Sub
Now, that's actually quite inefficient in cases where you have lots of controls on your tab control that aren't subforms. If your tab has nothing but subforms, it will be fairly efficient. In either case, it's much more efficient to use a custom collection populated in the form's OnLoad event, and then you'd walk that collection that includes nothing but your tab control's subforms, and save any that are dirty.
Either of these is preferable to using the OnChange event of the tab, because each time you add a tab page with a subform or change the name of a subform control, you'd have to alter the OnChange event.
I was having a similar issue where I needed various code to run in the subform and values in the main form - that were based on values in the subform - to be recalculated. Here is what finally worked:
This is an example with a main form named 'frmCustomers' containing a subform 'sfmTransaction', which in turn has a subform called 'sfmOrderLine'. The forms have a button 'cmdSave' that is only visible when the user clicks the 'cmdEdit' button (the purpose of which is to lock all the controls until the user clicks the edit button, and then to re-lock them when he clicks save):
On the main form ('frmCustomer') go the subform's exit event, and add 'me.recalc' twice, like this:
Private Sub sfmTransaction_Exit(Cancel As Integer)
If (Not Form_sfmTransaction.NewRecord And Form_sfmTransaction.cmdSave.Visible) Or (Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible) Then
'To save subforms
Me.Recalc
Me.Recalc
End If
End Sub
In the subform ('sfmTransaction') go the subform's subform's exit event, and add 'me.recalc' twice, like this:
Private Sub sfmOrderLine_Exit(Cancel As Integer)
If Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible Then
'To save subform
Me.Recalc
Me.Recalc
End If
End Sub
Hope this helps.
Setting the dirty property to false may force Access to save the data to the database, but it bypasses the before_update event. This means that if you've used this event for validation or other purposes, you can now have bad data in your database.