I have been trying to fix this code, but have no idea why I keep having too few parameters :1 error
strSQL = "UPDATE tblProduct "
strSQL = strSQL & "SET [Verified_By] = " & Me.txtCurrentUser & "" & " , [Verified_Date] = #" & Me.txtAuto_Date & "#" & ", [Status] = ""Verified"""
strSQL = strSQL & " WHERE [Status] = ""Not Verified""" & " AND [Verify] = -1"
I am still having troubles with the syntax for attaching variables to queries in VBA. The query works in my UPDATE statement in Access.
This is what I use in Access query:
UPDATE tblProduct SET Verified_By = forms!frmVerificationProduct!txtcurrentuser, Verified_date = forms!frmVerificationProduct!txtAuto_date, Status = "Verified"
WHERE verify = -1 AND Status = "Not Verified";
If the tblProduct.Verified_By field is text datatype, the problem is that the UPDATE is supplying an unquoted text value. And when Access sees the unquoted text value, it assumes that must be a parameter for which you have not supplied a value.
In that case, you could revise the code to include the needed quotes or switch to a parameter query and not be bothered with quotes ...
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
strSQL = "UPDATE tblProduct" & vbCrLf & _
"SET [Verified_By] = [pCurrentUser], [Verified_Date] = [pAuto_Date], [Status] = 'Verified'" & vbCrLf & _
"WHERE [Status] = 'Not Verified' AND [Verify] = -1"
Debug.Print strSQL ' <- view in Immediate window; Ctrl+g will take you there
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strSQL)
qdf.Parameters("pCurrentUser").Value = Me!txtCurrentUser.Value
qdf.Parameters("pAuto_Date").Value = Me!txtAuto_Date.Value
qdf.Execute dbFailOnError
This should do:
strSQL = "UPDATE tblProduct "
strSQL = strSQL & "SET [Verified_By] = " & Me.txtCurrentUser & ", [Verified_Date] = #" & Format(Me.txtAuto_Date, "yyyy\/mm\/dd") & "#, [Status] = 'Verified' "
strSQL = strSQL & "WHERE [Status] = 'Not Verified' AND [Verify] = -1"
Related
I've written a function to loop through an array of a custom object (C_Document). In the loop, if the document number does not already exist, it should insert a new record into the table tbl_docs. If the document does exist, it should update the appropriate record in the database.
Public Function updateDocuments(docs() As C_Document) As Double
Dim db As Object
Set db = Application.CurrentDb
Dim docIndex As Double
'Loop through all imported documents
For docIndex = 1 To UBound(docs)
Dim strSQL As String
Dim exists As Double
exists = DCount("docNo", "tbl_docs", "docNo = '" & docs(docIndex).getDocNo() & "'" > 0)
'Check if entry already exists
If (exists > 0) Then
'docNo entry already exists - update
strSQL = "UPDATE tbl_docs SET " & _
"docReviewStatus = " & docs(docIndex).getDocStatus() & "," & _
"docRev = '" & docs(docIndex).getDocReview() & "'," & _
"docDate = '" & docs(docIndex).getDocDate() & "'" & _
" WHERE (" & _
"docNo = '" & docs(docIndex).getDocNo() & "');"
Else
'docNo does not exist - insert
strSQL = "INSERT INTO tbl_docs (docNo, docReviewStatus, docRev, docDate) " & _
"SELECT '" & docs(docIndex).getDocNo() & "'" & _
"," & docs(docIndex).getDocStatus() & _
",'" & docs(docIndex).getDocReview() & "'" & _
",'" & docs(docIndex).getDocDate() & "'" & _
";"
End If
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
MsgBox strSQL
Next
updateDocuments = docIndex
End Function
However, when the function is called (with tbl_docs empty), it only inserts one record and the SQL string thereafter becomes the update statement.
Is there a common issue when DCount() is used in a loop? Does anyone have any experience with this logical error?
Your check has a slight but important error:
exists = DCount("docNo", "tbl_docs", "docNo = '" & docs(docIndex).getDocNo() & "'" > 0)
should be
exists = DCount("docNo", "tbl_docs", "docNo = '" & docs(docIndex).getDocNo() & "'") > 0
or if exists isn't bool, but simply the count, then
exists = DCount("docNo", "tbl_docs", "docNo = '" & docs(docIndex).getDocNo() & "'")
You can simplify and speed up this a bit using DAO, where you can do the search and update/edit in one go:
Public Function updateDocuments(docs() As C_Document) As Long
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim docIndex As Long
Dim strSQL As String
strSQL = "Select * From tbl_docs"
Set db = Application.CurrentDb
Set rs = db.OpenRecordset(strSQL)
'Loop through all imported documents
For docIndex = LBound(docs) To UBound(docs)
rs.FindFirst "docNo = '" & docs(docIndex).getDocNo() & "'"
If rs.NoMatch Then
'docNo does not exist - insert
rs.AddNew
rs!docNo.Value = docs(docIndex).getDocNo()
Else
'docNo entry already exists - update
rs.Edit
End If
rs!docReviewStatus.Value = docs(docIndex).getDocStatus()
rs!docRev.Value = docs(docIndex).getDocReview()
rs!docDate = docs(docIndex).getDocDate()
rs.Update
Next
rs.Close
updateDocuments = docIndex
End Function
Okay, I need help resolving what should be an easy issue. I am trying to do an UPDATE query to an Access table. I have the ID of the record to be updated in a hidden text box on my form. What happens is that the query def changes my Integer to a string when it stores it in the parameter. It does this even after I cast the value to an Integer. p6 is the parameter name. See code below. I get a data type mismatch error on every other field that has an integer value as well.
Private Sub SubmitButton_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSql As String
Dim frm As Object
If IsRequiredFilled(Me) = False Then
MsgBox "Please fill out all required fields.", vbCritical
Exit Sub
End If
Set db = CurrentDb
strSql = "UPDATE [Batches_T] " & _
"SET [BatchName] = [BatchName] + [p1], " & _
"[StatusID] = [StatusID] + [p2], " & _
"[InternalStatusID] = [InternalStatusID] + [p2], " & _
"[ReviewerID] = [ReviewerID] + [p3], " & _
"[StartDate] = [StartDate] + [p4], " & _
"[PowerPointFilePath] = [PowerPointFilePath] + [p5] " & _
"WHERE [ID] = [p6]"
Set qdf = db.CreateQueryDef(vbNullString, strSql)
With qdf
.Parameters("p1").Value = Me.BatchName
.Parameters("p2").Value = Me.StatusID
.Parameters("p3").Value = Me.InternalStatusID
.Parameters("p4").Value = Me.StartDate
.Parameters("p5").Value = Me.PowerPointFilePath
.Parameters("p6").Value = CInt(Me.ID)
.Execute dbFailOnError
End With
Set qdf = Nothing
Set db = Nothing
Forms![Dashboard_F]![Batches_DS_F].Requery
If Me.keepOpenCheckBox = False Then
DoCmd.Close acForm, "AddBatch_F", acSaveYes
End If
End Sub
Try and add explicit type declarations for the parameter:
strSql = "PARAMETERS [p6] INTEGER; " & _
"UPDATE [Batches_T] " & _
"SET [BatchName] = [BatchName] + [p1], " & _
"[StatusID] = [StatusID] + [p2], " & _
"[InternalStatusID] = [InternalStatusID] + [p2], " & _
"[ReviewerID] = [ReviewerID] + [p3], " & _
"[StartDate] = [StartDate] + [p4], " & _
"[PowerPointFilePath] = [PowerPointFilePath] + [p5] " & _
"WHERE [ID] = [p6]"
Help! i am having some trouble with my access codes on a database whereby it says that access error 3061 Too Few parameters expected 1. Problem highlighted was
Set oRS = CurrentDb.OpenRecordset(sSQL)
Dim i As Date, n As Integer, oRS As DAO.Recordset, sSQL As String
Dim db As DAO.Database
Set db = CurrentDb
Dim BookedDate As Date
Dim FacilitiesID As String
Dim StartTime As Date
cboTime.RowSourceType = "Value List"
cboTime.RowSource = ""
If IsNull(Start) Then Exit Sub Else i = Start
If Me.NewRecord = True Then
DoCmd.RunCommand acCmdSaveRecord
End If
sSQL = "SELECT FacilitiesID, StartTime, BookedDate"
sSQL = sSQL & " FROM qrysubform"
sSQL = sSQL & " WHERE FacilitiesID= " & Me.FacilitiesID & _
" AND BookedDate=# " & Me.txtDate & "#"
Set oRS = CurrentDb.OpenRecordset(sSQL)
Your Facilities ID is dimensioned as a string, though in your SQL statement it is referenced as a number. If your form's FacilitiesID is in fact a string, you need to enclose it in quotes:
sSQL = "SELECT FacilitiesID, StartTime, BookedDate"
sSQL = sSQL & " FROM qrysubform"
sSQL = sSQL & " WHERE FacilitiesID= '" & Me.FacilitiesID & _
"' AND BookedDate=#" & Me.txtDate & "#"
In such cases, insert a debug line and study the output:
Debug.Print sSQL
' Study output
Set oRS = CurrentDb.OpenRecordset(sSQL)
That said, this error is typically caused by a missing or misspelled field name.
Generating a Report from Query; capturing data from several tables. The Report has two calculated boxes and I want to UPDATE the data back to one of the tables. Debugging shows I'm capturing the variables but keeps giving me Syntax errors in the WHERE clause. I've tried lots of syntax iterations from scouring the net.
Private Sub Report_Load()
Dim sqls As String
Dim TEP As Single
Dim PPS As Single
Dim RecipeN As String
TEP = Reports![RecipeBuild]![txtTEP]
PPS = Reports![RecipeBuild]![txtPPS]
RecipeN = Reports![RecipeBuild]![RecipeName]
sqls = "Update [tblRecipeBuild] " _
& "Set TEP = " & TEP & " " _
& "Set PPS = " & PPS & " " _
& "WHERE [RecipeName] = '" & RecipeN & "';"
DoCmd.SetWarnings False
DoCmd.RunSQL sqls
DoCmd.SetWarnings True
End Sub
An Access SQL UPDATE should include the SET keyword only once.
When you want to update more than one field, use SET once, and then use a comma between the pairs of FieldName=Value segments.
sqls = "Update [tblRecipeBuild] " _
& "Set TEP = " & TEP & ", PPS = " & PPS & " " _
& "WHERE [RecipeName] = '" & RecipeN & "';"
I think that should work but suggest you consider a parameter query instead of concatenating values into an UPDATE statement.
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strUpdate As String
strUpdate = "UPDATE tblRecipeBuild SET TEP=pTEP, PPS=pPPS WHERE RecipeName=pRecipeN;"
Debug.Print strUpdate
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strUpdate)
With qdf
.Parameters("pTEP").Value = TEP
.Parameters("pPPS").Value = PPS
.Parameters("pRecipeN").Value = RecipeN
End With
qdf.Execute dbFailOnError
I've inherited some Access VBA code and there are controls on a form (such as a listbox named lstOrderID, mentioned below) which have no RowSource property set (an empty string). I look in the code and find statements like this in various places:
Forms!frm_Customer.lstOrderID = rstCust!OrderID ' set from a record set
Forms!frm_Customer.lstOrderID.Requery
Me.lstOrderID = Me.lstOrderID.ItemData(0) ' set to first item in self
But nowhere in the code is lstOrderID.RowSource being set.
How can Requery be called on a listbox that has no RowSource?
How can a listbox be set to a single value (rstCust!OrderID) from a record set, unless this is a list of values (although the debugger shows an integer in lstOrderID.Value)?
Here is more code:
Dim rstCust As Recordset
Set db = CurrentDb
Set rstCust = db.OpenRecordset("SELECT * FROM Orders WHERE CustID=" & ID & _
"AND Datetaken =Date() " & _
"AND VendorID='" & Forms!frm_Customer.cboVendorID & "'")
Forms!frm_Customer.lstOrderID = rstCust!OrderID
rstCust.Close
db.Close
Another section:
Dim rstCust As Recordset
Dim blStatus As Boolean
Dim strSql As String
Set db = CurrentDb
strSql = "SELECT Orders.OrderID " & _
"FROM Orders " & _
"WHERE (((Orders.DateTaken)=#" & Date & "#) " & _
"AND ((Orders.VendorID)='" & Forms!frm_Customer.cboVendorID & "') " & _
"AND ((Orders.CustID)=" & ID & "));"
Set rstCust = db.OpenRecordset(strSql)
Forms!frm_Customer.lstOrderID = rstCust!OrderID
Forms!frm_Customer.lstOrderID.Requery
Forms!frm_Customer.lstOrderID = rstCust!OrderID
rstCust.Close
db.Close
Also this:
Me.lstOrderID.Requery
Me.lstOrderID = Me.lstOrderID.ItemData(0)