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

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.

Related

Getting a Run-time error 424 on command button click for MS Access VBA code

I created a button on an Access form that changes the value of column New_column to "YES" but I keep getting a run-time error 424 Object Required. Here's the code generating the error.
Private Sub Command1_Click()
New_column.Value = "YES"
End Sub
But if I simply change the column name to another one that accepts text (e.g., Old_column) I don't get the error.
Private Sub Command1_Click()
Old_column.Value = "YES"
End Sub
What is the difference between New_column and Old_column that would cause one to generate the error but not the other? Both are text fields that already contain text values. I compared the properties for both fields and didn't see any differences. I added New_column using an update query after some original VBA code was written, if that's a clue.

Using PreviousControl property with nested subforms and controls

I am creating a custom floating number pad so that tablet users can more easily tap numerical data into a form. I'm using toggle buttons (the idea is to eventually highlight them briefly). The following code for the number pad works on my main form's controls. When I click on the 1 button, then a 1 is put into the active control of the main form
Private Sub Form_Activate()
FocusForm = Application.Screen.PreviousControl.Parent.Name
FocusControl = Application.Screen.PreviousControl.Name
End Sub
Private Sub Toggle1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Add a 1 to the currently selected control
Dim refControl As Control
If FocusForm = "" Then End
Set refControl = Forms(FocusForm).Controls(FocusControl)
If (IsNull(refControl)) Then
refControl = "1"
Else
refControl.Text = refControl.Text & "1"
End If
refControl.SetFocus
End Sub
However, if I navigate into the subform then the Screen.PreviousControl properties return the main form's name and the subform's name, but I can't then seem to be able to refer to the subform control's name as well. Bascially I'm looking for a line that does the following
FocusForm = Application.Screen.PreviousControl.Parent.Name
FocusSubform = Application.Screen.PreviousControl.Name
FocusSubformControl = ?????
Similarly, my subform has its own nested subform and I would like to do the same with this
FocusForm = Application.Screen.PreviousControl.Parent.Name
FocusSubform = Application.Screen.PreviousControl.Name
FocusSubform2 = ?????
FocusSubform2Control = ?????
The in-built floating number pad on the tablets is very fiddly to use, hence my coding of this custom one, however if someone knows where I might find code for a customisable number pad that writes directly into whatever window is active, this would similarly be much appreciated!
If called from a subform,Screen.PreviousControlreturns the name of the mainforms subfom-control (as mainform needs to be active to get the subform control (nested in mainform) active), not the subform (but they can have same name, just change controls name and you won't get subforms name returned, but subforms control name!).
Now how to get previous control of the subform? By its.ActiveControlproperty, as form was active before, its active control must be the previous control. (if you want to get previous control, when you stay on the same subform, you need to store it in a module variable)
As there may be multiple subforms inside of subforms, we just loop while the control is a subform and set it to the next subform.ActiveControltill finished.
Why bother with names, if you can use references? This enables using multiple instances of a form.
Just store the reference to the control in Form_Activate and use it inMouseUp:
'On top of forms code module
Option Explicit
Private PreviousFormControl As Access.Control
Private Sub Form_Activate()
On Error Resume Next ' ignore error if no previous control availible
Set PreviousFormControl = Application.Screen.PreviousControl ' this stores the reference not the name!
If Err.Number <> 0 Then
'Handle error here, e.g. disable controls, show msg, ...
End If
On Error GoTo 0 'Reset error handler (not needed only to remind you not just to ignore all errors!
Do While TypeOf PreviousFormControl Is SubForm ' Loop till control is not subform
Set PreviousFormControl = PreviousFormControl.Form.ActiveControl ' if subform, previous control of it is its current ActiveControl
Loop
End Sub
Private Sub Toggle1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Add a 1 to the currently selected control
PreviousFormControl.Text = PreviousFormControl.Text & "1" ' concat "1" to controls text, no need to handle empty text as it can only be an vbNullString(""), even if Null, then Null & "1" => "" & "1" => "1"
PreviousFormControl.SetFocus
End Sub
however if someone knows where I might find code for a customisable number pad that writes directly into whatever window is active
Of course you can use any Virtual Keyboard running on windows that fit your needs. But then you may have to handle things like bring keyboard to front on wanted position.
numpad emulator was the first open source app I found on quick search, but looks goods on short test. Of course there may be better solutions out there, just search and test.

Suppress Error 3021: No Current Record in Access

I have an Access form with an attached recordset. Controls in the header adjust the recordset filters. Sometimes those filters return an empty recordset, which is OK.
However when the recordset is empty and the user clicks on any control in the header (let's say to change the filter again), Access pops up an error box with 3021 - No Current Record.
I've been unable to find the source of this error in the code - however I've added an event trigger on the form - onError for the form itself.
Private Sub Form_Error(DataErr As Integer, Response As Integer)
MsgBox "caught error: " & DataErr
End Sub
That works! But I had expected this sub to replace the Access error. Instead my code is executed and the original error message pops up after!
I know there are many questions about getting rid of this error but most are related to taking a VBA action - this is about removing the error when no other VBA is triggered. Is there a way to get the Form_Error sub to not show the popup?
The simple solution is to use the Response parameter in the Form Error event. Setting it to acDataErrContinue tells it to continue and ignore the error.
You can see more examples on the doc page.

Passing Data between two open forms

I know this has been answered many times over and I am actually using code that seems to be working but I can't seem to get the actually data to be presented in the receiving form.
In the sending form I am select an item in a tree menu which triggers an event to open the receiving form and then pass the data. I put a break point in my receiving code and can see the data is applied to the variable. I applied that variable to text box but it does not appear on the open form.
Here is the code from the sending form. I am first checking to see if the form is open. My variable that I am passing is a string strControl.
If Application.OpenForms.OfType(Of Guidance_Info).Any() Then
Dim f1 As New Guidance_Info()
Guidance_Info.LoadGuidance_Info(strControl)
Else
Dim f1 As New Guidance_Info()
Guidance_Info.LoadGuidance_Info(strControl)
f1.Show()
End If
Here is the code from the receiving form. I first apply the variable to the table adapter, then a text box and then a message box. The only item that presents the data is the message box. Using a breakpoint I can see that the variable is being passed to the both the text box and the table adapter.
Friend Sub LoadGuidance_Info(ByVal ControlID As String)
Me._800_53_CtrlTableAdapter.FillByControl(Me.AssessGuidanceDataSet1._800_53_Ctrl,
ControlID)
Me.lblControl.Text = ControlID
MsgBox(ControlID)
End Sub
As you can see from this image the variable is receive properly:
Friend sub LoadGuidance_Info
I also tried using f1.ShowDialog() instead of f1.Show() but got the same results. The problem with the Dialog, you can't use the sending form until you close the receiving form.
Any help would be appreciated:
Your problem has nothing to do with passing data, but what you are passing it to.
You look for an open form instance but whether you find one or not, you create a New form instance, pass the data to a default form instance, then show the (New) form instance you created. In the end you have as many as 3 instances of the same form:
' first instance may be in the collection
If Application.OpenForms.OfType(Of Guidance_Info).Any() Then
...similar issue to below
Else
' create a NEW instance (#2)
Dim f1 As New Guidance_Info()
' use/create a default instance
Guidance_Info.LoadGuidance_Info(strControl)
' show #2
f1.Show()
End If
Neither #2 nor #3 can ever be the one that may be showing. Rather than just checking the collection for an instance, get it and check that (using more idiomatic naming):
Dim f1 = Application.OpenForms.OfType(Of GuidanceInfo)().FirstOrDefault
If f1 IsNot Nothing Then
' use existing
f1.LoadInfo(strControl)
Else
' create, update, show one new form instance
f1 = New GuidanceInfo()
f1.LoadInfo(strControl)
f1.Show()
End If

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

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