MS-Access Update SQL Not Null But is Blank (! Date & Number Fields !) - sql

I have a few controls that are number and short date format in my tables also the date controls are masked to mm/dd/yyyy. Some of the fields that are loaded into the form are blank from the original table and so when executing the sql I am essentially evaluating the wrong thing whether Im checking for '' or Null. as '' fails as text for date number and the fields are not actually blank.
strSQL4 = "UPDATE [tblDetails] SET " & _
"[Proposed] = IIF(IsNull(" & Forms!frmEdit.txtProposed.Value & "),0," & Forms!frmEdit.txtProposed.Value & "), " & _
"[Multi] = IIF(IsNull(" & Forms!frmEdit.txtMulitplier.Value & "),0," & Forms!frmEdit.txtMulitplier.Value & "), " & _
"[Rational] = '" & Forms!frmEdit.txtRational.Value & "' " & _
" WHERE [RNumber] = '" & Forms!frmEdit.cmbUpdate.Value & "'"
Debug.Print strSQL4
dbs.Execute strSQL4
ERROR 3075 Wrong number of arguments used with function in query expression
'IIF(IsNull(),0,'
I also tried entering the field itself suggested from another site
strSQL4 = "UPDATE [tblDetails] SET " & _
"[Proposed] = IIF(" & Forms!frmEdit.txtProposed.Value & "='',[Proposed]," & Forms!frmEdit.txtProposed.Value & "), " & _
" WHERE [RNumber] = '" & Forms!frmEdit.cmbUpdate.Value & "'"
Debug.Print strSQL4
dbs.Execute strSQL4
Same Error 3075 'IIF(IsNull(),0,[ProposedHrs]'
***also fails if I use the IIF(IsNull method as opposed to the =''
I did not paste an example of the dates failing, but is the same idea, not null but is blank, but cant seem to update back to blank again or even skip maybe?
Thanks to anyone in advance.
Update-1 from attempting Erik Von Asmuth code <--Thanks btw!
Set qdf = db.CreateQueryDef("", & _
"UPDATE [tblDetails] SET " & _
"[Proposed] = #Proposed, " & _
"[Multi] = #Multi, " & _
"[Rational] = #Rational " & _
"WHERE [RNumber] = #RNumber")
This portion is all red and the first "&" is highlighted after closing the notification window
Compile error:
Expected: expression
Update-2: I moved the update to the first line and it seems to be working. Set qdf = db.CreateQueryDef("", "UPDATE [tblDetails] SET " & _
I am going to try this method with the dates fields next.
Update-3: when attempting the same parameterization with textbox's masked with 99/99/0000;0;_ I am receiving item not found in collection? I have checked the spelling several times and everything seems ok. I tried the following three formats so set parameter DateRcvd, can anyone comment if this is correct for a text box with dates?
qdf.Parameters("#DateRcvd") = IIf(Nz(Forms!frmEdit.txtDateRcvd.Value) = "", 0, Forms!frmEdit.txtDateRcvd.Value)
qdf.Parameters("#DateRcvd") = IIf(IsNull(Forms!frmEdit.txtDateRcvd.Value), 0, Forms!frmEdit.txtDateRcvd.Value)
qdf.Parameters("#DateRcvd") = IIf(Forms!frmEdit.txtDateRcvd.Value = "", 0, Forms!frmEdit.txtDateRcvd.Value)
Update-4:
Dim qdf2 As DAO.QueryDef
Set db = CurrentDb
Set qdf2 = db.CreateQueryDef("", "UPDATE [tblDetails] SET " & _
"[DateReceived] = #DateRcvd " & _
"WHERE [RNumber] = #RNumber")
qdf.Parameters("#DateRcvd") = IIf(Nz(Forms!frmEdit.txtDateRcvd.Value) = "", 0, Forms!frmEdit.txtDateRcvd.Value)
qdf.Parameters("#RNumber") = Forms!frmEdit.cmbUpdate.Value
qdf2.Execute
Please Note text box txtDateRcvd has an Input Mask 99/99/0000;0;_ set within the properties of the textbox.

You should account for empty strings, and do that IIF statement in VBA instead of SQL:
strSQL4 = "UPDATE [tblDetails] SET " & _
"[Proposed] = " & IIF(Nz(Forms!frmEdit.txtProposed.Value) = "",0, Forms!frmEdit.txtProposed.Value) & ", " & _
"[Multi] = " & IIF(Nz(Forms!frmEdit.txtMulitplier.Value) = "",0, Forms!frmEdit.txtMulitplier.Value) & ", " & _
"[Rational] = '" & Forms!frmEdit.txtRational.Value & "' " & _
" WHERE [RNumber] = '" & Forms!frmEdit.cmbUpdate.Value & "'"
Or better yet, do it properly and parameterize the whole update so you can't get these kind of errors or SQL injection.
Example of how to do it properly:
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", _
"UPDATE [tblDetails] SET " & _
"[Proposed] = #Proposed, " & _
"[Multi] = #Multi, " & _
"[Rational] = #Rational " & _
"WHERE [RNumber] = #RNumber"
)
qdf.Parameters("#Proposed") = IIF(Nz(Forms!frmEdit.txtProposed.Value) = "",0, Forms!frmEdit.txtProposed.Value)
qdf.Parameters("#Multi") = IIF(Nz(Forms!frmEdit.txtMulitplier.Value) = "",0, Forms!frmEdit.txtMulitplier.Value)
qdf.Parameters("#Rational") = Forms!frmEdit.txtRational.Value
qdf.Parameters("#RNumber") = Forms!frmEdit.cmbUpdate.Value
qdf.Execute

Related

Error 424 object required after NULL SQL query

I am running some EXCEL VBA code to update the contents of an ACCESS database table along the lines suggested here:
IF ##Rowcount = 0 -- SQL Syntax Error in Access
. When I execute the SELECT query, EXCEL VBA gives this error message:
Run-time error 424: Object required
I extracted the SQL string from the VBA Watch window and ran it as a Query in ACCESS. The first time I did this, there were no records becasue the table was empty, so I ran the INSERT query in ACCESS and then tried running the VBA code but got the same error message.
The code is here:
Public db As DAO.Database
' Open database
Public Sub OpenMdtDatabase()
Set db = DBEngine(0).OpenDatabase("SL_MDT_data_v1.accdb")
End Sub
' Update DB table
Sub UpdateDb()
' Initialise
Dim rs As DAO.Recordset
Set xlSht = Sheets("plot_data")
' Open database
Call OpenMdtDatabase
' Get the data to store
sname = xlSht.Cells(6, "R").Value
xfill = xlSht.Cells(6, "S").Value
xedge = xlSht.Cells(6, "T").Value
xstyl = xlSht.Cells(6, "U").Value
xsize = xlSht.Cells(6, "V").Value
' SQL stuff
sqlTxtSelect = "SELECT SeriesName FROM SeriesProperties WHERE SeriesName ='" & sname & "';"
sqlTxtUpdate = "UPDATE SeriesProperties " & _
sqlTxtUpdate = "SET SeriesFill = " & xfill & ", " & _
sqlTxtUpdate = "SeriesEdge = " & xedge & ", " & _
sqlTxtUpdate = "SeriesStyle = " & xstyl & ", " & _
sqlTxtUpdate = "SeriesSize = " & xsize & " " & _
sqlTxtUpdate = "WHERE SeriesName = '" & sname & "';"
sqlTxtInsert = "INSERT INTO SeriesProperties('" & sname & "') " & _
sqlTxtInsert = "VALUES(" & xfill & ", " & xedge & ", " & xstyl & ", " & xsize & ");"
Set rs = db.OpenRecordset(sqlTxtSelect)
If rs.RecordCount = 0 Then
DoCmd.RunSQL (sqlTxtInsert)
Else
DoCmd.RunSQL (sqlTxtUpdate)
End If
End Sub
I am guessing that there is something wrong with the SQL SELECT string. I tried setting this directly using
SELECT SeriesName FROM SeriesProperties WHERE SeriesName ='14/10-2:F2F_SLMC'
but still get the same error message. I have also tried removing the colon ...
The problem lies with the statement
DoCmd.RunSQL (sqlTxtInsert)
If I change this to
db.Execute (sqlTxtInsert)
then everything is fine. Should have scrolled to the end of the answer at the original link ....

Update SQL MS Access 2010

This is wrecking my brains for 4 hours now,
I have a Table named BreakSked,
and I this button to update the table with the break end time with this sql:
strSQL1 = "UPDATE [BreakSked] SET [BreakSked].[EndTime] = " & _
Me.Text412.Value & " WHERE [BreakSked].AgentName = " & Me.List423.Value _
& " AND [BreakSked].ShiftStatus = '1'"
CurrentDB.Execute strSQL1
Text412 holds the current system time and List423 contains the name of the person.
I'm always getting this
"Run-time error 3075: Syntax Error (missing operator) in query
expression '03:00:00 am'
Any help please?
EDIT: Thanks, now my records are updating. But now its adding another record instead of updating the record at hand. I feel so silly since my program only has two buttons and I can't figure out why this is happening.
Private Sub Form_Load()
DoCmd.GoToRecord , , acNewRec
End Sub
Private Sub Command536_Click()
strSQL1 = "UPDATE BreakSked SET BreakSked.EndTime = '" & Me.Text412.Value & "',BreakSked.Duration = '" & durationz & "' " & vbCrLf & _
"WHERE (([BreakSked].[AgentID]='" & Me.List423.Value & "'));"
CurrentDb.Execute strSQL1
CurrentDb.Close
MsgBox "OK", vbOKOnly, "Added"
End Sub
Private Sub Command520_Click()
strSql = "INSERT INTO BreakSked (ShiftDate,AgentID,StartTime,Status) VALUES ('" & Me.Text373.Value & "', '" & Me.List423.Value & "', '" & Me.Text373.Value & "','" & Me.Page657.Caption & "')"
CurrentDb.Execute strSql
CurrentDb.Close
MsgBox "OK", vbOKOnly, "Added"
End Sub
You wouldn't need to delimit Date/Time and text values if you use a parameter query.
Dim strUpdate As String
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
strUpdate = "PARAMETERS pEndTime DateTime, pAgentName Text ( 255 );" & vbCrLf & _
"UPDATE BreakSked AS b SET b.EndTime = [pEndTime]" & vbCrLf & _
"WHERE b.AgentName = [pAgentName] AND b.ShiftStatus = '1';"
Debug.Print strUpdate ' <- inspect this in Immediate window ...
' Ctrl+g will take you there
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", strUpdate)
qdf.Parameters("pEndTime").Value = Me.Text412.Value
qdf.Parameters("pAgentName").Value = Me.List423.Value
qdf.Execute dbFailOnError
And if you always want to put the current system time into EndTime, you can use the Time() function instead of pulling it from a text box.
'qdf.Parameters("pEndTime").Value = Me.Text412.Value
qdf.Parameters("pEndTime").Value = Time() ' or Now() if you want date and time
However, if that is the case, you could just hard-code the function name into the SQL and dispense with one parameter.
"UPDATE BreakSked AS b SET b.EndTime = Time()" & vbCrLf & _
As I said in my comment you need to wrap date fields in "#" and string fields in escaped double quotes
strSQL1 = "UPDATE [BreakSked] SET [BreakSked].[EndTime] = #" & _
Me.Text412.Value & "# WHERE [BreakSked].AgentName = """ & Me.List423.Value & _
""" AND [BreakSked].ShiftStatus = '1'"

Correctly assigned parameter valuecan not be used

I want to get a cmb-value before the entry is changed, by using ".oldValue". The value is correctly assigned (according to debugger), but running the SQL Access is asking for a manual entry. Doing the entry manually works fine, so the remaining code should be fine.
My Code:
Dim CategoryNameBeforeChange As String
CategoryNameBeforeChange = Forms!frmCategory!txtCategoryName.OldValue
SQL = "UPDATE CategoryTbl " & _
"SET CategoryTbl.CategoryName = Forms!frmCategory!txtCategoryName " & _
"WHERE (CategoryTbl.CategoryName = CategoryNameBeforeChange);"
Any idea what went wrong here?
Any help is greatly appreciated!
Try this:
SQL = "UPDATE CategoryTbl " & _
"SET CategoryTbl.CategoryName = Forms!frmCategory!txtCategoryName " & _
"WHERE (CategoryTbl.CategoryName = " & CategoryNameBeforeChange & ");"
I suspect that CategoryName is text, in this case it should be
SQL = "UPDATE CategoryTbl " & _
"SET CategoryTbl.CategoryName = Forms!frmCategory!txtCategoryName " & _
"WHERE (CategoryTbl.CategoryName = '" & CategoryNameBeforeChange & "');"

access 2013 increasing quantity in a table field

Good day. I'm a little stumped about what is happening in my code. I have a userform which collects txtQntyRecd and cboSupplySource. I calculate the lookupValue. And it works just fine. It successfully places the txtQntyRecd in the correct tblWarehouseLocations.WQuantity location. The code is:
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = '" & Me.txtQntyRecd & "'" & _
"WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError
What I want to do is add the next quantity to the same location. I get weird results if I change the SET statement to the following:
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + '" & Me.txtQntyRecd & "'"
If I put 200 in the first statement, I get 200 in my WQuantity field. When I change to the second statement and I try to add 1 to the 200 I get a result of 211. If I add 1 again, the result is 223. Add 1 again, the result is 236.
Could someone explain what is happening and why the results aren't 201, 202 and 203? In the future I will need to subtract quantities from WQuantity as well.
Thanks
You're adding quotes around an integer and appending it as a string. Change it to:
".....
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & val(Me!txtQntyRecd) & "....
...."
I've changed the . to a ! as I think it's still a nice distinction between objects properties and controls, and used the val function as it converts the string number value to the integer value.
This is your query in full:
' When I use values from controls, I like to store them in vars
Dim quantityReceived As integer
quantityReceived = val(Me!txtQntyRecd)
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
I solved the problem. I created a SELECT query to get the present amount in WQuantity. Now quantityReceived = Me!txtQntyRecd + the present amount. With SET tblWarehouseLocations.WQuantity = " & quantityReceived it works fine. However, if just seems so cumbersome.
' lookupValue gives the index into the tblWarehouseLocations where WQuantity resides
Dim lookupValue As Integer
lookupValue = DLookup("[WLocation_ID]", "[tblWarehouseLocations]", "[Location_Name] = '" & Me.cboWLocation & "'")
'Define SQL Query
strSQL = "select tblWarehouseLocations.WQuantity FROM tblWarehouseLocations WHERE (((tblWarehouseLocations.WLocation_ID)= " & lookupValue & "))"
Set rs = db.OpenRecordset(strSQL)
If IsNull(rs!WQuantity) Then
dbvalue = 0
Else
dbvalue = rs!WQuantity
End If
Dim quantityReceived As Integer
quantityReceived = Val(Me!txtQntyRecd) + dbvalue
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError

Access Run-time error '3061': Too few parameters. Expected 1

I'm getting an Access Run-time error:
'3061': Too few parameters. Expected 1
when trying to run some VBA code from a form with sub-report.
I've tried with the variable (CurAssetID) as well as the direct link (Forms!Details!ID) in the SQL query but both result in the same error. I put in the MsgBox just to verify it was picking up the correct value which it is.
If I replace the last part of the SQL query with a value (HAVING (((Assignments.AssetID)=1));") it works fine. What's going on here and how can I fix it?
Private Sub LineSelect_Click()
CurAssetID = Forms!Details!ID
Status = MsgBox(CurAssetID, vbOKOnly)
Dim LastAssignment As DAO.Recordset
LastAssignmentSQL = "SELECT Assignments.AssetID, Last(Assignments.LocationID) AS LastLocationID FROM Assignments GROUP BY Assignments.AssetID HAVING (((Assignments.AssetID)=CurAssetID));"
Set LastAssignment = CurrentDb.OpenRecordset(LastAssignmentSQL, dbOpenDynaset, dbSeeChanges)
You can create a string variable with the parameter value concatenated inside it:
curAssetID = Forms!Details!ID
status = MsgBox(CurAssetID, vbOKOnly)
Dim lastAssignment As DAO.Recordset
lastAssignmentSQL = "SELECT Assignments.AssetID, " & _
"Last(Assignments.LocationID) AS LastLocationID " & _
"FROM Assignments " & _
"GROUP BY Assignments.AssetID " & _
"HAVING (((Assignments.AssetID)=" & CurAssetID & "));"
Set lastAssignment = CurrentDb.OpenRecordset(lastAssignmentSQL, dbOpenDynaset, dbSeeChanges)
' ...
As an additional precaution, if Forms!Details!ID is suposed to be a number (Integer or Long), I suggest you declare the variable CurAssetID explicitly:
Dim curAssetID as Integer ' Or Long
curAssetID = Forms!Details!ID
Dim lastAssignment As DAO.Recordset
lastAssignmentSQL = "SELECT Assignments.AssetID, " & _
"Last(Assignments.LocationID) AS LastLocationID " & _
"FROM Assignments " & _
"GROUP BY Assignments.AssetID " & _
"HAVING (((Assignments.AssetID)=" & CurAssetID & "));"
Set lastAssignment = CurrentDb.OpenRecordset(lastAssignmentSQL, dbOpenDynaset, dbSeeChanges)
' ...
If the value is a 'String', then you should enclose the value in quotes in your query:
Dim curAssetID as String
' ...
lastAssignmentSQL = "SELECT Assignments.AssetID, " & _
"Last(Assignments.LocationID) AS LastLocationID " & _
"FROM Assignments " & _
"GROUP BY Assignments.AssetID " & _
"HAVING (((Assignments.AssetID)= '" & CurAssetID & "'));"
' ...