I have a textbox (in this instance it is textbox11) where the front end user will need to input "Half Day" in some form or another.
Here is my code:
Private Sub TextBox11_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
If Me.TextBox11 = "half" Or Me.TextBox11 = "half day" Or Me.TextBox11 = "half-day" Or Me.TextBox11 = 0.5 Or Me.TextBox11 = "1/2" Then
Me.TextBox11 = "Half Day"
End If
End Sub
When I run it, it works wonderfully - for the conditions I have set. However, if a user, say, inputs "hALf dAy", then this will not be validated and fixed to standard form as it is not on my condition list.
There is noway where I could put all permutations of what a user might put in. Is there a way to make this case-insensitive? So no matter what case a user puts in, it will check against my conditions anyway.
Thanks
LCase (or UCase) the user input. By converting all characters to lower case, and then comparing to your lower-case strings, you are effectively case-insensitive. Here's an example of that.
Private Sub TextBox11_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
Select Case Trim(LCase(Me.TextBox11.Text))
Case "half", "half day", "half-day", "0.5", ".5", "1/2"
Me.TextBox11.Text = "Half Day"
Case Else
' do nothing?
'
'
End Select
But if you really want validation the best option is to use a ComboBox with predefined values rather than a text box where the user can type any ol' garbage.
Related
I have set the row source to the same table for two different unbound comboboxes, cbo_MaxCost and cbo_MinCost, on a form. These comboboxes are meant to specify the minimum and maximum of a range of values for each record in another table. To ensure they do, I've set up code in each combobox's AfterUpdate event to check that
cbo_MaxCost >= cbo_MinCost
or warn the user with an error.
The problem is, this check performs erratically. For example, sometimes Access VBA will evaluate
21 > 11
as False and other times as True. Usage of the dot and exclamation point notations makes no difference, nor does using "Me." or not, or ".Value" or not. Stepping through it shows that Access registers the proper values from the comboboxes during the comparison. This behavior seems to happen more often when I select a much higher or lower value than was previously in one of the boxes. I can't figure out what causes it.
This is the code:
Private Sub cbo_MaxCost_AfterUpdate()
If cbo_MaxCost >= cbo_MinCost Then
MsgBox ("Access is calculating correctly.")
Else
MsgBox ("The maximum cost should be higher than the minimum.")
End If
End Sub
Private Sub cbo_MinCost_AfterUpdate()
If cbo_MaxCost >= cbo_MinCost Then
MsgBox ("Access is calculating correctly.")
Else
MsgBox ("The maximum cost should be higher than the minimum.")
End If
End Sub
Have in mind, that a combobox/listbox always returns text, so convert to numeric before the comparison:
CCur(Me!cbo_MaxCost.Value) >= CCur(Me!cbo_MinCost.Value)
I have a form where I want either Asset or Location filled out and Supervisor or Lead or Crew or Work Group or Crew Work Group. I have the code and it works but it only allows me to enter numbers into these fields. I want to be able to enter numbers and letters into these fields.
Private Sub Form_BeforeUpdate(Cancel As Integer)
If IsNull(Form_frmAddPM.Asset Or Form_frmAddPM.Location) Then
MsgBox "Please enter a value in an asset or location."
Cancel = True
End If
If IsNull(Form_frmAddPM.Supervisor Or Form_frmAddPM.Lead Or
Form_frmAddPM.Crew Or Form_frmAddPM.Work_Group Or
Form_frmAddPM.Crew_Work_Group) Then
MsgBox "Please enter value in Supervisor, Lead, Crew, Work Group, or
Crew
Work Group."
Cancel = True
End If
End Sub
I have tried to change integer to different types. With the code above when I try to enter letters into the form a mismatch type error pops up.
Thank you in advance for your help.
You're using the bitwise OR operator, which requires both values you use it on to be an integer (see the docs, VB.Net but works the same in VBA)
Instead, you should check for each field if it's null separately:
Private Sub Form_BeforeUpdate(Cancel As Integer)
If IsNull(Form_frmAddPM.Asset) Or IsNull(Form_frmAddPM.Location) Then
MsgBox "Please enter a value in an asset or location."
Cancel = True
End If
If IsNull(Form_frmAddPM.Supervisor) Or IsNull(Form_frmAddPM.Lead) Or
IsNull(Form_frmAddPM.Crew) Or IsNull(Form_frmAddPM.Work_Group) Or
IsNull(Form_frmAddPM.Crew_Work_Group) Then
MsgBox "Please enter value in Supervisor, Lead, Crew, Work Group, or
Crew
Work Group."
Cancel = True
End If
End Sub
I'm creating a Form in Microsoft Word. I have several 'Text form fields' some of which I want to restrict so users can only enter numbers. I don't understand why Microsoft gives you the option to change the 'Type' to 'Number' when that still allows any value to be input. Since that seems to be the case I have turned to VBA.
I'm trying to run a macro when the user exits one of these fields, to make sure the input is valid. I would rather not create a new macro for each field I want to restrict to numeric.
I think my problem is that I don't know how to get the result of the current field. I could create a different macro for each field, and get the result by specifying its name explicitly, but it seems like a smarter way would exist.
Here's what I have so far.
Sub validateNumericFields()
'Check to see if the value in the current field is numeric
'If it is not, send a message to the user, and set value to default value
If IsNumeric(Selection.Fields(1).Result) = False Then
MsgBox "You must enter a valid number.", vbExclamation
Selection.Fields(1).Result = Selection.Fields(1).TextInput.Default
End If
End Sub
There are various ways to get the "name" of a form field, since this is also a bookmark. The FormField object does have a Name property, but I can't get to it from the Selection object available when OnExit runs. But I can get the bookmark name, so:
Sub validateNumericFields()
'Check to see if the value in the current field is numeric
'If it is not, send a message to the user, and set value to default value
Dim ff As word.FormField
Set ff = ActiveDocument.FormFields(Selection.Bookmarks(1).Name)
If IsNumeric(ff.Result) = False Then
MsgBox "You must enter a valid number.", vbExclamation
ff.Result = ff.TextInput.Default
End If
End Sub
In my program, I have a snippet of code in a userfrom that looks at its own controls and loops through to see if all of them are empty. This is for the purpose of using all of the non-null controls' values as search parameters. They are three list boxes and three combo boxes. If it finds a control that is not empty, it sects the function to false and exits. This is because my search found a criteria it can use. I have it setup thus:
Function IsAllEmpty() As Boolean
'presumes true until we find evidence of a control being not empty
IsAllEmpty = True
'function elsewhere that sets my control background to normal
ClearControlFormatting
Dim ctrl As Control
'checks every control in the form
For Each ctrl In Me.Controls
'that is tagged with "searchme" (there are 6, three listbox, three combobox)
If ctrl.Tag = "SEARCHME" Then
'if the value of the control isn't null or len = 0
If Not IsNull(ctrl) Or Len(ctrl) <> 0 Then
ctrl.BackColor = vbGreen
IsAllEmpty = False 'in my other code, I can continue the search if this is triggered
MsgBox "Everything is good (no sarcasm) on this control!"
Exit Function
Else: MsgBox "EVERYTHING IS EMPTY, CARL. THAT KILLS PEOPLE."
End If
End If
Next
'If something is empty, tell the user to correct it
If IsAllEmpty = True Then
MsgBox "YOU NEED TO FILL OUT YOUR SEARCH, PAUL."
End If
End Function
I have tried various things to get this to work:
nesting the Not IsNull(ctrl) statement the only one in the if, the If Len(ctrl) <> 0 part (IDK WHY)
Removing the Len(ctrl) <> 0 part
Editing both parts of the Or statement to evaluate for ctrl.Value = "" instead
Removed the "SEARCHME" tags from the comboboxes, in case their dynamic values were interfering.
However, every time, I have watched this function highlight all of my controls green, and then proceed to continue attempting a search. (The function call down in the search says if all the cells come back null, exit the sub).
I'm at a loss, and would greatly appreciate the help! Thanks!
P.S.: If it helps, the above code is a modified version of the following, meant to check to see if any empty controls exist at all. When I used this on my controls, it found them all to be empty and worked like designed.
Function CheckForEmpty() As Boolean
CheckForEmpty = True
ClearControlFormatting
Dim ctrl As Control
'Checks each control that needs to be filled for null or 0 length value
'For every one it finds, it marks red
CheckForEmpty = True
For Each ctrl In Me.Controls
If ctrl.Tag = "FILL" Then
If IsNull(ctrl) Or Len(ctrl) = 0 Then
ctrl.BackColor = vbRed
CheckForEmpty = False
End If
End If
Next
'If something is empty, tell the user to correct it
If CheckForEmpty = False Then
MsgBox "Please fill out red boxes!"
End If
End Function
In this line, change to be explicit that you're looking for the value:
If Not IsNull(ctrl) Or Len(ctrl) <> 0 Then
change to:
If (Not IsNull(ctrl.Value)) OR (Len(ctl.Value & "") <> 0) Then
First, I added the .Value qualifier to the control. This is the default property, but sometimes (when assigning to a variant or checking null, for example), it might be checking that the Control itself is null because VBA isn't always smart enough to read your thoughts and you're technically telling it to check the control, and not it's value: be explicit.
Second, I explicitly split the two checks into two separate checks using parentheses. Not sure it's strictly required, but best to be clear and far easier to read and now we don't have to worry about the fact that it maybe was reading the boolean logic incorrectly.
Third, I added a ZLS concatenation to .Value to force it to ZLS if null before checking the length (you get an 'Invalid Use of Null' error if trying to check the Len() of a null value).
As Tom mentions, in this case ctrl will never be null (as it's part of the form's collection, which won't have null references in it), so the whole thing can be simplified to:
If Len(ctrl.Value & "") <> 0 Then 'ctrl has no value entered
Lastly, wrap it up in a Trim() function just in case there's a single (or double, or more) space in there, and you have:
If Len(Trim(ctrl.Value & "")) <> 0 Then 'ctrl has no meaningful value entered
I have a combo box (Status) which includes the following:
Shortage
Allocated
Actioned
Acknowledged
Complete
I also have 5 other date fields which are as follows:
Shortage_date
Allocated_date
Actioned_date
Acknowledged_date
Complete_date
However I want this status to be populated automatically based on what data has been entered in my previous fields.
For example, once shortage_date has been populated with a valid date (00/00/0000) I want the "status" to change to "shortage".
Once allocated_date has been populated with a valid date (00/00/0000) I want the "status" to change to "allocated".
I saw this bit of code online but I'm totally confused:
Private Sub Textbox1_AfterUpdate()
If Textbox1.Value = "1" Then
Textbox2.Value = "10"
End If
End Sub
I believe mine should look something like this but I dont know what I need to make sure it validates the date.
Private Sub shortage_date_AfterUpdate()
If shortage_date.Value = "(I want to valididate the date here)" Then
Status.Value = "Status"
End If
End Sub
Hope I make sense!
Firstly, I would set up an Input Mask on the field itself. You can do that by putting the form into design view, then select the field, then go the Property Sheet which isAlt+Enter if it isn't open, then select the Data tab and set up a Input Mask. That will handle your validation part so you don't have to in code.
Then you should be able to just use the code:
Private Sub shortage_date_AfterUpdate()
If Nz(shortage_date.Value, "") <> "" Then
Status.Value = "Status"
End If
End Sub
The If statement is just to make sure that it doesn't reset the value back to the original every time the date is changed. Also here is link where you can read about Input Masks: https://msdn.microsoft.com/en-us/library/office/ff821336.aspx
Update: Changed to Input Mask instead of Validation Rule