I have been searching the internet for this all day. But no luck.
Can you setup events for when you enter/leave a tab.
I.E.
OnExit(Tab1)
Do something
Thanks
Depending on your program flow, you might try:
Private Sub Combo3_Exit(Cancel As Integer)
If IsNull(Me.Combo3) Then
MsgBox "No exit"
Cancel = True
End If
End Sub
Private Sub Form_Current()
Me.Combo3.SetFocus
''Or to refer to a subform from the main form
Me.subformcontrolname.Form.Combo3.SetFocus
End Sub
Does the tab contain a subform or only controls from the main form?
A subform has an Exit event, so if you are only concerned that once you have entered the subform you should not leave without completing data, you could:
Private Sub subformcontrolname_Exit(Cancel As Integer)
If IsNull(Me.subformcontrolname.Form.Combo3) Then
Me.subformcontrolname.Form.Combo3.SetFocus
MsgBox "No exit"
Cancel = True
End If
End Sub
While this is not exactly what you want, you could instead of handling the exit simply prevent the user from clicking somewhere else. To do this, attach some code to your combobox1 that bascially set .Enabled=Xfor all elements outside your tab view - where X is determined by the state of the combobox...
Related
I'm using Office Professional Plus 2019. I have a ListBox that sometimes freezes the macro. The UserForm (AffDateSelector) has a ListBox (DateSelectionList) and a Button (Continue). The UserForm is called from the driving Sub with AffDateSelector.show. The code for the form is below:
Option Explicit
Private Sub Continue_Click()
Dim lngCurrItem As Long
'Assign the selected value to the public variable strClassDate.
For lngCurrItem = 0 To DateSelectionList.ListCount - 1
If DateSelectionList.Selected(lngCurrItem) = True Then
strClassDate = DateSelectionList.List(lngCurrItem)
End If
Next lngCurrItem
'Unload the form and return to the calling Sub.
Unload Me
End Sub
Private Sub DateSelectionList_Click()
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_initialize()
'Load ListBoxAccounts with the public variable strDateArray
With DateSelectionList
.List = strDateArray
End With
'Default the first row in DateSelectionList to be selected.
DateSelectionList.Selected(0) = True
End Sub
I've been using F8 to step through the code. When the form is shown, the UserForm_initialize() sub is executed and the data display properly. If the user does nothing else except click the Continue button, the Continue_Click() sub gets executed, the variable strClassDate is populated, control is returned to the calling sub and all is well.
The problem comes when the user selects an item other than the one defaulted in the list. Once the user clicks on the ListForm, the sub DateSelectionList_Click() is executed, but there's nothing in that sub, so the macro freezes. If I put in "dummy code" into DateSelectionlist_Click() (e.g. strClassDate = strClassDate) that line is executed and then the macro freezes when the End Sub statement is executed.
How can I allow the user to click on a non-defaulted item in the list, keep the form displayed, and wait for the Continue button to be pressed?
The code was fine. I had a lot of windows open and the pop-up didn't appear I was running the code from the VB editor but the pop-up never appeared. When I pressed Alt + Tab it didn't appear in that list either.
I must be missing something basic (no pun intended), but I can't figure this out.
I have a MS Word VBA form called frmChooseMacros. I want to execute a subroutine on an Open or Load event for that form before the user interacts with the form.
From this topic https://learn.microsoft.com/en-us/office/vba/api/access.form.open, I came up with this code as a test and added it to the code window for frmChooseMacros:
Private Sub Form_Open(Cancel As Integer)
MsgBox "Running open event"
End Sub
But it never executes when the form loads.
From this topic, https://learn.microsoft.com/en-us/office/vba/api/access.form.load, I also tried the Load event, like this, but still no joy:
Private Sub Form_Load()
MsgBox "Running open event"
End Sub
I'm running the form through this sub-routine...
Sub DocFix_00_RunMultipleMacros()
frmChooseMacros.Show
End Sub
...which executes when a button tied is clicked on the menu.
This image may help provide additional context:
Any help is appreciated. Thank you!
(Credit goes to #braX for helping me find the answer here.)
For Word, you have to use the UserForm_Initialize or UserForm_Activate events. There is no Form_Load or Form_Open events for Word.
I was able to solve this by first defining a UserForm object and setting it to my frmChooseMacros user form:
Sub DocFix_00_RunMultipleMacros()
Dim oForm As UserForm
Set oForm = New frmChooseMacros
frmChooseMacros.Show
End Sub
Then I use the UserForm_Activate event here:
Private Sub UserForm_Activate()
MsgBox "Form has activated."
End Sub
I have a sub called as sub1() which activates the userform1 through the command userform1.show()
This userform1 has a button called as continue. On clicking that button continue - A Macro called as Private Sub continuebutton() gets activated.
I want to program in such a way that it redirects to the line after userform1.show() in sub1().
Is it something that can be done?
Theoretically, what you want is possible, if you do it like this:
In the UserForm:
Private Sub btnContinue_Click()
flag = True
Debug.Print "I continue ..."
sub1
End Sub
In a module:
Public flag As Boolean
Public Sub sub1()
If flag Then
Debug.Print "sub 1 continues here..."
Else
flag = False
UserForm1.Show
Exit Sub
End If
End Sub
It will work exactly as intended, BUT it is not a good practice to work this way. (Some people may throw stones at you for using public variables at all in VBA.) Here are two articles, that give better ideas:
https://rubberduckvba.wordpress.com/2017/10/25/userform1-show/
Disclaimer - this one is mine:
http://www.vitoshacademy.com/vba-the-perfect-userform-in-vba/
On the form properties for userform1, set its "Modal" property to true.
When the form opens, it will have exclusive focus, and the code in sub1 will not continue running until after it closes. This may be the solution you need.
In the code below, the msgbox will only appear once userform1 closes:
sub sub1()
userform1.show()
msgbox "Now continuing with sub1"
end sub
No way as long as you show the form.
If you show the form modal, the calling routine continues if (and only if) the form is closed.
If you show the form non-modal, the code continues to run directly after the show - so it's already done.
So either you have to close the form when the user clicks the "continue..." button to let the calling macro continue or you have to split your code into two routines and call the second on button-click.
You can change your Sub1 as follows:
Sub sub1(Optional Continue As Boolean)
If Continue = True Then
DoSomeStuff
Exit Sub
End If
userform1.show
End sub
And then, you can call your sub1 using:
Private Sub continuebutton()
Call sub1(True)
End Sub
Hope it helps
If you don't want to go with the 'Modal Form' solution, you could add a subroutine to your main module, and call it when required. So, in userform1, you have:
sub sub1()
userform1.show()
end sub
public sub sub2()
msgbox "Now continuing..."
end sub
And then in userform1, set some code on its onClose event:
Private Sub continuebutton()
Call sub2()
end sub
I'm using a VBA Userform. The MassPrompt userform has a set of six GroupNames and some text boxes. Each GroupName contains two or more radio buttons.
I'd like the following code to be triggered anytime any element within the GroupName "GROnly" changes. If the user made an inappropriate button choice in "GROnly" based on the choice in another group, I'd like to display a warning message and present the MassPrompt userform again.
Right now, I've assigned the code to the one button "GROnly_yes". It works, but only when that one button is clicked. How do I position this within the UserForm code to trigger anytime a button with the GroupName "GROnly" is clicked? Thanks for looking at this.
Private Sub GROnly_yes_Click()
'Prompt if the GROnly is true and it's inappropriate for the GSetting choice
If GROnly_yes = True And GSetting_renewal = True _
Then
GROnly_yes = False
GROnly_no = True
MsgBox ("The GROnly can't be chosen with a Renewal." & vbNewLine & _
"The GROnly button has been changed to 'NO'.")
UserForm_Initialize
End If
'Other IF statements here.
End Sub
If I understood well, GRonly is the GroupBox that contains (let's say) the radio_button_1 and radio_button_2.
The reason why the code doesn't trigger is that when he/she changes the value of one radio-button is not clicking on the GroupBox, but rather changing the value of that single radio-button.
You will have to add the code to the _Change event of the radio button objects. This is an example:
Sub myFunctionalCode()
'your code here
End Sub
Private Sub radio_button_1_Change()
myFunctionalCode
End Sub
Private Sub radio_button_2_Change()
myFunctionalCode
End Sub
Thanks for the reply. That would work.
In the meantime, I came up with another alternative as well. I removed the code from:
Private Sub GROnly_yes_Click()
And I moved it to the button that the user clicks to submit the form:
Private Sub ContinueButton_Click()
In my original code I had to change UserForm_Initialize to Exit Sub to make the code work in the "submit" button.
Thanks again for your help.
Phil
Quick question here, hoping for a concise sensible solution.
I have a bound form purely for data entry (cannot browse records, only insert them).
I will have a lot of users that screw up. To avoid dirty data, I want them to confirm that the form is correct before submitting the record.
Problem is, as soon as I input ANYTHING on the form, access creates and saves a record.
I want the record to ONLY be saved and committed if the user clicks 'Submit'. If they click close or exit the application, I do not want that partially completed record in the database.
Without using an unbound form and calling an insert function, is there a simple solution?
An autonumber is there to be unique, not sequential. If you need a sequential number, do not use autonumber. Autonumber should never be shown to the user. It can never be relied upon to be anything but unique, and if you mess about enough, not even that.
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me.AText = "Invalid" Then
Me.Undo
Cancel = True
End If
End Sub
Note that a form with a subform may not work with undo, because the record is committed on change from the subform to the main form and vice versa and it all gets quite complicated.
Remou's method is definitely the quickest, here is another based on my comment ;)
Option Explicit
Private blnGood As Boolean
Private Sub cmdSubmit_Click()
blnGood = True
Call DoCmd.RunCommand(acCmdSaveRecord)
blnGood = False
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Not blnGood Then
Cancel = True
Call MsgBox(Prompt:="click submit to save the record", Title:="Before Update")
End If
End Sub
You can use the following code to create a clear button in case the user made an errors and wants to clear the entire form and start over.
Private Sub btnClear_Click()
If Me.Dirty = True Then
DoCmd.RunCommand acCmdUndo
Exit Sub
End If
End Sub`
I sometimes find the before_update event to act weird so I generally disable the close (x) button in properties and add a close button of my own that prompts the user if he wants to abandon the data on screen.
Private Sub close_Click()
Dim Answer As Integer
If Me.Dirty = True Then
Dim Response As Integer
' Displays a message box with the yes and no options.
Response = MsgBox(Prompt:="Do you wish to discard data?", Buttons:=vbYesNo)
' If statement to check if the yes button was selected.
If Response = vbYes Then
DoCmd.RunCommand acCmdUndo
DoCmd.Close
Else
Me.Clear.SetFocus
End If
Else
' The no button was selected.
DoCmd.Close
End If
End Sub