Tab control in VB - tabs

I'm working on a legacy VB6 application. I'm sure this probably relates to VB.NET so i will tag it, but please let me know if it's completely different(which I dont think it is) then I'll remove the tag to avoid confusion.
Here is my issue....
I have a Tab control with multiple tabs: 0 - 3. On TabStuff.Tab = 0, I have a few textboxes and comboboxes. The user uses keyboard TAB to move from Indexed controls. What happens is once they get to the last control which is a textbox called txtCity - and click keyboard TAB once more, it brings them to TabStuff.Tab=1.
My issue is I do VALIDATE on txtCity - I call a function that verifies that a couple of the fields aren't NULL and if one of the fields is in fact NULL then I show a MSgBox and try to setFocus on that control. But instead, when OK is clicked on msgbox, it goes to the next tab which is TabStuff.tab=1 which is not correct.
Here's some of my code...
Dim FirstName, City as String
flag=false
firstName = txtName.text
city = txtcity.text
if FirstName="" or isnull(FirstName) then
msgbox "Please enter Name"
tabstuff.tab=0
txtname.setfocus
exit sub
elseif city = "" or isnull(city) then
msgbox "Please enter city"
tabstuff.tab=0
txtcity.setfocus
exit sub
end if
flag=true
This code is in txtCITY_VALIDATE
So in case city was empty, it shows MsgBox, stays on Tab=0 and setfocus on that control, but instead it goes to the next tab=1 and sets focus on the first control of that tab.
EDIT:
in txtCITY_LostFocus
If Flag = False Then
TabStuff.Tab = 0
Exit Sub
End If
I added this but it still goes to tabstuff.tab=1 setting the focus on first control of the tab
EDIT 2:
In a new project i created txt1 and txt2 - i set TabIndex 0 and 1 respectively.
Private Sub Txt1_Validate(Cancel As Boolean)
If Txt1.Text = "" Then
MsgBox "no text in txt1"
Txt1.SetFocus
End If
End Sub
This is the code I use. I click TAB on txt1 without entering any text, so this gets executed, but after msgbox, the focus gets set on txt2

For some extremely weird reason - i seem to have been getting this discrepancy because I was doign it in the VALIDATE property. When i entered the same code in LostFOCUS it seems to work fine. Thanks everyone for your help with this!

Related

Textbox Form Field Required

I inserted the following VBA code to my textbox in a form. It only works if i type something then delete what i typed. If i go to the next box, then the error message comes out. Is there any way to require the textbox is filled out?
Private Sub master_bill_a_BeforeUpdate(Cancel As Integer)
If IsNull(Me.master_bill_a) Then
Cancel = True
MsgBox "You must enter a value for 'YourControlNameOrYourDescription'.
Please make a valid entry or press ESC to Cancel"
'You could set the focus on the specific control if your wish, change
the background color, ...
End If
End Sub

MS-Access: Populate modal form from custom type

I am trying to display an error form, populated with text from a custom type object, as a MS-Access version of the fantastic answer on this Excel question.
The problem I run into is that I want to wait for a user response/confirmation on this error form, so it must be (as far as I am aware) a modal form and therefore I cannot just open the form and immediately populate it.
I have tried to find a way of doing in Access what was done in Excel; load the form, populate the form then display the form, but this doesn't seem possible since Access' event order is Open->Load->...
I have also tried looking for a way to open as a normal form, populate and then 'modalise' the form but could not find a way to do this.
Does anyone know of a way to achieve this function? Or is there an alternative to modal forms to pause execution awaiting user input?
A modal form is VERY different from a dialog form.
Modal forms do NOT cause the calling code to halt, but a dialog form does.
(do not confuse the two types of forms).
To “get back” a user response from a dialog form, simply set the form visible = false in place of a close form command. This will KICK the dialog form out of dialog mode, and your calling code now continues and the calling code is “free” to examine any values the user typed in or say choose from combo boxes, or check boxes, or whatever.
So your code block will look like this:
Private Sub Command0_Click()
Dim f As String
Dim strT As String
f = "formB"
DoCmd.OpenForm f, , , , , acDialog
If CurrentProject.AllForms(f).IsLoaded Then
' grab any values entered by user, or whatever buttons hit
strT = Forms(f).Text1
' etc. etc. etc. - grab values from that form
' don't forget to close the form
DoCmd.Close acForm, f
Else
' user canceled the form
' code goes here for user hitting your cancel button or "x"
End If
End Sub
And in your dialog form, the “ok” button, or “close” button simply goes:
Me.visible = False
If the user hits your cancel button, that code would be:
Docmd.Close acForm
So if the user hits “cancel” or even the “X” in the upper right corner, you consider and assume the user “bailed out”. When they do this, the form will be closed.
So the code after the dialog part simply checks if the form is STILL open (because your “ok” button does a visible = false).
And since the form is STILL open, then you are free to grab the values of ANY control – say user text typed into a text box, values from a combo box, check box, or whatever.
When user is done the calling code is free to examine or grab any value(s) from that form.
Edit - 2nd solution to allow "setting" of values.
This code will work:
Private Sub Command0_Click()
Dim f As String
Dim strT As String
f = "formB"
DoCmd.OpenForm f
Forms(f).Text1 = "Hello" ' set values on form
' now WAIT for user
Do While CurrentProject.AllForms(f).IsLoaded
If Forms(f).ok = True Then Exit Do
DoEvents
Loop
If CurrentProject.AllForms(f).IsLoaded Then
If Forms(f).ok = True Then
MsgBox "value return = " & Forms(f).Text1
Else
MsgBox "user cancel"
End If
DoCmd.Close acForm, f
Else
' cancel code goes here
MsgBox "user cancel"
End If
End Sub
The code for the OK button on the form B is now:
Me.Visible = False
Me.ok = True
And you need a public var "ok" in form B.
eg this:
Option Compare Database
Option Explicit
Public ok As Boolean
So the cancel button in form B can simply close the form. (you can close the form - but don't set ok = True)

Creating Message Boxes

In Access 2010, I need to have a Message Box pop-up when the user selects specific text (Real Estate) in a combo-box (ProductType).
In short...if the [ProductType] entered by the user is any one of the multiple "Real Estate" options available, then show a Message Box that states "USER MUST COMPLETE RESPA TRACKING" and then direct them to that page (tab) to complete additional text fields.
I've attached the following code to the BEFORE UPDATE function of the combo box. But that only creates the message, it does not direct them to the tab/fields that need to be entered.
Private Sub ProductType2_BeforeUpdate(Cancel As Integer)
Dim strPrompt As String
strPrompt = "The Product Type selected is Real Estate. The RESPA Tracking tab MUST be completed at time of App Entry and validated during Underwriting."
If Not IsNull(Me.ProductType2.Value) Then
If Me.ProductType2.Value Like "Real Estate*" Then
Cancel = (MsgBox(strPrompt, vbOK) = vbNo)
End If
End If
End Sub
It seems you've solved the creating a MsgBox issue, and now your remaining challenge is to "direct them to the tab/fields that need to be entered".
Use the SetFocus method to place focus on a specific page in your tab control, or on a control within that page.
This command button example shifts focus to the first control on a page named Page1 ...
Private Sub cmdPage1_Click()
Me!Page1.SetFocus
End Sub
But my guess is you will prefer focus on a specific control within the page. My Page1 contains a text box named txtMemo_field. This version places the focus on that text box. Notice the page name is not mentioned in this version; SetFocus is called on the text box directly ...
Private Sub cmdPage1_Click()
Me!txtMemo_field.SetFocus
End Sub

MS Access de-select listbox after running macro/query

So I have a form (frmBookingForm) in Access, and a listbox (lstMyBookings) that displays the results of a query.
Below this, I have a button (cmdDeleteBooking) which runs a delete query using the lstMyBookings selection as input. The button then runs a macro that firstly checks whether a record in the listbox is selected, and if one is, runs the delete query and requeries the data, so the deleted record is no longer shown in the listbox. If not, an error message is displayed.
However, if I then click the button again, it again runs the delete query, even though there is apparently nothing selected in the list box.
Essentially, how can I 'clear' the listbox selection?
I'd prefer a solution that can be done in a macro format, as I have little to no understanding of VBA. However, if providing a VBA solution, I'd greatly appreciate a short explanation of it.
Thanks :)
Looks like this website has a nice little function to do it. Essentially, you need to test if it's a multiselect, and then do one of two things. I suppose if you know ahead of time that it is/isn't a multiselect, you wouldn't even need the "if" statement:
If List0.MultiSelect = 0 Then
List0 = Null
Else
For Each varItem In List0.ItemsSelected
List0.Selected(varItem) = False
Next
End If
If the control's MultiSelect property is set to None, this code just sets List0 to Null. If the control's MultiSelect property is set to anything else, the code loops through all items that are currently selected, and sets the Selected property of that item to False. My example assumes your control is called List0.
EDIT
To use this code, use an event instead of a macro. Here's how you do this:
Right click on the button, select properties
In the Property Sheet window, click on the "Event" tab
Click inside of the "On Click" blank area, and click the dropdown arrow, then select "[Event Procedure]"
Click the ellipsis ("...") to go into the code editor.
In the code editor, your should already have your event for the button (let's assume the button is called Command1:
Private Sub Command1_Click()
End Sub
Add your code in between (assuming the listbox is called List0):
Private Sub Command1_Click()
If List0.MultiSelect = 0 Then
List0 = Null
Else
For Each varItem In List0.ItemsSelected
List0.Selected(varItem) = False
Next
End If
End Sub

Check which tab is clicked / Active in a MS Access form

I have created a form in MS Access 2011 in which there are a tab control on top named TabCtl18 in which 3 tabs are page1, page2, page3.
Under the page1 tab there are another 3 other tabs page11, page22, page33, under three tabs there are 3 reports respectively
Now I want that when a user clicks on pdf icon it check which tab has clicked and print that report.
My Code :
Private Sub cmdPrintReportPDF_Click()
If TabCtl18.TabIndex = 0 Then
If tab_graph.TabIndex = 0 Then
DoCmd.OpenReport "Graph_report", acViewNormal
DoCmd.OutputTo acOutputReport, "Graph_report"
DoCmd.Close acReport, "Graph_report"
End If
Else
If tab_graph.TabIndex = 2 Then
DoCmd.OpenReport "Graph_Report_FieldShifts", acViewNormal
DoCmd.OutputTo acOutputReport, "Graph_Report_FieldShifts"
DoCmd.Close acReport, "Graph_Report_FieldShifts"
End If
End If
End Sub
Based on issue highlighted by #David, here is the way to check name of the TabPage selected.
if tabControl1.Pages(tabControl1.Value).Caption = "TabPageName" then
'Do Something
end if
Moreover, You can use this code in Tab Control Click Event to check which Page is active.
The Value (which is the default) property of the tab control is the index of the page with the focus. It starts with zero.
If TabCtl18.Value = 0 Then
'this must be the first page
Similar to #adarsh marecha, but I suggest using the TAG property of the page - using index may not work as intended if the page order gets changed. Also, tabs names can get changed too, which may mean the code fails.
If you set the TAG property to the required value it is likely only you will use it, and it will thus be less likely to fail due to DB changes.
So my code becomes:
With Your_Form
If !tabControl.Pages(!tabControl.Value).Tag = "Your tag" then
'Do Something
End if
End With