MS Word Document Form - Check Value of Text Form Field on Exit - vba

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

Related

How to access Form.Textbox.Text property when the source query returns no results?

I am making a continuous form for searching that self-updates as the user types in multiple search boxes.
The code works up until the user types in parameters that don't correspond to any records.
The query then can't find anything and I get the error
"Can't use the property or method when the control doesn't have the focus"
I could not figure out what element of the form is doing it. Adding the .SetFocus to the textbox control didn't help.
Any ideas on how to either
Set focus to the textbox again and prevent it from being lost, or
Figure out what is stealing the focus and disable it?
The following sub is called in the textbox_Change sub. I added a workaround.:
Private Sub RefreshTB(textbox As Control)
'This is to prevent Acces from removing trailing spaces
'If the textbox isn't empty and there is a space at the end, don't requery. This preserves trailing spaces as Access trims them on Me.requery
If Len(textbox.Text) <> 0 And InStr(Len(textbox.Text), textbox.Text, " ", vbTextCompare) Then
Exit Sub
End If
'If the last character isn't a space, requery on change to show new results of the query
Me.Requery
'The workaround: If the query returns no results, detect that, warn the user and clear search box. Requery to show some results again.
If DCount("*", "DatasetsFilterQ") = 0 Then
If MsgBox("No results found. The last TextBox you searched in will be cleared.", vbOKOnly, "No Records") = vbOK Then
textbox = ""
Me.Requery
End If
Exit Sub
End If
textbox.SetFocus
textbox.SelStart = Len(Nz(textbox.Text))
End Sub
I tried a filter but ran into the same error when passing .text value to the function.
You can't set SelStart to Null, so avoid that with Nz:
textbox.SelStart = Len(Nz(textbox.Value))

Access and VBA - default value of field is null?

I'm making a form with Microsoft Access and I'm trying to make an AfterUpdate event procedure for a field. I need to know if the value of that field is the default value (or if it's empy). I read that the default value of a field in VBA is Null so I made this:
Private Sub EB1_10_Val1_AfterUpdate()
If Me.EB1_10_Val1.Value = Null Then
MsgBox "hello"
End If
End Sub
This didn't work so I tried this for when the user updates the value in the field and then erases it (empties the field)
Private Sub EB1_10_Val1_AfterUpdate()
If Me.EB1_10_Val1.Value = Empty Then
MsgBox "hello"
End If
End Sub
The messages never pop up. On the other hand I tried changing the default value of the field to 0 but Its not working. The 0 doesn't appear in the field as default when in Form View.
You can check if the field is empty with this expression:
If IsNull(Me.EB1_10_Val1.Value) Then
In addition to solution provided by mielk, you can use Nz or Iif function to replace Null with default value.
Usage:
myVal = Nz(Me.SomTextBox, 0)

Access 2013 - Set a field value based on value of another field

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

Changing Textbox.DefaultValue in Access

I would like to be able to change the Textbox.DefaultValue during the 'On Load' event of a form such that each time the form is loaded the user is prompted with an InputBox to change a specific TextBox.Default value which in my case the TextBox control on the table is called Stream. I have tried the following code but each time it gives me a
'RunTime Error 3422 Cannot modify table structure. Another user has
the table open'.
Private Sub Form_Load()
CurrentDb.TableDefs("Class 1 Students (C1)").Fields("Stream").DefaultValue = InputBox("Enter Stream Letter:")
End Sub
I am using Microsoft Access
As Doug Glancy said in a comment, don't change the field's default value in table design. Instead change the text box's default value.
This is a critical point in a multi-user database application --- you wouldn't want one user stomping on another's default value choice. But, even if this will always be a single-user application, changing the table design means you can't have the table open in the record source of your form.
Changing the text box default value is easy. I added an unbound text box, txtDefaultStream, to my form's header. And, in its after update event, I change Me.txtStream.DefaultValue. The code is below.
Here is a screenshot of that form in action. I had A as the default when entering the first 2 rows. Then entered B in the default stream text box. Notice the new record has B in its Stream text box.
Private Sub txtDefaultStream_AfterUpdate()
Dim strDefault As String
If Len(Trim(Me.txtDefaultStream & vbNullString)) > 0 Then
strDefault = """" & Me.txtDefaultStream.value & """"
Me.txtStream.DefaultValue = strDefault
Else
Me.txtStream.DefaultValue = vbNullString
End If
End Sub
As Doug Glancy said, use the textbox, so you should try
Private Sub Form_Load()
Me.AText.DefaultValue = "='S'"
End Sub

Weird Error: Hit ENTER key in listbox, get NULL error for bound recordset values

Access 2007 ADP/ADE.
I have a modal that is bound to a table. The modal has a single listbox control, and two buttons. One executes a subroutine of code that access values from the bound recordset, the other closes the modal.
Two methods of use:
Select a value in the listbox, and then click on the button to execute the subroutine, it works just fine.
Select a value in the listbox and then hit the ENTER
key on the keyboard twice, it attempts to execute the same
subroutine, but throws a NULL error the first time it tries to
access a value from the bound record.
So using method 1, a value like Me.RecordNumber will return 12345. Using Method 2, it will be NULL and error out. Interestingly enough, the selected value in the listbox itself is available using either method.
Not really a critical bug, but it is annoying. I have to teach folks to click buttons rather than just use the ENTER key on this particular modal. Has anyone seen this before? Any idea why values from a bound recordset are unavailable using method #2?
EDIT for clarification:
This error appears to be independent of any particular piece of VBA code. I've even created a new modal, bound a different table, and just tried to access a random datacolumn on that recordset. Same result.
Here is the snippet where the error appears. It errors out when attempting to grab the RecordType, a value that is never null.
Private Sub cmdAddFromTemplate_Click()
On Error GoTo Err_MyErrorHandler
Dim myTemplateName As String
Dim myDepartment As String
Dim i As Integer
'Did they provide a valid template name?
If Me.listTemplateToImport.ItemsSelected.Count > 0 Then
'Cycle through list and build criteria
For i = 0 To Me.listTemplateToImport.ListCount - 1
'Is this status selected?
If Me.listTemplateToImport.Selected(i) Then
'Grab selected template name
myTemplateName = Trim(Me.listTemplateToImport.ItemData(i))
End If
Next i
Else
'Warn and exit
MsgBox "You must select a valid template name.", vbOKOnly, "STEP: Action Canceled"
Exit Sub
End If
'Grab Bound Values
myDepartment = Me.RecordType 'NULL error here when using ENTER key.