Access VBA - AfterUpdate() Recordset edit leads to "No current Record 3021" even if Record exists - vba

I have an issue where I was not able to find a solution by tinkering and searching similiar problems already solved on the web.
First:
Im'using a form to enter a component ID (CID). After entering the Number in the Field I'm making use of the AfterUpdate() function to use the CID to look up a corresponding Prod ID in another Table. The Matching Prod ID from the other Table will then be entered automaticaly into the field. The field is a multivalued Field.
Here is the code:
Private Sub Form_AfterUpdate()
Dim rst As DAO.Recordset
Dim rstChld As DAO.Recordset2
Dim tmpVar
If Me.Dirty Then
Me.Dirty = False
End If
If StrComp(Me.Part, "Device") = 0 Then
tmpVar = DLookup("[Device Prod]", "subLookTblCIDDevice", "[CID Device] = '" & Me.CIDDevice & "'")
Set rst = Me.Recordset
If Me.Recordset.RecordCount = 0 Then
rst.MoveFirst
End If
If Not (rst.BOF And rst.EOF) Then
If rst.Updatable Then
rst.Edit
Set rstChld = rst!Prod.Value
rstChld.AddNew
rstChld.Fields(0) = tmpVar
rstChld.Update
rst.Update
Me.Bookmark = rst.LastModified
Set rst = Nothing
Set rstChld = Nothing
End If
End If
End If
End Sub
If the record exists and im Changing the CID - Everything is working fine the corresponding field gets its correct coresponding ID.
But if it is a new Record and the first of the recordset I got the error message
No Current Record - 3021
It can be mitigated by adding
If Me.Recordset.RecordCount = 0 Then
rst.MoveFirst
End If
But if its a new Record and not the first record it changes the previous record.
I have tried to use .AddNew instead of .Edit. This will create a new record after the one which has been updated.
I would be really glad if someone could have a look at it. I dont understand whats going on. why it is jumping before or after the record.
Thx and Cheers

Related

The changes you requested to the table were not successful because they would create duplicate values

So I have a database with two tables. There is a primary key in both tables, AccountID which has a relationship.Image1 Image2Image3
DonationsTable HOAFeesTable(All the entries on the HOAFees table are just test entries, the data entered aren't important)
I have a form that adds records to the HOAFees table. The code on the form is designed to find if an AccountID exists in the table already and if it does it edits the record. If the ID is not on the table already, it should add the record.
`
Option Compare Database
Private Sub btnAddRecord_Click()
'Declare variables
Dim db As DAO.Database
Dim rst As Recordset
Dim intID As Integer
'Set the current database
Set db = Application.CurrentDb
'Set the recordset
Set rst = db.OpenRecordset("tblHOAFees", dbOpenDynaset)
'Set value for variable
intID = lstAccountID.Value
'Finds the Account ID selected on the form
With rst
rst.FindFirst "AccountID=" & intID
'If the record has not yet been added to the form adds a new record
If .NoMatch Then
rst.AddNew
rst!AccountID = intID
rst!HOAID = txtHOAID.Value
rst!Location = txtLocation.Value
rst!House = chkHouse.Value
rst!Rooms = txtRooms.Value
rst!SquareFeet = txtSquareFeet.Value
rst!HOAFees = txtHOAFees.Value
rst.Update
'If the Account ID is already in the form edits the record
Else
rst.Edit
rst!AccountID = intID
rst!HOAID = txtHOAID.Value
rst!Location = txtLocation.Value
rst!House = chkHouse.Value
rst!Rooms = txtRooms.Value
rst!SquareFeet = txtSquareFeet.Value
rst!HOAFees = txtHOAFees.Value
rst.Update
End If
End With
'Closes the recordset
rst.Close
Set rst = Nothing
Set db = Nothing
End Sub
`
It works without any issues when editing an existing record. But when I add a new record and then try to close the form I get this: ErrorImage The strange thing is though, when I click through all the errors and check the table. The new record is still added to the table despite it saying it can't save. How can I get this to stop coming up? Everything I keep finding is saying that an autonumber field is causing the error. But I don't have any auto number fields.
I've tried removing primary key from the HOAFees table, but it makes no difference. I need the primary key for the Donations table, so I can't change or have any duplicates on that.
If you don't have a problem with the error itself, and everything works fine, you just don't want the error message to appear, add code in the OnError event of the form, which checks if it's the error number you want to ignore.
Private Sub Form_Error(DataErr As Integer, Response As Integer)
Const ErrNumber = your_err_number
If DataErr = ErrNumber Then
Response = acDataErrContinue
End If
End Sub

Access add Record issue with autonumber

I'm having an issue with my code generating an autonumber for my UserID field.
I am trying to generate my UserID through VBA since Access's autonumber doesn't actually go sequentially.
For some reason my code will not fill in the Autonumber but instead UserID always ends up as 0 which is the default value. Not sure what I'm missing.
Any help would be greatly appreciated!!
Private Sub RegistrationBtn_Click()
Dim db As Database
Dim rst As DAO.Recordset
Dim strMember As String
strMember = "" & Me!CallSign
Autonumber = Nz(DMax("[UserID]", "[Memberstbl]"), 0) + 1
If Len(strMember) = 0 Then Exit Sub
Set db = CurrentDb
Set rst = db.OpenRecordset("Memberstbl", dbOpenDynaset)
With rst
.FindFirst "CallSign = '" & strMember & "'"
If .NoMatch Then
.AddNew
!UserID = Autonumber
!CallSign = strMember
MsgBox "Welcome to the UNCC"
DoCmd.OpenForm "Logonfrm"
DoCmd.Close acForm, "Registration"
Else
MsgBox "That Call Sign is already in use!"
End If
.Close
End With
Set rst = Nothing
Set db = Nothing
End Sub
I think that the problem that you are having is that you don't finish the adding of the record using .Update. Try:
If .NoMatch Then
.AddNew
!UserID = Autonumber
!CallSign = strMember
.Update 'Needed to "commit" the adding of the new record
Ok, lets back the truck up here a bit.
User enters a call sign.
Check if call sign exists - if yes, then don't proceed.
If call sign does not exist, generate new number AND ALSO NEW record.
Then launch form to the NEW record for additonal information to fill out.
In other words, we can't, and don't launch the 2nd form in "add mode", else you get two records (that explains your other issue - two records). So we can't and don't want to launch the 2nd form to a new record, since we ARE going to assume we created that record already, right??
so, first bit of code - check for existing call sign - lets do that 100% separate and not attempt to combine that operation if we have a green light to add the call sign record (along with a new generated number).
So, first bit of code should look like this:
Dim strTable As String
Dim strMember As String
strTable = "Memberstbl"
If Nz(Me.CallSign, "") = "" Then
MsgBox "Please enter a call sign", vbCritical, "Enter Call sign"
Exit Sub
End If
' get here, user entered a call sign.
' check if exists.
Dim strWhere As String
strWhere = "CallSign = '" & Me.CallSign & "'"
If Nz(DLookup("CallSign", strTable, strWhere), "") <> "" Then
MsgBox "That call sign is already in use, try another", vbInformation, "In use"
Exit Sub
End If
' if we reach here, then user entered a call sign, and it not in use.
' create new reocrd, new UserID, and then launch form to this record.
Dim NewUserID As Long
NewUserID = Nz(DMax("UserID", strTable), 0) + 1
Dim rstMember As DAO.Recordset
Set rstMember = CurrentDb.OpenRecordset(strTable)
With rstMember
.AddNew
!UserId = NewUserID
!CalSign = Me.CallSign
.Update
.Close
End With
' now launch form to this new record
DoCmd.OpenForm "Logonfrm", , , "UserID = " & NewUserID
DoCmd.Close acForm, Me.Name
Do make sure that Logonfrm is set with data entry = "no".
(if you set yes, then the form can ONLY add records - but we already did that in code).
see June 7th's comments but if you want to continue try these things. Make sure UserID is not still an autonumber and make sure that UserID has the same datatype as the foreign key. I've seen both those cases. Then make sure UserID is still the primary key for the UsersTable. At that point you can set up relationships but there are issues with cascading updates. My copy of Access 2016 refused to cascade updates but would allow cascading deletes. I can't see any problems with this except for the error message as access already makes changing primary keys difficult. see here: https://support.microsoft.com/en-us/office/guide-to-table-relationships-30446197-4fbe-457b-b992-2f6fb812b58f#:~:text=When%20you%20enforce%20referential%20integrity,that%20reference%20the%20primary%20key.

Form event procedure not moving to last record

I am experiencing some odd behavior from a form I am creating in an access database. I have a form called frmSeedling with a subform called frmSeedling detail. frmSeedling gets launched by an event procedure from a command button on a separate form called frmTransect. The OpenArgs passes the primary key of frmTransect called Transect_OID to frmSeedling. Transect_OID is the link field between frmSeedling and frmSeedlingDetail. I have a Form_Current event procedure in frmSeedling to count the number of unique entries on frmSeedling, and create a custom unique id called Seedling_OID. The tables that are the record source for these forms are linked ODBC tables. Below is the code:
Private Sub Form_Current()
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
If Not (rs.EOF) Then
rs.MoveLast
End If
Set rs = Nothing
If IsNull(Seedling_OID) Then
Entry_No = Nz(DCount("Seedling_OID", "rd_Seedling", "Transect_OID = '" & Me.Transect_OID & "'"), 0) + 1
Seedling_OID = Transect_OID & "SD" & Entry_No
End If
End Sub
However, when I launch frmSeedling from frmTransect, I get an error saying I am trying to overwrite the primary key. When I look at the form, this is happening because somehow Access is try to create a new record at the beginning of the form instead of the end of the form, thus thinking that the unique Id I have: created has already been used. Here is a screenshot to show what I mean:
What is curious is that with a separate form called frmDWD with subform frmDWDdetail, I have used this exact setup and it worked fine. Here is the code from frmDWDdetail:
Private Sub Form_Current()
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
If Not (rs.EOF) Then
rs.MoveLast
End If
Set rs = Nothing
If IsNull(DWD_OID) Then
DWD_Piece = Nz(DCount("DWD_OID", "rd_DWD", "Transect_OID = '" & Me.Transect_OID & "'"), 0) + 1
DWD_OID = Transect_OID & "W" & DWD_Piece
End If
End Sub
And here is what that looks like:
Notice how in frmDWD, the record being edited is the last record in the form, while in frmSeedling it is trying to edit the first record in the form. I have set all of the data properties exactly the same in both form and subform, and at least to my eye the code looks identical. Any SQL reasons why I am getting this behavior? Any ideas for fixes? Thanks!!
After hours of playing "Which-of-these-things-is-not-like-the-other" I discovered that the issue was in the property sheet of the subform. I switched "Filter on Empty Master" from "Yes" to "No" and that solved my issue.
You are not using the recordset for anything, so try this reduced code:
Private Sub Form_Current()
Dim Entry_No As Long
If IsNull(Me!Seedling_OID.Value) Then
Entry_No = Nz(DCount("*", "rd_Seedling", "Transect_OID = '" & Me!Transect_OID.Value & "'"), 0) + 1
Me!Seedling_OID.Value = Me!Transect_OID.Value & "SD" & Entry_No
End If
End Sub

Create a new record from existing one with changes to two fields in Access dB [duplicate]

Background:
I have a subform (datasheet) I update using a datasheet checkbox afterupdate event:
I clone the clicked record & Insert into the referenced table via an Insert Query
I modify the original record to differentiate from the Inserted record via an Update Query
To avoid RecordLock complaints, I have inserted: SendKeys "+{Enter}", True after each of the above to save the updates - is there a better way to do this??
Next I need to requery the subform to display the newly inserted record AND use a bookmark (?) to retain the cursor position of the original record (inserted record will be adjacent). Subform datasheet recordset is based on a query.
Question:
From within the subform's afterupdate event, using Forms![ParentForm].[SubForm].Form.Requery does not produce an error, but does open the code window with the line highlighted in Yellow.
Next attempt, from within the subform's afterupdate event, I have attempted to set focus to a control on the ParentForm BEFORE using Forms![ParentForm].[SubForm].Form.Requery, but I get a similar ~silent error~ as noted above.
What is the proper way to REQUERY a subform from within the same subform?
Thanks!
You are making it way too hard for yourself. Here is how to copy a record from a button click. No locks, no queries, and auto update of the form:
Private Sub btnCopy_Click()
Dim rstSource As DAO.Recordset
Dim rstInsert As DAO.Recordset
Dim fld As DAO.Field
If Me.NewRecord = True Then Exit Sub
Set rstInsert = Me.RecordsetClone
Set rstSource = rstInsert.Clone
With rstSource
If .RecordCount > 0 Then
' Go to the current record.
.Bookmark = Me.Bookmark
With rstInsert
.AddNew
For Each fld In rstSource.Fields
With fld
If .Attributes And dbAutoIncrField Then
' Skip Autonumber or GUID field.
ElseIf .Name = "SomeFieldToHandle" Then
rstInsert.Fields(.Name).Value = SomeSpecialValue
ElseIf .Name = "SomeOtherFieldToHandle" Then
rstInsert.Fields(.Name).Value = SomeOtherSpecialValue
ElseIf .Name = "SomeFieldToSkip" Then
' Leave empty or with default value.
ElseIf .Name = "SomeFieldToBlank" Then
rstInsert.Fields(.Name).Value = Null
Else
' Copy field content.
rstInsert.Fields(.Name).Value = .Value
End If
End With
Next
.Update
' Go to the new record and sync form.
.MoveLast
Me.Bookmark = .Bookmark
.Close
End With
End If
.Close
End With
Set rstInsert = Nothing
Set rstSource = Nothing
End Sub
If the button is placed on the parent form, replace Me with:
Me!NameOfYourSubformControl.Form
Between AddNew and Update you can modify and insert code to adjust the value of some fields that should not just be copied.

Query error on a recordset.update vba line

I am trying to print multiple labels for multiple records. The number of labels is consistent for any one run of the label report and all labels for the same record need to be together on the printed sheet. Parameters are entered on TakeNoticeForm and once a button is clicked a recordset, rsQuery, is created with TakeNoticeLabelQuery. Another recordset is created, rsTable, based on a table, TemporaryTNLabels. This table is a copy of my main table, Certificates, without data. I'm using nested For loops to parse through the query results and add "x" copies of said record into the temp table, which will then be used to print the labels. Once the labels are printed the data will be cleared from the temp table for use again later.
Everything I have so far appears to work until I actually start adding data to my temp table. I get Error 3991 - "The query failed to execute because the identifier '[Certificates].[TownshipID]' could not be found" and it points to .Update. [TownshipID] is a lookup field in the Certificates table that was the original for TemporaryTNLabels. I tried to keep the copy intact for possible reuse with other reports but I don't need that field for this report so deleted the lookup field from the temp table to hopefully solve the problem. TakeNoticeLabelQuery is actually a copy of another query, TakeNoticeQuery, that did reference Township information. Again, I was hoping to reuse objects but made a copy and only kept what I needed, which has no reference to TownshipID.
After stripping everything unnecessary away, I can't figure out why it's still trying to find [TownshipID]. I'm still trying to wrap my head around recordsets so wondering if the problem is actually elsewhere, buty I'm confused as to how this error is even remotely related to my code. Any help is appreciated. The SQL for the query and code for generating label data are below.
SELECT Certificates.DatabaseID, Certificates.CertCounty, Certificates.TaxYear, Certificates.ParcelNumber, Certificates.MailToFirstName, Certificates.MailToLastName, Certificates.MailToAlso, Certificates.MailToCity, Certificates.MailToState, Certificates.MailToZip
FROM Counties INNER JOIN Certificates ON Counties.ID = Certificates.CertCounty
WHERE (((Certificates.DatabaseID) Between ([Forms]![TakeNoticeForm]![FirstDBTextbox]) And ([Forms]![TakeNoticeForm]![LastDBTextbox])) AND ((Certificates.CertCounty) Like [Forms]![TakeNoticeForm]![CountyCombobox] & '*') AND ((Certificates.TaxYear) Like [Forms]![TakeNoticeForm]![TaxYearTextbox] & '*')) OR (((Certificates.CertCounty) Like [Forms]![TakeNoticeForm]![CountyCombobox] & '*') AND ((Certificates.TaxYear) Like [Forms]![TakeNoticeForm]![TaxYearTextbox] & '*') AND ((IsNull([Forms]![TakeNoticeForm]![FirstDBTextbox]))<>False) AND ((IsNull([Forms]![TakeNoticeForm]![LastDBTextbox]))<>False));
Option Compare Database
Option Explicit
Private Sub TNLabelPreviewButton_Click()
Dim iTab As Integer
Dim iLabel As Integer
Dim numLabels As Integer
Dim totalRecords As Long
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rsTable As DAO.Recordset
Dim rsQuery As DAO.Recordset
' Set query definition for creating recordset
Set db = CurrentDb()
Set qdf = db.QueryDefs("TakeNoticeLabelQuery")
If CurrentProject.AllForms("TakeNoticeForm").IsLoaded Then
qdf.Parameters("[Forms]![TakeNoticeForm]![FirstDBTextbox]") = [Forms]![TakeNoticeForm]![FirstDBTextbox]
qdf.Parameters("[Forms]![TakeNoticeForm]![LastDBTextbox]") = [Forms]![TakeNoticeForm]![LastDBTextbox]
qdf.Parameters("[Forms]![TakeNoticeForm]![CountyCombobox]") = [Forms]![TakeNoticeForm]![CountyCombobox]
qdf.Parameters("[Forms]![TakeNoticeForm]![TaxYearTextbox]") = [Forms]![TakeNoticeForm]![TaxYearTextbox]
' qdf.Parameters("[Forms]![TakeNoticeForm]![TakeNoticeDateTextbox]") = [Forms]![TakeNoticeForm]![TakeNoticeDateTextbox]
Else
qdf.Parameters("[Forms]![TakeNoticeForm]![FirstDBTextbox]") = ""
qdf.Parameters("[Forms]![TakeNoticeForm]![LastDBTextbox]") = ""
qdf.Parameters("[Forms]![TakeNoticeForm]![CountyCombobox]") = ""
qdf.Parameters("[Forms]![TakeNoticeForm]![TaxYearTextbox]") = ""
' qdf.Parameters("[Forms]![TakeNoticeForm]![TakeNoticeDateTextbox]") = CStr(Date)
End If
Set rsQuery = qdf.OpenRecordset
rsQuery.MoveLast
totalRecords = rsQuery.RecordCount
'Close and delete records from TemporaryTNLabels table.
DoCmd.SetWarnings False
DoCmd.Close acTable, "TemporaryTNLabels"
DoCmd.RunSQL "DELETE FROM [TemporaryTNLabels]"
DoCmd.SetWarnings True
numLabels = Me.NumLabelsTextbox
MsgBox numLabels & " labels"
'Open a table-type Recordset
Set rsTable = db.OpenRecordset("TemporaryTNLabels", dbOpenTable)
rsQuery.MoveFirst
With rsTable
For iTab = 1 To totalRecords
For iLabel = 1 To numLabels
Debug.Print rsQuery!DatabaseID
.AddNew
!ParcelNumber = rsQuery!ParcelNumber
.Update ' <-------------------------This is where the error points.
.Bookmark = .LastModified
Next iLabel
rsQuery.MoveNext
Next iTab
End With
' DoCmd.OpenReport ReportName:="TakeNoticeLabelReport", View:=acViewPreview
rsTable.Close
Set rsQuery = Nothing
Set qdf = Nothing
Set db = Nothing
End Sub
This is why I stopped using lookup fields :-( I would delete the table TemporaryTNLabels or rename it to TemporaryTNLabels_OLD. Then recreate the table TemporaryTNLabels from scratch with only one field ParcelNumber, and start from there.