I have a userform with with 6 different categories in which the user must select an option between 0-4. Each option is selectable with a radio button with a set value that will be written in the parent sheet. Each set of radio buttons that belong to a category are grouped (a-e).
Could someone please help me to implement a mechanism that will make it mandatory for the user to select at one option in each category by displaying a message prompting the user to select an option?
The workflow is as such:
User selects options --> Selected options are written in the sheet --> Unload Me on the form
Ideally it would be best if the macro to write all is "paused" (not proceeding to Unload Me). Instead the message is displayed, and then the form remains as it was so that the user can go back and continue, without having to redo the whole process.
EDIT:
Thanks for all help. Hope this makes it easier:
The code I'm using is being triggered by a "Register score" button that I've placed on the UserForm that contains all the radio buttons. The button contains the following code (where aa = first radio button):
Private Sub CommandButton1_Click()
If aa.Value = False Then
MsgBox ("Please select at least one option")
Else
Range("A" & Rows.Count).End(xlUp).Offset(1).Value = "Category A"
Range("B" & Rows.Count).End(xlUp).Offset(1).Value = "0"
End If
Unload Me
End sub
I now repeat this code for every radio button. Problem is, if the user for example selects a radio button properly in every category but forgets the first, the form will reset meaning that the user must re-do the entire thing. I can of course also add (I've only included the radio buttons here for sake of simplicity, but the correct code would of course include all buttons):
Private Sub CommandButton1_Click()
If aa.Value = False and ab.Value = False And ac.Value = False Then
MsgBox ("Please select at least one option")
In this case the user must select one option every category, but it will also reset the entire form, meaning that you have to redo everything.
How about something like:
If Radio1.value = False And Radio2.value = False And Radio3.value = False And Radio4.value = False then
Msgbox "Please select something from the first four Radio Buttons"
Exit Sub
End if
To ensure one is selected simply add a section of code in the OK/Close button's event that checks that at least one button is selected - if not display message and then either Exit Sub to abort the routine, or implement the checks as a function that returns a boolean and only unload if it returns true.
Incidentally, on your proposed workflow, if you unload the form how are you going to then write the user's choices into the sheet?
Related
New to Access (still), have only basic VBA skills.
I've got 3 subforms (subfrm_PackingSteps1 , subfrm_MetalDetection and subfrm_Weights - the first 2 are continuous and the other one is single form) within a main form (frm_daily_packing_record) that users go through and input data. The user should be able to input data in no particular order, and only at the end there would be a button to confirm that the user is ready to save this form.
I'd like to have this button on the main form that checks each control (in main form and subforms) for empty values. I found and adjusted a code to check the recordset of one of the continuous forms (see below), but I can't figure out:
how to include a code that checks each control instead of manually adding all of them (I've used a function before that utilises the Tag property, but can't add it to this)
how to keep the button in the main form while checking the controls/recordsets in the other subforms.
Thanks in advance.
Private Sub ConfirmBtn_Click()
Dim blnSuccess As Boolean
blnSuccess = True
Me.Recordset.MoveFirst
Do While Not Me.Recordset.EOF
If IsNull(Me.pc) Or IsNull(Me.InnerP) Then
blnSuccess = False
Exit Do
End If
Me.Recordset.MoveNext
Loop
If blnSuccess = True Then
MsgBox "You may proceed to save this record"
Else
MsgBox "You still have some empty fields to fill in!", vbCritical + vbOKOnly, "Empty Fields!"
End If
End Sub
I personally don't like this because it is too code-heavy and can easily break when the form is modified.
Instead may I suggest doing it slightly different, for each field have vba code .ondirty or .onupdate and do the validation checking right as the user is actually on that field.
This has 2 benefits, it is creating the validation when you are creating each form field and it STOPS the user right when their first mistake or bad data is entered. The last thing I want is to enter 50 fields, scroll to the bottom, submit fails then scroll back and try to find where the mistake was. If validation is done while the user it doing the actual data entry, when you get to the bottom you should have valid data and the submit should succeed without further testing.
Less code to debug and timely messages to the user if an error is caught!
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
I am creating an electronic checklist for a manufacturing process. Operators will have a series of tasks that they must identify are complete with a Yes/No option. Originally I used check boxes but because we want to validate the form is correctly filled out, I changed them to radio buttons under ActiveX controls. I intend to have the default value of both buttons as False so that the form appears blank when opened, then upon hitting a submit button it validates that all tasks are complete.
Originally I thought I could Group the Y/N's and iterate through opt_yes.value and opt_no.value with the group#, but that doesn't work. So Now I'm not sure how to do it without writing out code for all 19 tasks.
I've started a Function to validate my text entries:
Private Function EverythingFilledIn() As Boolean
EverythingFilledIn = True
With ActiveDocument.FormFields("Time")
If Len(.Result) < 1 Then
Application.OnTime When:=Now + TimeValue("00:00:01"), Name:="GoBackToTime"
MsgBox "What time is it?"
EverythingFilledIn = False
End If
End With
With ActiveDocument.FormFields("Cut")
If Len(.Result) < 1 Then
Application.OnTime When:=Now + TimeValue("00:00:01"), Name:="GoBackToCut"
MsgBox "What is the Cut Number"
EverythingFilledIn = False
End If
End With
And I'm wondering if I can get help on the radio button validations, or an insight to looking at it a different way. I have spent a couple of weeks on forums and learned nuances of radio buttons vs. check boxes, grouping and form validating but somehow none of it has addressed my situation.
1: The radio buttons should all be set to False upon opening template: Done
2. The radio button selected will be highlighted [radio1_Change()]: Done
3. Upon hitting Submit button, validation will alert operator of skipped tasks: ie both button values still False = exit Sub: Need Help Here
Currently the radio buttons are numbered and grouped per task: ie grp_1 has radio1(y) and radio2(n); grp_2 has radio3(y) and radio4(n) etc. I was hoping that this would make it easy to iterate through.
I don't know that how I have built my form is necessarily the best way that I can do it, but it was the way that I could get it to work, at least partially. I have built a form in ms-access 2007 that uses vba to either hide or make available certain combo boxes. The first choice and the one on which the rest of the form is based is a yes/no option, being that either the customer requires outside services for their job or not. Once that is selected the user can then choose from the outside service options(Which are the combo boxes, either visible or no based on the first choice). So this is where the problem comes in, I have code written so that if the user chooses no in the very first box the rest of the boxes are made invisible. However if the user chooses yes they must then choose values, again yes or no to either retain or remove other options for the remainder of the form.
What I am looking to do is to make it so that when the user returns to the form what choices they made are still there. So if they chose no then the form would basically be blank and if they had said yes initially than that answer along with only the other choices they made would be available.
What I am currently using is a simple if-then statement to make the boxes either visible or not.
Private Sub Combo36_AfterUpdate()
If Combo36.Value = "No" Then Me.Combo18.Visible = False
If Combo36.Value = "Yes" Then Me.Combo18.Visible = True
If Combo36.Value = "No" Then Me.Combo20.Visible = False
If Combo36.Value = "Yes" Then Me.Combo20.Visible = True
End Sub
Obviously I am not experienced with access and have stumbling my way through it. I am sorry if any of what I have said above is confusing. If clarity is needed please let me know.
Well for a start, "Flase" should be updated to "False".
Instead of storing and then repopulating the selected values it might be easier to turn the visibility of the whole form true/false based on selection which would keep the last values the user selected.
For showing visibility of the controls try:
Private Sub Combo36_Change()
If Me.Combo36.Value = "No" Then
Me.Combo18.Visible = False
Me.Combo20.Visible = False
ElseIf Me.Combo36.Value = "Yes" Then
Me.Combo18.Visible = True
Me.Combo20.Visible = True
End If
End Sub
Your initial code is okay, to be able to have the form retain the choices then copy the code you have under the Combo36_AfterUpdate() event into the Private Sub Form_Current() event. This will do it.
Hopefully I can explain what I want to do well enough...here it goes...
I have a data entry form...the user will be entering employeeIDs. Once in normal operation, most people will be entering only their own EmpID, and they should know it, so this won't be a big problem 99% of the time once this DB goes live.
However, I need some temps to enter historical data from paper sheets into the DB. These people will not know anyone else's EmpID. I'd like to set the Student field's OnDblClick event in the subform's datasheet to open a small form with a combo box. The combo box has a list of all Employee Names, and is bound to the EmpID. Once this user enters the name, and selects the person, I have a button they can click to return to the datasheet.
I can use a function to launch the form, no problem there. But how do I return the EmpID to the field in the datasheet that was double clicked?
When user double clicks in the Student field...I want the next form to appear, and then once they type in the name and select the correct person...and then click Found Them!...I need that bound value to return.
I'd love to say I have code to share right now...but the only code I have is to launch the look up form. I'm brain farting on how to pull the value back down.
The way to do this to launch your little dialog form as “acDialog”. This will cause the calling code to WAIT.
And then the “magic” part is when they click on “Found Them” you do NOT close the popup form, but simply set the form’s visible = false. This has the effect of the calling code that popped up this form that halted to continue (the form is kicked out of dialog mode when you do this). So now your calling code continues.
So your code will look like this:
Dim strF As String ' name of popup form
strF = "frmPopUp"
' open form, wait for user selection
DoCmd.OpenForm strF, , , , , acDialog
' if for is NOT open, then assume user hit cancel buttion
' (you should likly have a cancel button on the form - that cancel buttion will
' execute a docmd.close
If CurrentProject.AllForms(strF).IsLoaded = True Then
' grab the value of thee combbo box
strComboBoxValue = Forms(strF)!NameOfComboBox
DoCmd.Close acForm, strF
End If
As noted, the code behind the Found Them button DOES NOT do a close form, but sets forms visible = false (me.Visible = false), and this trick allows the calling code to continue at which point you can examine any value on the form. Remember to then close the form after you grab the value.
It looks like your data table is in a subform so there is a little more work but it does not have to be as complex as the above solution if you don't want it to be. #Andre451 was close but you need the extra step of identifying the form and subform. For the purpose of demonstration let's call the form Attendance and subform Entry then I'll call the second form LookUp. So the code for your double click in the subform field will of course look something like this :
Private Sub Student_DblClick(Cancel As Integer)
DoCmd.OpenForm "LookUp"
End Sub
You really don't need anything else fancy there. For the button on "LookUp" you will put this:
Private Sub Command2_Click()
Forms![Attendance]![Entry].Form![Student] = Forms!Lookup!Student
DoCmd.Close acForm, "LookUp"
End Sub
And that should get you what you want without any overhead or having to leave any ghosts open.