Open Access form with pointer on record - vba

I have a form with a tabular subform and want to set the record pointer to be on a particular record (on or near current date) and this record highlighted.
Following code is used to set the pointer after the desired record is found:
DoCmd.RunCommand acCmdSelectRecord
Unfortunately, this works only when the form/subform is already open: then the record marker is highlighted as desired.
HOWEVER, when the same code is run from Form_current() upon opening the form, the code line runs (I checked this !) but has no effect at all: when the form displays, THE HIGHLIGHT IS ON THE FIRST FIELD (in the subform) !
Similarly, the attempt to deselect the field contents works only after the form is already open, but not upon opening the form :
With Forms![MyForm]![MySubform]![MyHighlightedField]
On Error Resume Next
.SelStart = 0
.SelLength = 0
On Error GoTo 0
End With
Is there any way to enforce the desired record marker to be highlighted on opening the form/subform ?

Related

Button to check for missing values in a MainForm and Subforms in MS Access

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!

How to handle Access "Run-Time Error 3021 - No current record" after DoCmd.Requery?

I have been having a quite annoying issue on my access project.
It is an Access 2007 - 2016 file.
My database has two queries that I intend to use to filter data to feed combo-boxes.
On one of my forms I have done that with success. The first list is fed from a table, and the succeeding ones are fed by filtering their respective table based on the previous list selection.
Here is a screenshot of my form that worked out.
And here is part of the code that goes with it:
Private Sub frm01ListSetor_Click()
DoCmd.Requery (qry01_frm01ListArea)
Me![frm01ListArea] = Null
DoCmd.Requery (qry02_frm01ListEquip)
Me![frm01ListEquip] = Null
Me![frm01TextID] = Null
End Sub
Private Sub frm01ListArea_Click()
DoCmd.Requery (qry02_frm01ListEquip)
Me![frm01ListEquip] = Null
Me![frm01TextID] = Null
End Sub
Here are the queries that goes along with the code above:
qry01_frm01ListArea
SELECT tblAreas.ID_Area, tblAreas.NomeArea
FROM tblAreas
WHERE (((tblAreas.SetorArea)=[Forms]![frm01_AddEquip]![frm01ListSetor]));
qry02_frm01ListEquip
SELECT tblEquipamentos.ID_Equipamento, tblEquipamentos.NomeEquipamento
FROM tblEquipamentos
WHERE (((tblEquipamentos.SetorEquipamento)=[Forms]![frm01_AddEquip]![frm01ListSetor]) AND ((tblEquipamentos.AreaEquipamento)=[Forms]![frm01_AddEquip]![frm01ListArea]))
ORDER BY tblEquipamentos.ID_Equipamento;
The code above works just fine. It filters data to previous selection accordingly and it also clears the data and selection of the "righter" lists every time another value is selected on the "lefter" ones.
So that was a form I created to help me out on populating my equipment database.
Let us get to the problematic twin now:
I created another form for Maintenance Orders of these equipment.
This one must be more user friendly since other people will use it. Therefore I used Combo-boxes for value selection instead of List Boxes. I say this before hand because it is the only thing I could notice that differs the new form from the one above.
Here I have this:
Screenshot of troubled form
After the expanded Combo-box on image 2 is selected I should run the following code:
Private Sub frm02SetorOM_Click()
DoCmd.Requery (qry04_frm02CBArea)
Me![frm02AreaOM] = Null
DoCmd.Requery (qry05_frm02CBEquip)
Me![frm02EquipamentoOM] = Null
End Sub
Private Sub frm02AreaOM_Change()
DoCmd.Requery (qry05_frm02CBEquip)
Me![frm02EquipamentoOM] = Null
End Sub
It is basically the very same thing I have done on the first form but with different variables.
But I get a "Run-time error 3021: No current record" every time I select a value on my "Setor" field.
The crash happens at the "DoCmd.Requery (qry04_frm02CBArea)" line.
Here is the query for this form's Area field (qry04_frm02CBArea):
SELECT tblAreas.ID_Area, tblAreas.NomeArea
FROM tblAreas
WHERE (((tblAreas.SetorArea)=[Forms]![frm02_SubmitOM]![frm02SetorOM]));
But the thing that is confusing me the most is that when I click "End" on the Run-time error dialog box, my Area combo-box - that was empty before - even with the error gets the proper options like if it actually "requeried".
How can I fix this issue?
Thank you in advance.
Btw, this is my first Access project so please consider that on the response.

Error appears, when event On Current is triggered

When I reference to subform error occurs. I have 1 main form and 2 subforms on the main one. One of subform has On Current event which trigger code:
Me.Parent![1ChildEquipFilter].Form.RecordSource = StrSQL
(it changes second subform's RecordSource)
When the main form is opened the first time, the error message appears
'you entered an expression that has an invalid reference to the property form/report'.
But when I click on the debug and then reset, all work properly. What's the matter?
When you open the form, first the two subforms are opened, then the main form, and then the two subforms again.
The simple workaround is to eat the error:
On Error Resume Next
Me.Parent![1ChildEquipFilter].Form.RecordSource = StrSQL
On Error GoTo 0

Can't set focus on my Subform in Access - error 2465 (can not find the field '|1' referred to in your expression)

Recently I am messing ( a lot) around with setting focus to my subform. For some reason I can't set the focus to my subform and it keeps giving me the error: can not find the field '|1' referred to in your expression I tried multiple ways to set the focus but all of them won't work.
What I tried so far:
Forms("frmArtikelSubInkoopHistorie").SetFocus (Set focus directly to the subform)
[Forms]![frmArtikelen].[frmArtikelSubInkoopHistorie].SetFocus (Set focus to the subform with reference to it's main form)
[Forms]![frmArtikelen].[frmArtikelSubInkoopHistorie].SetFocus
[Forms]![frmArtikelen].[frmArtikelSubInkoopHistorie].[Form].[Tekst33].SetFocus (First set focus to the subform itself and then setting focus to the subforms control)
First I tried to set the focus on the Load event of the main form but this caused the error as well.
Then I tried to set the focus in the load event of the subform itself but this event never gets fired.
Lastly I tried (and this is where I left off) to set the focus in the change event of my tab control (the subform resides in one of the tabs):
Private Sub TabbestEl91_Change()
On Error GoTo eri
Select Case TabbestEl91
Case 3 'Inkoop Historie
'Forms("frmArtikelSubInkoopHistorie").SetFocus
[Forms]![frmArtikelen].[frmArtikelSubInkoopHistorie].SetFocus
[Forms]![frmArtikelen].[frmArtikelSubInkoopHistorie].[Form].[Tekst33].SetFocus
End Select
eri:
MsgBox (Err.Number)
MsgBox (Err.description)
End Sub
I guess the focusing failing because the subform isn't loaded yet on the moment it sets the focus, this is just an assumption though and I thought this would be fixed if I would set the focus in the tab change (the subform should be loaded by then).
P.s. found multiple posts on this subject but non of them fixed my problem or were totally different than mine.
Any ideas to get this fixed? Thanks in advance!
I would try the following syntax:
Forms![frmArtikelen]![frmArtikelSubInkoopHistorie].Form![Tekst33].SetFocus
Note the exclamation marks that have been added. Also, it may sound counter intuitive but I believe that when a form loads, the subform loads before the mainform.
I don't understand at what point you actually want to apply the setfocus, in order to understand where the event should go.
Are you aware that you don't need VBA to select the tab index of the subform to 0? and then set the tab index within the subform so that tekst33 is 0?
I tried to set focus on my subform date after a new record is created.
Sequential code to set focus on the subform then the subform field might work for you:
from parent form setfocus on the subform first
Me.SF_DRL_Scheduling.SetFocus
then point to last record of the subform (even if filter is active)
DoCmd.GoToRecord , , acLast '
finally refer to the field in subform
Me.SF_DRL_Scheduling.Form.DrScDte.SetFocus
On Error Resume Next
'For second time doesn't run code below and raises error, so we need On Error Resume Next above. but with one more time else again run it code, there is ok runing all codes and process below
Me.frmArtikelSubInkoopHistorie.SetFocus
Forms![frmArtikelen]![frmArtikelSubInkoopHistorie].Form![Tekst33].SetFocus

How to set focus following setting Form Filter that returns zero records

I have a textbox control in the header of a continuous form. Characters entered are used to build and apply a filter string. Once the filter is applied the focus is set back to the textbox using set focus and selstart so the user is able to add more characters. The result is the list of records is filtered as each character is entered.
The set filter code is triggered by the textbox on change event. The code moves focus to another control and then back so that the textbox.value property is updated (I tried using .text but kept running into other focus issues).
The record filtering works until a string is entered that results in zero records being displayed.
At this point the line of VBA that sets the Selstart property throws
"you can't set a property of a control unless it has focus"
The lines of code are listed below, TxtFilterString is the name of the textbox, LengthOfText is an integer, SetFormFilter is a sub that builds the filter and applies it:
LengthOfText = Len(Me.TxtFilterString.Value)
SetFormFilter
Me.TxtFilterString.SetFocus
Me.TxtFilterString.SelStart = LengthOfText
It appears that the line Me.TxtFilterString.SetFocus fails when there are no records to display and this causes the following line to throw an error despite the control being visible in the header section.
I am assuming you have listbox displaying the results of your query.
If it errors when 0 records are displayed in the listbox then could you not put a simple check around the listbox results that doesn't run the line that errors?
if listbox.listcount >0 then
Me.TxtFilterString.SelStart = LengthOfText
endif
I have no idea why the problem occurs but my solution is to not execute the line of code if the record set is empty or the text box in question contains null which seems to happen if the contents are deleted using the delete key. My on change sub is here:
Private Sub TxtFilterString_Change()
' Call sub that sets the form filter to value entered in text box
Dim LengthOfText As Integer
On Error GoTo ErrHandler
Me.CmdResetSearch.SetFocus ' move the focus away to update the value prop, as the text prop has focus issues
Me.TxtFilterString.SetFocus
SetFormFilter ' build and set the continuous forms filter string
' The following if block is to overcome a bug where Access does not allow the
' set focus property of the text field to be set when there are no records to display
' The result is that the filter string that returns zero records becomes highlighted
' allowing it to be overwritten.
' The IsNull clause is required if the user used delete to remove the text in the text box
If Me.Recordset.RecordCount = 0 Or IsNull(Me.TxtFilterString) Then
' There are no records or the user has deleted in the field (causing a Null to be enetered)
Me.TxtFilterString.SetFocus
Else
' There are records and there is text in the text box so set focus and caret position
Me.TxtFilterString.SetFocus
Me.TxtFilterString.SelStart = Len(Me.TxtFilterString.Value)
End If
Exit Sub
ErrHandler:
MsgBox "An error in TxtFilterString_change : " & Err.Description, vbExclamation
Exit Sub
End Sub