I am using SQL update query in VBA and I am getting the datatype mismatch error. I know that error is basically because of the column spare part. The spare part column contains numeric and alphanumeric values.
Public Function UpdateDistinctColumnFRNumberBasis()
StrInvoiceNumber = "109839-01"
FRSparepartNumber = "FT7119907459"
MergedInvoiceFile = "/test.xlsx"
Dim objConn As Object
Dim objRecordSet As Object
Set objConn = CreateObject("ADODB.Connection")
Set objRecCmd = CreateObject("ADODB.Command")
Set objRecCmd_Update = CreateObject("ADODB.Command")
objConn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
MergedInvoiceFile & ";Extended Properties=""Excel 8.0;""")
strSQL = " Update [Tabelle1$] SET [Status] = 'Include' Where " & _
"([RECHNR] ='" & StrInvoiceNumber & "' AND [Sparepart] = " & FRSparepartNumber & ")"
objConn.Execute strSQL
objConn.Close
End Function
As commented, the partnumber is text, thus it must be quoted in the SQL:
FRSparepartNumber = "FT7119907459"
' snip
strSQL = "Update [Tabelle1$] SET [Status] = 'Include' Where " & _
"([RECHNR] = '" & StrInvoiceNumber & "' AND " & _
"[Sparepart] = '" & FRSparepartNumber & "')"
I have an Access database that I am trying to insert, update and delete with SQL commands using VBA from an Excel workbook. My update and insert commands work fine but my delete command freezes Excel. I have tried various methods with and without table aliasing.
Set dbConnection = CreateObject("ADODB.Connection") 'New ADODB.Connection
dbConnection.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data source=C:\Users\me\Desktop\Opstats Import\TG_DB.accdb;"
Set dbCommand = CreateObject("ADODB.Command") 'New ADODB.Command
L = "[Excel 12.0 Xml;HDR=YES;IMEX=2;ACCDB=YES;DATABASE=" & ThisWorkbook.FullName & "].[LImport$]"
With dbCommand
.ActiveConnection = dbConnection
'Update Labour
SQL = "UPDATE tblLabour A" & _
" INNER JOIN " & L & " X" & _
" ON A.PositionID = X.PositionID AND A.Date = X.Date AND A.PayCode = X.PayCode" & _
" SET A.Hours = X.Hours, A.Dollars = X.Dollars"
.CommandText = SQL
.Execute
SQL = "DELETE FROM tblLabour" & _
" WHERE NOT EXISTS (SELECT * FROM " & L & " X WHERE X.PositionID = tblLabour.PositionID AND X.Date = tblLabour.Date AND X.PayCode = tblLabour.PayCode)"
.CommandText = SQL
.Execute
'Insert Labour
SQL = "INSERT INTO tblLabour" & _
" SELECT * FROM " & L & " X" & _
" WHERE NOT EXISTS (SELECT PositionID, Date, PayCode FROM tblLabour A WHERE A.PositionID = X.PositionID AND A.Date = X.Date AND A.PayCode = X.PayCode)"
.CommandText = SQL
.Execute
End With
dbConnection.Close
Set dbCommand = Nothing
Set dbConnection = Nothing
I have also tried:
SQL = "DELETE A FROM tblLabour A" & _
" WHERE NOT EXISTS (SELECT * FROM " & L & " X WHERE X.PositionID = A.PositionID AND X.Date = A.Date AND X.PayCode = A.PayCode)"
.CommandText = SQL
.Execute
Because of my data source, I do not have a primary key and rely on three fields to create a composite primary key so the only way to find records is to match all three fields.
I tested the SQL in an Access query and it seems to work fine.
Try concatenating fields to use as a unique identifier with NOT IN().
SQL = "DELETE FROM tblLabour" & _
" WHERE NOT PositionID & PayCode & [Date] IN (SELECT PositionID & PayCode & [Date] FROM " & L & " X)"
I am using Access 2016 and I am running into an error where a memo field gets updated and people are using apostrophes and it interferes with the code to update. The code works great and it updates the table for specific values unless there is an apostrophe present. No amount of parentheses or brackets have resolved this issue to isolate the apostrophes in text from the code. I would prefer suggestions that would I allow me to have apoostrophes if possible.
Private Sub btnlledit_Click()
Dim SQL As String
SQL = "UPDATE tblll " & _
"SET [LLN] = '" & Forms!frmaddll!txtlln & "',[REF] = '" & Forms!frmaddll!txtllref & "',[TRN] = '" & Forms!frmaddll!txtlltr & "',[HN] = '" & Forms!frmaddll!txtllhull & "', [LL] = '" & Forms!frmaddll!txtll & "',[CA] = '" & Forms!frmaddll!txtllca & "',[CP] = '" & Forms!frmaddll!txtllcomponent & "',[LOC] = '" & Forms!frmaddll!txtllloc & "',[LFSE] = '" & Forms!frmaddll!txtlllfse & "',[FC] = '" & Forms!frmaddll!txtllfc & "' " & _
"WHERE [LLN] = '" & Forms!frmaddll!txtlln.Value & "';"
DoCmd.RunSQL SQL
DoCmd.Requery
Me.Refresh
End Sub
I've cut down your SQL to give you an idea.
The first line of SQL are the parameters - note the ; at the end of the first line.
Private Sub btnlledit_Click()
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef("", _
"PARAMETERS LLN_Value TEXT(255), REF_Value TEXT(255), TRN_Value TEXT(255); " & _
"UPDATE tblll " & _
"SET LLN = LLN_Value, REF = REF_Value, TRN = TRN_Value " & _
"WHERE LLN = LLN_Value")
With qdf
.Parameters("LLN_Value") = Forms!frmaddll!txtlln
.Parameters("REF_Value") = Forms!frmaddll!txtllref
.Parameters("TRN_Value") = Forms!frmaddll!txtlltr
.Execute
End With
End Sub
A better way would be to move the execution of the query to another procedure and pass the required values to that:
Public Sub MyQuery(My_LLN_Value AS String, My_Ref_Value AS String, My_TRN_Value AS String)
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef("", _
"PARAMETERS LLN_Value TEXT(255), REF_Value TEXT(255), TRN_Value TEXT(255); " & _
"UPDATE tblll " & _
"SET LLN = LLN_Value, REF = REF_Value, TRN = TRN_Value " & _
"WHERE LLN = LLN_Value")
With qdf
.Parameters("LLN_Value") = My_LLN_Value
.Parameters("REF_Value") = My_Ref_Value
.Parameters("TRN_Value") = My_TRN_Value
.Execute
End With
End Sub
You can then call this procedure from your button click:
Private Sub btnlledit_Click()
MyQuery Forms!frmaddll!txtlln, Forms!frmaddll!txtllref, Forms!frmaddll!txtlltr
End Sub
Or from elsewhere, and getting your values from elsewhere to:
Public Sub Test
Dim Second_Arg AS String
Second_Arg = "Some Reference Value"
MyQuery Forms!frmaddll!txtlln, Second_Arg, "Third Argument"
End Sub
I said in a minute but had other stuff (+ writing this in VBA is a torture):
Dim SQL As String
SQL = "UPDATE tblll " & _
"SET [REF] = #ref,[TRN] = #trn,[HN] = #hn" & _
", [LL] = #ll,[CA] = #ca,[CP] = #cp,[LOC] = #loc " & _
", [LFSE] = #lfse, [FC] = #fc" & _
"WHERE [LLN] = #lln";"
Dim oConnection As ADODB.Connection
Dim oCommand As ADODB.Command
Set oConnection = New ADODB.Connection
Set oCommand = New ADODB.Command
oConnection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\MyFolder\MyData.accdb;"
oConnection.Open
oCommand.ActiveConnection = oConnection
oCommand.CommandText = SQL
oCommand.Parameters.Append oCommand.CreateParameter("#ref", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#trn", adVarChar, adParamInput, 100)
oCommand.Parameters.Append oCommand.CreateParameter("#hn", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#ll", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#ca", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#cp", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#loc", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#lfse", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#fc", adInteger)
oCommand.Parameters.Append oCommand.CreateParameter("#lln", adInteger)
oCommand.Parameters("#ref" ).Value = Forms!frmaddll!txtref.Value
oCommand.Parameters("#trn" ).Value = Forms!frmaddll!txttrn.Value
oCommand.Parameters("#hn" ).Value = Forms!frmaddll!txthn.Value
oCommand.Parameters("#ll" ).Value = Forms!frmaddll!txtll.Value
oCommand.Parameters("#ca" ).Value = Forms!frmaddll!txtca.Value
oCommand.Parameters("#cp" ).Value = Forms!frmaddll!txtcp.Value
oCommand.Parameters("#loc" ).Value = Forms!frmaddll!txtloc.Value
oCommand.Parameters("#lfse").Value = Forms!frmaddll!txtlfse.Value
oCommand.Parameters("#fc" ).Value = Forms!frmaddll!txtfc.Value
oCommand.Parameters("#lln" ).Value = Forms!frmaddll!txtlln.Value
oCmd.Execute
This code is not specifically an access code but VBA (that you can execute from any VBA environment, say Excel, Word ...).
Since I don't know your fields, parameter types are just for sampling. The important thing here is, you have to define the parameters in the same order as they appear in your query string. After appending the parameters, you are free to set their values in any order you like (that is a limitation in driver I think, parameters are not named but positional).
NOTE: I dropped initial LLN= because you were searching for it and setting to the same value (IOW no change).
Single quotes are escaped by doubling them up, just as you've shown us in your example. The following SQL illustrates this functionality.
BTW, Go for SQL Parameter instead of these inline SQL Injection.
Try like below:
Private Sub btnlledit_Click()
Dim SQL As String
SQL = "UPDATE tblll " & _
"SET [LLN] = '" & Forms!frmaddll!txtlln & "',[REF] = '" & Forms!frmaddll!txtllref & "',[TRN] = '" & Forms!frmaddll!txtlltr & "',[HN] = '" & Forms!frmaddll!txtllhull & "', [LL] = '" & Forms!frmaddll!txtll & "',[CA] = '" & Forms!frmaddll!txtllca & "',[CP] = '" & Forms!frmaddll!txtllcomponent & "',[LOC] = '" & Forms!frmaddll!txtllloc & "',[LFSE] = '" & Forms!frmaddll!txtlllfse & "',[FC] = '" & Forms!frmaddll!txtllfc & "' " & _
"WHERE [LLN] = '" & Forms!frmaddll!txtlln.Value & "';"
Replace (SQL, "'", "''")
DoCmd.RunSQL SQL
DoCmd.Requery
Me.Refresh
End Sub
I'm trying to loop according to the count of the gridview but it's giving me timeout at the second iteration.
Here's my code
Try
For i = 0 To Charges_GridView.Rows.Count - 2
'check unit price
'here is the error at the second iteration
Dim quantity As String = "SELECT QUANTITY FROM [dbo].[SERVICEITEMCHARGES] WHERE SERVICEITEMFID ='" & txt_FID.Text & "' AND FEESID = " & Charges_GridView.Rows(i).Cells(0).Value & " AND CURRENCY = '" & Charges_GridView.Rows(i).Cells(2).Value & "'"
Dim quantity_Adap As New SqlClient.SqlDataAdapter(quantity, conn)
Dim quantity_dt As New DataTable
quantity_Adap.Fill(quantity_dt)
If quantity_dt(0)(0) = 0 Then
'Update ServiceItemCharges
cmd.CommandText = "Update [dbo].[SERVICEITEMCHARGES] SET [AMOUNT] = " & Math.Ceiling(Charges_GridView.Rows(i).Cells(1).Value * 100) / 100 & ", UNIT_PRICE = 0 WHERE SERVICEITEMFID ='" & txt_FID.Text & "' AND FEESID = " & Charges_GridView.Rows(i).Cells(0).Value & " AND CURRENCY = '" & Charges_GridView.Rows(i).Cells(2).Value & "'"
cmd.Connection = connection
cmd.ExecuteNonQuery()
Else
'Update ServiceItemCharges
cmd.CommandText = "Update [dbo].[SERVICEITEMCHARGES] SET [AMOUNT] = " & Math.Ceiling(Charges_GridView.Rows(i).Cells(1).Value * 100) / 100 & ", UNIT_PRICE = " & (Math.Ceiling(Charges_GridView.Rows(i).Cells(1).Value * 100) / 100) / quantity_dt(0)(0) & " WHERE SERVICEITEMFID ='" & txt_FID.Text & "' AND FEESID = " & Charges_GridView.Rows(i).Cells(0).Value & " AND CURRENCY = '" & Charges_GridView.Rows(i).Cells(2).Value & "'"
cmd.Connection = connection
cmd.ExecuteNonQuery()
End If
Next
thanks for your help
I tested an UPDATE query in Access's query design, and it works, but when I try to use it in my module, I get the error:
Invalid SQL statement; expected... or 'UPDATE'.
My query:
strSql = "UPDATE " & rs.Fields("tableName") & _
" SET " & rs.Fields("foreignKeyName") & " = " & rsContacts.Fields("contactId") & _
" WHERE contactId = " & ContactID
rs: a table that has tableName, foriegnKeyName of the tables to update
rsContacts: a list of contactIds (currently standing on a particular one).
The actual string comes out like this:
UPDATE myTable SET ContactId = 5 WHERE contactId = 2
If the query works, and it is an action query, why am I getting this error?
This is my full code:
Public Sub updateChildTables(ByVal ContactID As Long, ByVal CompanyID As Long)
Dim strSql As String
Dim rs As Recordset
Dim rsPending As Recordset
strSql = "SELECT contactID FROM contacts _
WHERE companyId = " & CompanyID & " and contactId <> " & ContactID
Set rs = CurrentDb.OpenRecordset(strSql)
If Not (rs.BOF And rs.EOF) Then
rs.MoveFirst
strSql = "SELECT * FROM childTables"
Set rsChild = CurrentDb.OpenRecordset(strSql)
rsChild.MoveFirst
Do While Not rsChild.EOF
strSql = "UPDATE " & rsChild.Fields("tableName") & " SET " & rsChild.Fields("foreignKeyName") & " = " & rs.Fields("contactId") & " WHERE contactId = " & ContactID
DoCmd.RunSQL strSql
rs.moveNext
Loop
rsChild.Close
Set rsChild = Nothing
End If
Here is my idea for debugging and possibly even resolving this.
Create a query from within Access normally -- name it UpdateMyTable, for the sake of this example.
Then, rather than using the DoCmd, actually execute this specific query from your VBA.
Dim qry As QueryDef
strSql = "UPDATE " & rsChild.Fields("tableName") & " SET " & _
rsChild.Fields("foreignKeyName") & " = " & _
rs.Fields("contactId") & " WHERE contactId = " & ContactID
Set qry = CurrentDb.QueryDefs("UpdateMyTable")
qry.SQL = strSql
qry.Execute
The big advantage of this is that you can very easily debug this from within Access to both see the rendered SQL and manually run it / tweak it.