Record navigation on a form - ms-access

So I have been tasked with creating a tracking database & I am having an issue which is driving me crazy.
I have created an input form and for ease of use I need to create custom navigation buttons, again I have completed this and they work fine.
I have added code to the current event to disable the buttons if at the first record / last record - again this works fine.
This is where I have gotten stuck, as soon as I disable the built in navigation buttons it disables the custom buttons I have created. If I remove the current event code, again they work but not how I intend.
I would appreciate any help you could provide as I am still new to learning Access & I am sure this is a simple fix & something I am not doing correct - but I just cannot figure it out, I have included my code below.
Thank you in advance for your assistance.
Option Compare Database
Option Explicit
Private Sub cmdBack_Click()
On Error Resume Next
DoCmd.GoToRecord , , acPrevious
End Sub
Private Sub cmdNew_Click()
On Error Resume Next
DoCmd.GoToRecord , , acNewRec
End Sub
Private Sub cmdNext_Click()
On Error Resume Next
DoCmd.GoToRecord , , acNext
End Sub
Private Sub Form_Current()
On Error Resume Next
If Me.CurrentRecord = 1 Then
Me.cmdBack.Enabled = False
Else
Me.cmdBack.Enabled = True
End If
If Me.CurrentRecord >= Me.Recordset.RecordCount Then
Me.cmdNext.Enabled = False
Else
Me.cmdNext.Enabled = True
End If
If Me.NewRecord Then
Me.cmdNew.Enabled = False
Else
Me.cmdNew.Enabled = True
End If
End Sub

You can replace your DoCmd. calls with navigation using the form recordset.
Me.Recordset.MoveNext 'alternative to DoCmd.GoToRecord , , acNext
Me.RecordSet.MovePrevious 'alternative to DoCmd.GoToRecord , , acPrevious
Me.RecordSet.AddNew 'alternative to DoCmd.GoToRecord , , acNewRec

Thank you very much for the updated code - I had to add the following line to get them to work as I intented though.
Me.RecordsetClone.MoveLast

Related

Next Button that cycles back to first on Access Form

I've been trying a couple things to create a button that navigates back to the first record you are at the last record. I get the "can't go to specified record" error. Here are the two styles of code I have tried for this button:
Private Sub Command161_Click()
On Error Resume Next
If Me.CurrentRecord = acLast Then
DoCmd.GoToRecord , , acFirst
Else
DoCmd.GoToRecord , , acNext
End If
End Sub
Private Sub Command161_Click()
With Me.Recordset
If .AbsolutePosition = .RecordCount - 1 Then
DoCmd.GoToRecord , , acFirst
Else
DoCmd.GoToRecord , , acNext
End If
End With
End Sub
The goal is to loop back around to the first record without allowing the user to create a new record. I've tried this code with "allow additions" set to both yes and now, with the same result. Any help would be appreciated.
I would suggest defining a private predicate function within your form module which returns a boolean value depending on whether or not the active form is displaying the last record in its Record Source.
Such a function might be written:
Private Function LastRecordP() As Boolean
With Me.RecordsetClone
If Not .EOF Then
.MoveLast
.MoveFirst
LastRecordP = Me.CurrentRecord = .RecordCount
End If
End With
End Function
Your OnClick event handler for your button control could then be written more succinctly as:
Private Sub Command161_Click()
If LastRecordP Then
DoCmd.GoToRecord , , acFirst
Else
DoCmd.GoToRecord , , acNext
End If
End Sub
Alternatively, you could allow the function to accept a Form object as an argument and evaluate such function using the Me keyword, e.g.:
Private Function LastRecordP(Frm As Form) As Boolean
With Frm.RecordsetClone
If Not .EOF Then
.MoveLast
.MoveFirst
LastRecordP = Frm.CurrentRecord = .RecordCount
End If
End With
End Function
Private Sub Command20_Click()
If LastRecordP(Me) Then
DoCmd.GoToRecord , , acFirst
Else
DoCmd.GoToRecord , , acNext
End If
End Sub

Automatically Close Form After Certain Idle Time

I am having a little bit problem on my access form.
I have 2 forms:
menu-form
input-form
After input-form has been idle for one minute, I want to close it and go back to the menu-form.
This is my code that isn't working.
Public ExpireTime As Date 'expiration time-date value
Sub ResetExpiration()
If ExpireTime <> 0 And ExpireTime > Now Then
Application.OnTime ExpireTime, "FormExpire", schedule:=False
End If
ExpireTime = Now + 1 / 1440#
Application.OnTime ExpireTime, "FormExpire", schedule:=True
End Sub
I also created a macro with this in it.
Sub FormExpire()
Unload input-form
End Sub
You need to set the form.Timer to 60000 (that is 1 minute) then use on OnTimer event to check if some properties have changed. Below I quickly wrote something to give you an idea, but it is not complete nor tested.
Option Compare Database
Option Explicit
Dim isIdle As Boolean
Private Sub Form_LostFocus()
'you can use this event also
End Sub
Private Sub Form_Timer()
Dim ctlName As String, wasDirty As Boolean
If ctlName = vbNullString Then ctlName = Me.ActiveControl.Name
If Me.ActiveControl <> ctlName Then isIdle = False
If wasDirty <> Me.Dirty Then isIdle = False
'more checks....
If isIdle Then DoCmd.Close acForm, Me.Name
End Sub
You've got a couple of potential issues here.
First and foremost, that's not how you close a form.
This:
Sub FormExpire()
Unload input-form
End Sub
Should look something more like this:
Sub FormExpire()
DoCmd.Close acform, Me.Name
DoCmd.OpenForm "menu-form"
End Sub
Your second issue is that I don't believe the Application.Ontime method is available from Access. MSDN says it's an Excel function, and I can't find it in the Access Documentation. I'd personally be interested in seeing you make your method work with the Access form Timer Event.
I'm not sure it matters, but I think this is what you were trying to do.
Public ExpireTime As Date 'expiration time-date value
Private Sub InputForm_Timer()
If ExpireTime <> 0 And ExpireTime > Now Then
Call FormExpired
Else
' reset timer
ExpireTime = Now + 1 / 1440#
End If
End Sub
I'm not sure this method would work without also including #iDevelop's answer. I just wanted to help clarify where you were going wrong.
I realize that this thread is aged but I recently experienced a need to close forms from a timer event and came across the answers here. My situation was slightly different as I had several forms to close so here is my solution.
Private Sub Form_Timer()
Dim daysRemaining As Integer
Dim endDate As Date
endDate = "4/15/2021"
daysRemaining = DateDiff("d", Now, endDate)
MsgBox ("This is an evaluation version of the application. You have " & Str(daysRemaining) & " days of use remaining")
If daysRemaining < 1 Then
Close_All
End If
End Sub
Private Sub Close_All()
For Each myForm In CurrentProject.AllForms
strFormName = myForm.name
DoCmd.Close acForm, strFormName
Next
End Sub

Private Sub Form_Open(Cancel as Integer)

I have a main form with all of the selection criteria. If someone selects a year, like 2015, inadvertantly, there is NO data in the SQL Server for that year. When a button is pushed to open a subsequent Form, it will produce a Run_Time Error 2105. What would I need to add to the following code to alleviate the aforementioned error:
Private Sub Form_Open(Cancel As Integer)
Me.AllowEdits = True
DoCmd.GoToRecord , , acFirst
End Sub
Something along the lines of
'test for numeric
If IsNumeric(UserForm1.ComboBox1.Value) Then
'convert to long before comparing to year
If CLng(UserForm1.ComboBox1.Value) <= Year(Now) Then
DoCmd.GoToRecord , , acFirst
End If
End If

Open a form to a specific tab

When a button is pressed I want to open a form at a specific tab.
on click event I have:
DoCmd.OpenForm "MAIN_USER_FORM", acNormal, , "App_Ref = " & Me.App_Ref, , , "PRB"
On the open event of the form I have:
If Me.OpenArgs = "PRB" Then
Me.PRB_Validation.SetFocus
End If
PRB_Validation is the name of the tab in the MAIN_USER_FORM I wish to open.
I've searched forms, I just can't get it to work any help would be great.
Thanks in advance.
All you need is to check the OpenArgs in the form's OnLoad event, and set the TabCtontrol's value to the index of the page you want to show, like this:
Private Sub Form_Load()
If OpenArgs = "PRB" Then
TabCtl0.Value = PagePRB.PageIndex
End If
End Sub
I made an example accdb to show the complete setup.
In case if anyone is looking for code where you have a button on another form and want to open Main form from that and also take user to a particular Tab.
Private Sub YourButton_Click()
On Error GoTo Err_YourButton_Click
Dim stDocName As String
Dim stLinkCriteria As String
stDocName = "YourFormName"
DoCmd.OpenForm stDocName, , , stLinkCriteria
Forms![YourFormName]!YourPage.SetFocus
Exit_YourButton_Click:
Exit Sub
Err_YourButton_Click:
MsgBox Err.Description
Resume Exit_YourButton_Click
End Sub

Access: How can I display a new record in one form after creating in a second form

Access 2007: I have one form with 100s of records displayed. I have a second form for editing or creating new records. When I return to the first form after adding a new record, I do On Activate: Me.Requery so the new record is added to the list, but I would like it to display on the screen with the record selector on the new record. Is there a way to do this? I am assuming that I save the ID in a global variable, but not sure what to do next. Thanks.
RESPONSE:
Thanks //t. Your answer got me going in the right direction. I will post my solution, which I think is more of a work-around. There has to be a better solution, but this seems to work.
Form 1 (list) -> Form 2 (edit/new) and create new record.
Private Sub Form_Current ()
glngID = Me.ID.Value
End Sub
Private Sub Form_Close
gstrLastForm = "Form2"
End Sub
When I close Form 2, Form 1 is active.
Private lngSelectedRecord as Long
Private Sub Form_Activate()
Me.Requery
FindSelectedRecord
If gstrLastForm = "Form2" Then
DoCmd.GoToRecord acDataForm, "Form1", acGoTo, lngSelectedRecord
End If
End Sub
Private Sub FindSelectedRecord()
...
Open recordset, move through records, increment counter, exit when ID found
...
lngSelectedRecord = intCounter
...
End Sub
This is usually done with a form opened in dialog mode. In most cases, you'd have a command button on your main form ADD NEW RECORD, that when clicked would run code like this:
DoCmd.OpenForm "MyAddForm", , , , acFormAdd, acDialog
This opens the form you use for adding a new record to a new, empty record, and pauses the code.
However, you need to know the PK of the record that was added, so you can't just close the form and let the code continue. So, the usual practice is to set the dialog form's Visible property to False, get the data out of it that you need, then close it and do what you want:
Dim lngPK As Long
DoCmd.OpenForm "MyAddForm", , , , acFormAdd, acDialog
If Forms!MyAddForm.Tag <> "Cancel" Then
lngPK = Forms!MyAddForm!PK
Application.Echo False
Me.Requery
With Me.RecordsetClone
.FindFirst "[PK]=" & lngPK
If Not .NoMatch Then
If Me.Dirty Then
Me.Dirty = False
End If
Me.Bookmark = .Bookmark
End If
End With
Application.Echo True
End If
DoCmd.Close acForm, "MyAddForm"
In the dialog form, you have to hide the default window controls so the user can't close it. Instead, have two command buttons SAVE and CANCEL. The SAVE button does this:
If Me.Dirty Then
Me.Dirty = False
End If.
Me.Visible = False
...and the CANCEL button does this:
Me.Undo
Me.Tag = "Cancel"
Me.Visible = False
The result is that you know that a record was not saved so you don't want to do anything to the calling form.
This is all standard Access user interface design, and it's by far the easiest and most bulletproof method for doing this kind of thing.
Use the on_close-method in your popup window to go to the inserted record,
something like:
private sub on_close()
'maby first check we're not undoing..
docmd.gotoRecord yourform,yournewid
me.close
(on osx currently, but I hope you get the concept...)