I am in the process of developing an Access 2016 database that has local tables. It will be migrated to SQL Server in future so I am using ADO for data processing.
While testing earlier, my error processing procedure failed to perform a log insert immediately after an error was trapped in the following test CRUD procedure.
Public Function updateTransportRate(lngOrigin As Long, lngDestination As Long, dblRate As Double) As Boolean
' check if global error handling is enabled ->
If glbErrorHandling Then On Error GoTo Error_Handler
' declarations ->
Dim strSQL As String
Dim strGUID As String
Dim cnn As ADODB.Connection
Set cnn = CurrentProject.Connection
Dim p_lRowsUpdated as Integer
strSQL = "UPDATE tbl_transport " & _
"SET rate=" & dblRate & ", modify_dtm=Now(), modify_user ='" & Application.CurrentUser & "' " & _
"WHERE origin=" & lngOrigin & " AND destination=" & lngDestination & ""
With cnn
.BeginTrans
.Execute strSQL, p_lRowsUpdated, dbFailOnError
If Err.Number <> 0 Then
.RollbackTrans
GoTo Error_Handler
Else
.CommitTrans
If glbDebugMode Then
Debug.Print "Records Updated : " & p_lRowsUpdated
End If
If p_lRowsUpdated > 0 Then updateTransportRate = True Else updateTransportRate = False
If glbLogApplicationActivity = True And p_lRowsUpdated > 0 Then
Call addActivityLog(SystemLogType.UpdateRecord, "Updated route " & lngOrigin & " -> " & lngDestination & " with rate: " & dblRate & " in tbl_transport")
End If
End If
End With
Error_Handler_Exit:
On Error Resume Next
Exit Function
Error_Handler:
If Err.Number <> 0 Then
If glbDebugMode Then
Select Case DebugOption("Error # " & Err.Number & " was generated by " & Err.Source & " (" & Err.Description & ")")
Case vbAbort, vbIgnore
ProcessError Err.Number, Err.Description, , , "Module", "MAINTENANCE", "Function", "updateTransportRate", Erl, True
Case vbRetry
Stop: Resume 0
End Select
Else
ProcessError Err.Number, Err.Description, , , "Module", "MAINTENANCE", "Function", "updateTransportRate", Erl, True
End If
End If
Resume Error_Handler_Exit
End Function
Below procedure is used in the above error handler to capture response only while in debug mode:
Public Function DebugOption(sErrorMessage As String) As Integer
DebugOption = MsgBox("" & sErrorMessage & "" _
& vbCrLf & "Abort - Stop" _
& vbCrLf & "Retry - Debug (then press F8 twice to show error line)" _
& vbCrLf & "Ignore - Continue with next line", _
Buttons:=vbAbortRetryIgnore Or vbCritical Or vbDefaultButton2, Title:=CurrentDb.Properties("AppTitle"))
End Function
Debug prompt message for testing only:
Below is my error processing procedure which accepts a number of parameters and writes the result to a log file:
Public Sub ProcessError(Optional strErrNumber As String = vbNullString, _
Optional strErrDescription As String = vbNullString, _
Optional intErrSeverity As Integer = 0, _
Optional strErrState As String = vbNullString, _
Optional strErrModuleType As String = vbNullString, _
Optional strErrModuleName As String = vbNullString, _
Optional strErrProcedureType As String = vbNullString, _
Optional strProcedureName As String = vbNullString, _
Optional strErrLineNo As String = vbNullString, _
Optional blnDisplay As Boolean = True)
' declarations ->
Dim strGUID As String
Dim strSQL As String
Dim cnn As ADODB.Connection
Set cnn = CurrentProject.Connection
Dim tmpString As String
' build string ->
tmpString = "Error # " & strErrNumber & " (" & strErrDescription & ") on line " & strErrLineNo & " in procedure " & strProcedureName & " of " & strErrProcedureType & " in " & strErrModuleType & " " & strErrModuleName & ""
If glbDebugMode Then Debug.Print tmpString
' check if error logging is enabled ->
If glbErrorLogging Then
' write error log to table ->
strGUID = CreateGuid
' insert log into error table ->
strSQL = "INSERT INTO system_error_log (error_user, error_number, error_description, error_severity, error_state, " & _
"error_module_type, error_module_name, error_procedure_type, error_procedure_name, " & _
"error_line, error_message, rowguid) " & _
"VALUES('" & Application.CurrentUser & "', '" & strErrNumber & "', '" & strErrDescription & "', " & intErrSeverity & ", '" & strErrState & "', " & _
" '" & strErrModuleType & "', '" & strErrModuleName & "', '" & strErrProcedureType & "', '" & strProcedureName & "', " & _
" '" & strErrLineNo & "', '" & Replace(tmpString, "'", "''") & "', '" & strGUID & "')"
cnn.Execute strSQL, , dbFailOnError **<---- FAILS HERE**
End If
End Sub
Why would the above error processing procedure fail on cnn.Execute strSQL, , dbFailOnError and then display the same error message from earlier CRUD procedure?
cnn.Execute error message:
Perhaps I am missing something simple here so hopefully someone can point me in the right direction.
Edit with new source code based on changes for review:
Public Function updateRoutePairRate(lngFromLocationNumber As Long, lngToLocationNumber As Long, dblRate As Double) As Boolean
If glbErrorHandling Then On Error GoTo Error_Handler
Dim prm_FromLocationNumber As ADODB.Parameter
Dim prm_ToLocationNumber As ADODB.Parameter
Dim prm_Rate As ADODB.Parameter
strSQL = "UPDATE tbl_transport " & _
"SET PalletRate =?, EffectiveDTS =Now(), LastUpdateUserID ='" & Application.CurrentUser & "' " & _
"WHERE FromLocNo=? AND ToLocNo=?"
' set connection and command objects ->
Set cnn = CurrentProject.Connection
Set cmd = New ADODB.Command
With cmd
' create and append parameters ->
Set prm_Rate = .CreateParameter("PalletRate", adDouble, adParamInput, , dblRate)
.Parameters.Append prm_Rate
Set prm_FromLocationNumber = .CreateParameter("FromLocNo", adInteger, adParamInput, , lngFromLocationNumber)
.Parameters.Append prm_FromLocationNumber
Set prm_ToLocationNumber = .CreateParameter("ToLocNo", adInteger, adParamInput, , lngToLocationNumber)
.Parameters.Append prm_ToLocationNumber
.Parameters.Refresh
For Each param In cmd.Parameters
Debug.Print param.Name, param.Value
Next
.ActiveConnection = cnn ' set the connection
.CommandText = strSQL ' set command text to SQL
.CommandType = adCmdText ' set command type
.Execute p_lRowsUpdated ' execute command
End With
If p_lRowsUpdated > 0 Then updateRoutePairRate = True Else updateRoutePairRate = False
End With
Error_Handler_Exit:
On Error Resume Next
Set cnn = Nothing
Set cmd = Nothing
Exit Function
Error_Handler:
If Err.Number <> 0 Then
If glbDebugMode Then
Select Case DebugOption("Error # " & Err.Number & " was generated by " & Err.Source & " (" & Err.Description & ")")
Case vbAbort, vbIgnore
ProcessError Err.Number, Err.Description, , , "Module", "MAINTENANCE", "Function", "updateRoutePairRate", Erl, True
Case vbRetry
Stop: Resume 0
End Select
Else
ProcessError Err.Number, Err.Description, , , "Module", "MAINTENANCE", "Function", "updateRoutePairRate", Erl, True
End If
End If
Resume Error_Handler_Exit
End Function
Related
I have the following code (which a very helpful person on here wrote based on a previous question). It loops through two tables to determine if an interview is valid and then loops though a gift card table for an unused card. This all works as expected. However, I now realize I need to add a new record to a third table (Receipts) everytime a card is assigned. I have tried using "INSERT INTO..." in the loop but it never puts anything into the Receipts table. The data going to the Receipts table will need to selected from both the Interviews table and the Giftcards table.
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsInterview As DAO.Recordset
Dim rsGiftcard As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT * FROM [SOR 2 UNPAID Intake Interviews]" _
& " WHERE InterviewTypeId='1' " _
& " AND ConductedInterview=1 " _
& " AND StatusId IN(2,4,5,8)" _
& " AND IsIntakeConducted='1' " _
& " ORDER BY InterviewDate ASC;"
Set rsInterview = db.OpenRecordset(strSQL)
If Not (rsInterview.BOF And rsInterview.EOF) Then
strSQL = "SELECT * FROM Giftcard_Inventory_Query" _
& " WHERE CardType=1 " _
& " AND Assigned=0 " _
& " AND Project=3 " _
& " ORDER BY DateAdded ASC, CompleteCardNumber ASC;"
Set rsGiftcard = db.OpenRecordset(strSQL)
If Not (rsGiftcard.BOF And rsGiftcard.EOF) Then
Do
rsGiftcard.Edit
rsGiftcard!DateUsed = Format(Now(), "mm/dd/yyyy")
rsGiftcard!Assigned = "1"
rsGiftcard.Update
db.Execute " INSERT INTO [SOR 2 Intake Receipts] " _
& "(PatientID,GiftCardType,GiftCardNumber,GiftCardMailedDate,InterviewDate,CreatedBy,GpraCollectorID) VALUES " _
& "(rsInterview!PatientID, rsGiftcard!CardType, rsGiftcard!CompleteCardNumber, Now(), rsInterview!InterviewDate, rsInterview!CreatedBy, rsInterview!GpraCollectorID);"
rsGiftcard.MoveNext
rsInterview.MoveNext
Loop Until rsInterview.EOF
End If
End If
sExit:
On Error Resume Next
rsInterview.Close
rsGiftcard.Close
Set rsInterview = Nothing
Set rsGiftcard = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sAssignGiftCards", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
I figured it out. Thanks to everyone who pushed me in the correct direction.
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsInterview As DAO.Recordset
Dim rsGiftcard As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT * FROM [SOR 2 UNPAID Intake Interviews]" _
& " WHERE InterviewTypeId='1' " _
& " AND ConductedInterview=1 " _
& " AND StatusId IN(2,4,5,8)" _
& " AND IsIntakeConducted='1' " _
& " ORDER BY InterviewDate ASC;"
Set rsInterview = db.OpenRecordset(strSQL)
If Not (rsInterview.BOF And rsInterview.EOF) Then
strSQL = "SELECT * FROM Giftcard_Inventory_Query" _
& " WHERE CardType=1 " _
& " AND Assigned=0 " _
& " AND Project=3 " _
& " ORDER BY DateAdded ASC, CompleteCardNumber ASC;"
Set rsGiftcard = db.OpenRecordset(strSQL)
If Not (rsGiftcard.BOF And rsGiftcard.EOF) Then
Do
rsGiftcard.Edit
rsGiftcard!DateUsed = Format(Now(), "mm/dd/yyyy")
rsGiftcard!Assigned = "1"
rsGiftcard.Update
db.Execute " INSERT INTO [SOR 2 Intake Receipts] " _
& "(PatientID,GiftCardType,GiftCardNumber,GiftCardMailedDate,InterviewDate,CreatedBy,GpraCollectorID) VALUES " _
& "('" & rsInterview("PatientID") & "', '" & rsGiftcard("CardType") & "', '" & rsGiftcard("CompleteCardNumber") & "', Now(), '" & rsInterview("InterviewDate") & "', '" & rsInterview("CreatedBy") & "', '" & rsInterview("GpraCollectorID") & "');"
rsGiftcard.MoveNext
rsInterview.MoveNext
Loop Until rsInterview.EOF
End If
End If
sExit:
On Error Resume Next
rsInterview.Close
rsGiftcard.Close
Set rsInterview = Nothing
Set rsGiftcard = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sAssignGiftCards", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
Public Sub UpdateTermFeedbackAddlReqt(ByVal runid As Integer, ByVal BHTerm As String, ByVal username As String, ByVal currtime As Double)
Dim db As DAO.Database
Dim rs As DAO.Recordset
DoCmd.SetWarnings False
Set db = CurrentDb
sql = "SELECT tbl_SCG_ExpectedTraffic.BHTerm, Sum(tbl_SCG_ExpectedTraffic.CurrSent2) AS SumOfCurrSent2, iif(Sum([CurrSent2]) = 0, 0, Sum([Accepted])/Sum([CurrSent2])) AS [Term Accept Rate], Sum(tbl_SCG_ExpectedTraffic.Accepted) AS SumOfAccepted, Sum(tbl_SCG_ExpectedTraffic.Rejected) AS SumOfRejected, Sum(tbl_SCG_ExpectedTraffic.Modified) AS SumOfModified, Sum(tbl_SCG_ExpectedTraffic.CurrCalledin) AS SumOfCalledin, Sum([ExpTotal])-Sum([CurrSent2]) AS [Need to Send]" & _
" FROM tbl_SCG_ExpectedTraffic" & _
" GROUP BY Date(), tbl_SCG_ExpectedTraffic.BHTerm, tbl_SCG_ExpectedTraffic.OptRunID" & _
" HAVING (((tbl_SCG_ExpectedTraffic.OptRunID)=" & runid & ") And BHTerm= """ & BHTerm & """);"
Set rs = db.OpenRecordset(sql, dbOpenDynaset, dbSeeChanges)
DoCmd.RunSQL ("Update tbl_SCG_TerminalFeedback set [CurrentSend2] = " & rs![SumOfCurrSent2] & ", [Term Accept Rate] =" & rs![Term Accept Rate] & ", Accepted= " & rs![SumOfAccepted] & ", Rejected = " & rs![SumOfRejected] & ", Modified =" & rs![SumOfModified] & ", Calledin = " & rs![SumOfCalledin] & ", AddlReqst =" & rs![Need To Send] & _
",[Last Update User] =""" & username & """, [Last Update Time]= " & currtime & " , HrDiff = iif( isnull(DLookup(""SubmissionDT"", ""tbl_SCG_OptRunSummary"", ""OptRunID = " & runid & """)), 0, Round((" & currtime & " - DLookup(""SubmissionDT"", ""tbl_SCG_OptRunSummary"", ""OptRunID =" & runid & """)) * 24, 1))" & _
" where OptRunID = " & runid & " And Term = """ & BHTerm & """")
DoCmd.SetWarnings True
rs.Close
db.Close
End Sub
I keep recieving compiling errors saying that txtlln in the where line cannot be found. I am fairly new to SQL/VBA so I am not sure I am using the correct expressions to have this work.
Private Sub btnlledit_Click()
Dim strSQL As String
SQL = "UPDATE tblll " & _
"SET [Component/Product] = '" & Forms!frmaddll!txtllcomponent & "',[HN] = '" & Forms!frmaddll!txtllhn & "' " & _
"WHERE [LLN] = '" & Forms!frmaddll!txtlln.value & "';"
debug.print sql
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
DoCmd.Requery
Me.Refresh
End Sub
You seem to have a few issues swith your string concatenation.
Private Sub btnlledit_Click()
Dim strSQL As String
SQL = "UPDATE tblll " & _
"SET [Component/Product] = '" & Forms!frmaddll!txtllcomponent & "' " & _
"WHERE [LLN] = '" & Forms!frmaddll!txtlln.value & "';"
debug.print sql
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
DoCmd.Requery
Me.Refresh
End Sub
I have a macro that pulls from an Access DB and writes the recordset to the spreadsheet based upon dates that are entered into a userform. However, if I enter in "3/2/2105" and "3/5/2015" it returns all the records from 3/2-3/5 and then 3/20-3/31. I cannot think of any reason why it would do this. If anybody could point me in the right direction/make suggestions it would be greatly appreciated.
Sub pullfrommsaccess()
queryform.Show
Dim conn As Object
Dim rs As Object
Dim AccessFile As String
Dim SQL As String
Dim startdate As String
Dim enddate As String
Dim i As Integer
Sheet2.Cells.Delete
Application.ScreenUpdating = False
AccessFile = ThisWorkbook.Path & "\" & "mdidatabase.accdb"
On Error Resume Next
Set conn = CreateObject("ADODB.connection")
If Err.Number <> 0 Then
MsgBox "Connection was not created!", vbCritical, "Connection Error"
Exit Sub
End If
On Error GoTo 0
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & AccessFile
If tblname = "Attainments" Then
If shift1 = "1" Then
SQL = "SELECT [Line],[Area],[Shift],[Attainment Percentage],[Date] FROM " & tblname & " WHERE Shift='1' and Date Between " & "'" & pastdate & "' " & "and" & " '" & currentdate & "'"
End If
If shift2 = "2" Then
SQL = "SELECT [Line],[Area],[Shift],[Attainment Percentage],[Date] FROM " & tblname & " WHERE Shift='2' and Date Between " & "'" & pastdate & "' " & "and" & " '" & currentdate & "'"
End If
If shift1 = "1" And shift2 = "2" Then
SQL = "SELECT [Line],[Area],[Shift],[Attainment Percentage],[Date] FROM " & tblname & " WHERE Date Between " & "'" & pastdate & "' " & "and" & " '" & currentdate & "'"
End If
End If
If tblname = "MDItable" Then
If shift1misses = "1" Then
SQL = "SELECT [Date],[Area],[Shift],[Line],[Quantity],[Issue] FROM " & tblname & " WHERE Shift='1' and Date Between " & "'" & pastdatemisses & "' " & "and" & " '" & currentdatemisses & "'"
End If
If shift2misses = "2" Then
SQL = "SELECT [Date],[Area],[Shift],[Line],[Quantity],[Issue] FROM " & tblname & " WHERE Shift='2' and Date Between " & "'" & pastdatemisses & "' " & "and" & " '" & currentdatemisses & "'"
End If
If shift1misses = "1" And shift2misses = "2" Then
SQL = "SELECT [Date],[Area],[Shift],[Line],[Quantity],[Issue] FROM " & tblname & " WHERE Date Between " & "'" & pastdatemisses & "' " & "and" & " '" & currentdatemisses & "'"
End If
End If
On Error Resume Next
Set rs = CreateObject("ADODB.Recordset")
If Err.Number <> 0 Then
Set rs = Nothing
Set conn = Nothing
MsgBox "Recordset was not created!", vbCritical, "Recordset Error"
Exit Sub
End If
On Error GoTo 0
rs.CursorLocation = 3
rs.CursorType = 1
rs.Open SQL, conn
If rs.EOF And rs.BOF Then
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
Application.ScreenUpdating = True
MsgBox "There are no records in the recordset!", vbCritical, "No Records"
Exit Sub
End If
For i = 0 To rs.Fields.Count - 1
Sheet2.Cells(1, i + 1) = rs.Fields(i).Name
Next i
'Copy From RecordSet to Excel and Reset
Sheet2.Range("A2").CopyFromRecordset rs
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
MsgBox "The records from " & pastdate & " and " & currentdate & " were successfully retrieved from the '" & tblname & "' table!", vbInformation, "Done"
End If
Call TrimALL
End Sub
You have a field named Date, try renaming that and reworking the code as in first instance that's a reserved word and is a bad idea for starters!
When working with dates, see Allen Browne's comments on the matter here for consistency;
http://allenbrowne.com/ser-36.html
You have your dates declared as string, but in your SQL query you're surrounding them with a ' not a #. It should read;
Date Between " & "#" & pastdate & "# " & "and" & " #" & currentdate & "#"
All of the above should sort you out, if not comment and I'll take a much closer look for you!
I have problem with this UPDATE query , I have got message about syntax error query. I think that this query is correct and I can't find what is giving this error.
Link to error
Private Sub cmdModifyBook_Click() 'approves modifying books to the database
Dim str As String
Dim dbs As DAO.Database
Set dbs = CurrentDb()
'checks if the typed all the data of book
If (Me.txtModifyTitle.Value = "") Or (Me.txtModifyTitleWeb.Value = "") Or (Me.txtModifyVerkaufpreis.Value = "") _
Or (Me.txtModifyThemengruppe.Value = "") Then
MsgBox "Nicht alle von Ihnen eingegebenen Daten"
Exit Sub
End If
str = " UPDATE Katalog " _
& "(Bezeichnung, BezeichnungWeb, Verkaufspreis, Themengruppe) SET " _
& "('" & Me.txtModifyTitle.Value & "', '" & Me.txtModifyTitleWeb.Value & "', '" & Me.txtModifyVerkaufpreis.Value & "', '" & Me.txtModifyThemengruppe.Value & "') WHERE ID_Buch =" & Me.lblModifyID.Caption & ";"
dbs.Execute str, dbFailOnError
MsgBox "Das Buch wurde in der Datenbank geändert", vbInformation
dbs.Close
Set dbs = Nothing
End Sub
Your code should look like this instead:
Private Sub cmdModifyBook_Click() 'approves modifying books to the database
Dim str As String
Dim dbs As DAO.Database
Set dbs = CurrentDb()
'checks if the typed all the data of book
If (Me.txtModifyTitle.Value = "") Or (Me.txtModifyTitleWeb.Value = "") Or (Me.txtModifyVerkaufpreis.Value = "") _
Or (Me.txtModifyThemengruppe.Value = "") Then
MsgBox "Nicht alle von Ihnen eingegebenen Daten"
Exit Sub
End If
str = "UPDATE Katalog " & _
"SET Bezeichnung = '" & PQ(Me.txtModifyTitle.Value) & "', " & _
"BezeichnungWeb = '" & PQ(Me.txtModifyTitleWeb.Value) & "', " & _
"Verkaufspreis = '" & PQ(Me.txtModifyVerkaufpreis.Value) & "', " & _
"Themengruppe = '" & PQ(Me.txtModifyThemengruppe.Value) & "' " & _
"WHERE ID_Buch = " & Me.lblModifyID.Caption & ";"
Debug.Print str
MsgBox str
dbs.Execute str, dbFailOnError
MsgBox "Das Buch wurde in der Datenbank geändert", vbInformation
dbs.Close
Set dbs = Nothing
End Sub
Private Function PQ(s as string) as String
PQ = Replace(s, "'", "''")
End Function
Be aware that you need to replace any single quotes that might exist inside the values from the textboxes with two single quotes to prevent SQL errors. That's why I posted the PQ function.
The UPDATE command syntax is as follows
UPDATE Katalog
SET
Bezeichnung = Me.txtModifyTitle.Value ,
BezeichnungWeb = Me.txtModifyTitleWeb.Value ,
Verkaufspreis = Me.txtModifyVerkaufpreis.Value,
Themengruppe = Me.txtModifyThemengruppe.Value
WHERE ID_Buch = Me.lblModifyID.Caption
Of course the above will now work since you have to adopt it for str variable