When I want to save data then show this error massage.
Run Time error 3021
Either BOF or EOF is true, or the current record has been deleted. Requested operation requires a current record.

 With rs1
rs1.Open "Select * from debtordue where debtorname = '" & Me.cmbreceiver & "'", con, adOpenKeyset, adLockOptimistic
        .Fields("due") = rs1.Fields("due") - Val(Me.txtamount)
        !debtorname = cmbreceiver
        !payment = txtamount
        !By = cmbRcvIBy
        !Date = RcvDate
        .Update
        .Close
        MsgBox "Information is Saved", vbInformation, Me.Caption
         End With

Dani AI

Generated

Runtime error 3021 means there is no current record when an operation that requires one is attempted — typically BOF and EOF are both True because the SELECT returned zero rows or the record was deleted. In the posted snippet is opening a Recordset filtered by debtor name and then writing fields; if that SELECT finds nothing, any attempt to access .Fields or call .Update triggers 3021. See the ADO error reference and the BOF/EOF property notes for the formal explanation. (ADO error reference) (BOF, EOF properties (ADO)). (learn.microsoft.com)

Two practical, safe approaches avoid the error and are more robust than unguarded string concatenation. Either (A) test the Recordset before updating and call AddNew when no row exists, or (B) perform the change with a single parameterized SQL statement (UPDATE or INSERT) via the Connection or an ADODB.Command — that avoids opening an updatable Recordset and removes race conditions.

Example pattern (parameterized UPDATE with ADODB.Command):

' ADODB.Command pattern — adjust types/sizes for the provider
Dim cmd As New ADODB.Command
cmd.ActiveConnection = con
cmd.CommandText = "UPDATE debtordue SET due = due - ?, payment = ?, [By] = ?, [Date] = ? WHERE debtorname = ?"
cmd.CommandType = adCmdText

cmd.Parameters.Append cmd.CreateParameter("pAmount", adNumeric, adParamInput, , Val(Me.txtamount))
cmd.Parameters.Append cmd.CreateParameter("pPayment", adVarChar, adParamInput, 50, CStr(Me.txtamount))
cmd.Parameters.Append cmd.CreateParameter("pBy", adVarChar, adParamInput, 100, CStr(Me.cmbRcvIBy))
cmd.Parameters.Append cmd.CreateParameter("pDate", adDate, adParamInput, , CDate(RcvDate))
cmd.Parameters.Append cmd.CreateParameter("pDebtor", adVarChar, adParamInput, 255, CStr(Me.cmbreceiver))

cmd.Execute

If the intent is to create a new debtordue row when none exists, use Recordset.AddNew (set fields, then .Update) or issue an INSERT. See the AddNew example and the Connection.Execute/Command docs for details. (learn.microsoft.com)

Quick troubleshooting checklist (common root causes):

  • Verify the value coming from the combo box (bound column vs display text); use the bound value if that’s the key.
  • Test the SELECT or UPDATE SQL directly in the database engine to confirm matches.
  • Watch for names with apostrophes (single quotes) — parameterize instead of concatenating.
  • Handle Null or missing numeric fields before arithmetic (coalesce to 0 in SQL or check IsNull/Nz in code).
  • Avoid unbracketed reserved names (e.g., Date); use [Date], [By], or rename columns.
  • For security and correctness, prefer parameterized statements or stored procedures rather than building SQL with string concatenation. (SQL injection prevention / parameterization guidance). (cheatsheetseries.owasp.org)

As suggested, INSERT is valid when creating a new row; the above expands on when to AddNew vs. when a parameterized UPDATE/INSERT or Connection.Execute call is safer and why.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.