How to handle errors on broken table links - vba

I have recently updated my linked tables to use UNC links. However when I test the front end using a machine which does not have the mapped drives,
my error handling procedure fails in line Set rs = CurrentDb.OpenRecordset("SELECT ItemName FROM tblDonatedItems") with error number 3044
Is there a way of trapping the error so that the procedure can keep running? Please see below:
Private Sub Form_Load()
On Error Resume Next
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("SELECT ItemName FROM tblDonatedItems")
If Err.Number <> 0 Then
MsgBox "Error Number: " & Err.Number & " " & Err.Description & " Please link to backend file!", , "Locate backend file"
Call AttachDataFile
End If
rs.Close
Set rs = Nothing
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "frmSplash"
End Sub
I have also tried this without success:
Private Sub Form_Load()
On Error GoTo ErrorHandler
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("SELECT ItemName FROM tblDonatedItems")
ErrorHandler:
If Err.Number <> 0 Then
MsgBox "Error Number: " & Err.Number & " " & Err.Description & " Please link to backend file!", , "Locate backend file"
Call AttachDataFile
rs.Close
Set rs = Nothing
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "frmSplash"
Else: MsgBox ("Error! Please email: info#abc.com Quoting Error Number: " & " Err.Number"), vbCritical
DoCmd.OpenForm "frmSplash"
End If
End Sub

Related

In Access how can I make the email address to send to conditional based on a table of contacts?

I set up a code to save each page of a report as a separate PDF with the file name being the "release number"
I was able to get it to email each file in a separate email to a single email address.
But I can't figure out how to have the email recipient be dependent on the field "account"?
I have a table called "Distribution list" with the fields "Company" (the account name) and "Email".
I want it to send to the corresponding email for each company/account.
How could I achieve this?
Private Sub Command11_Click()
Dim rs As DAO.Recordset
Dim sFolder As String
Dim sFile As String
Const sReportName = "BLreport2"
'Dim strTo As String
' Dim strMessage As String
'Dim strSubject As String
On Error GoTo Error_Handler
'The folder in which to save the PDFs
sFolder = Application.CurrentProject.Path & "\"
'Define the Records that you will use to filtered the report with
Set rs = CurrentDb.OpenRecordset("SELECT account, [release number], contents3 FROM selectedbols", dbOpenSnapshot)
With rs
If .RecordCount <> 0 Then 'Make sure we have record to generate PDF with
.MoveFirst
Do While Not .EOF
'Build the PDF filename we are going to use to save the PDF with
sFile = sFolder & Nz(![release number], "") & ".pdf"
'Open the report filtered to the specific record or criteria we want in hidden mode
DoCmd.OpenReport sReportName, acViewPreview, , "[release number]=" & ![release number], acHidden
'Print it out as a PDF
DoCmd.OutputTo acOutputReport, sReportName, acFormatPDF, sFile, , , , acExportQualityPrint
'Close the report now that we're done with this criteria
'strTo = test#gmail.com
' strSubject = "Your invoice"
'strMessage = "Please find the invoice attached"
'DoCmd.SendObject acSendReport, "BLreport2", acFormatPDF, _
strTo, , , strSubject, strMessage
DoCmd.Close acReport, sReportName
'If you wanted to create an e-mail and include an individual report, you would do so now
.MoveNext
Loop
End If
End With
'Open the folder housing the PDF files (Optional)
Application.FollowHyperlink sFolder
Error_Handler_Exit:
On Error Resume Next
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
Exit Sub
Error_Handler:
If Err.Number <> 2501 Then 'Let's ignore user cancellation of this action!
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: Command0_Click" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
End If
Resume Error_Handler_Exit
End Sub

Loop through continuous form records and adding them to a table

Good afternoon,
I have a bound continuous form with a yes/no checkbox for each of the records shown. I'd like to have my users be able to click a "Select all" control and automatically have each one of those records be added to a different table.
So far, I have my loop working but not quite sure where to insert the proper code to add the records. I am using a frame control with a with a "Select all" "Deselect all" options. The [PrintPart] is the Yes/No field in the form.
Many thanks.
Private Sub SelectionFrame_Click()
Dim SQL as String
On Error GoTo errHandler
SQL = "INSERT INTO PARTS_T ([PRINTORDER], [PART_TITLE], [PARTID])
VALUES (" & Me.RecordsetClone.RecordCount + 1 & "," & Chr(34) &
Me.PART_TITLE & Chr(34) & "," & Me.PARTID & ");"
'Toggle select/deselect all
Select Case Me.SelectionFrame
Case 1 'Select
With Me.RecordsetClone
.MoveFirst
Do While Not .EOF
.Edit
!PrintPart = True
RunSQLCode
.Update
.MoveNext
Loop
End With
Case 2 'Deselect
With Me.RecordsetClone
.MoveFirst
Do While Not .EOF
.Edit
!PrintPart = False
.Update
.MoveNext
Loop
End With
End Select
Exit Sub
errHandler:
MsgBox "The following error has occurred: " & vbNewLine & vbNewLine & "Error Number: " & Err.Number & vbNewLine & "Error Description: " & Err.Description, vbCritical, "Error - " & APPNAME
End Sub
Don't run repeated SQL. DAO is way simpler and faster:
Private Sub SelectionFrame_Click()
Dim Source As DAO.Recordset
Dim Target As DAO.Recordset
Dim SQL As String
Dim PrintPart As Boolean
Dim PrintOrder As Long
On Error GoTo errHandler
Set Source = Me.RecordsetClone
PrintOrder = Source.RecordCount
If PrintOrder > 0 Then
SQL = "Select * From PARTS_T"
Set Target = CurrentDb.OpenRecordset(SQL, dbOpenDynaset, dbAppendOnly)
PrintPart = Me.SelectionFrame
Source.MoveFirst
While Not Source.EOF
If Source!PrintPart.Value <> PrintPart Then
Source.Edit
Source!PrintPart.Value = PrintPart
Source.Update
End If
Target.AddNew
Target!PRINTORDER.Value = PrintOrder + 1
Target!PART_TITLE.Value = Source!PART_TITLE.Value
Target!PARTID.Value = Source!PARTID.Value
Target.Update
Wend
Target.Close
End If
Source.Close
Exit Sub
errHandler:
MsgBox "The following error has occurred: " & vbNewLine & vbNewLine & "Error Number: " & Err.Number & vbNewLine & "Error Description: " & Err.Description, vbCritical, "Error - " & APPNAME
End Sub

MS Access: Trying to create an error if there is a duplicate record but code flags everything

I have a form that if a duplicate record is entered, the form creates an error message and prevents the record from being entered. However, my code is popping up the error message no matter what I'm putting in. My code is this...
Private Sub cmdSave_Click()
' ToDo fix the labels in this function so they match the function name. Just cosmetic.
On Error GoTo Add_CmdSave_Click_Err
On Error Resume Next
' ToDo fix the labels in this function so they match the function name. Just cosmetic.
On Error GoTo Add_CmdSave_Click_Err
On Error Resume Next
Me.cbCompletedTrainingID = Me.IntermediateID
'
Dim OKToSave As Boolean
OKToSave = True
If Not SomethingIn(Me.[fIntermediate FacultyID]) Then ' Null
Beep
MsgBox "A faculty member is required", vbOKOnly, "Missing Information"
OKToSave = False
End If
If Not SomethingIn(Me.[fIntermediate TrainingID]) Then
Beep
MsgBox "A training is required", vbOKOnly, "Missing Information"
OKToSave = False
Else
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[IntermediateID] = " & Me.[fIntermediate FacultyID] And Me.[fIntermediate TrainingID]
If Not rs.EOF Then
Beep
MsgBox "This person has already completed this training", vbOKOnly, "Duplicate Training Completion"
OKToSave = False
End If
End If
If OKToSave Then
' If we get this far, all data is valid and it's time to save
Me.Dirty = False
DoCmd.GoToRecord , "", acNewRec
End If
Add_CmdSave_Click_Exit:
Exit Sub
Add_CmdSave_Click_Err:
Resume Add_CmdSave_Click_Exit
End Sub
The issue, from my standpoint, lies in this part...
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[IntermediateID] = " & Me.[fIntermediate FacultyID] And Me.[fIntermediate TrainingID]
If Not rs.EOF Then
Beep
MsgBox "This person has already completed this training", vbOKOnly, "Duplicate Training Completion"
OKToSave = False
End If
What am I doing wrong?
Have a look at How to debug dynamic SQL in VBA.
This line makes no sense as it is:
rs.FindFirst "[IntermediateID] = " & Me.[fIntermediate FacultyID] And Me.[fIntermediate TrainingID]
You probably want something like
S = "[IntermediateID] = " & Me.[fIntermediate FacultyID] & " And [TrainingID] = " & Me.[fIntermediate TrainingID]
Debug.Print S ' Ctrl+G shows the output
rs.FindFirst S
Also, remove all these On Error Resume Next - this will happily ignore any errors, making debugging nearly impossible.
Also useful: Debugging VBA Code
And there is more: If Recordset.FindFirst doesn't find a match, it doesn't trigger .EOF. It sets the .NoMatch property.
rs.FindFirst S
If rs.NoMatch Then
' all is good, proceed to save
Else
' record exists
End If
This should work as intended:
Dim rs As DAO.Recordset
Dim Criteria As String
Set rs = Me.RecordsetClone
Criteria = "[IntermediateID] = " & Me![fIntermediate FacultyID].Value & " And [TrainingID] = " & Me![fIntermediate TrainingID].Value & ""
Debug.Print OKToSave, Criteria
rs.FindFirst Criteria
If Not rs.NoMatch Then
Beep
MsgBox "This person has already completed this training", vbInformation + vbOKOnly, "Duplicate Training Completion"
OKToSave = False
End If
rs.Close
Debug.Print OKToSave

printing report to PDF based on each record in query

I have a query in Access (Q_Invoices) that has separate records based on the invoice number (Invoice_Number). I also have a report that is linking to this query (R_Invoices_PDF). What I would like to do is to have VBA code to loop through each record in the query, and print the record as a separate PDF from the report.
I copied the following code from some website, and tried to adapt it for my purposes. It works to an extent. However, I stop it before it loops, and it saves all the records, not just the first one.
Private Sub cmd_GenPDFs_Click()
Dim rs As DAO.Recordset
Dim sFolder As String
Dim sFile As String
On Error GoTo Error_Handler
sFolder = "D:\Documents\Orchestra\Invoices\Invoice files\"
Set rs = CurrentDb.OpenRecordset("SELECT Invoice_Number FROM Q_Invoices", dbOpenSnapshot)
With rs
.MoveFirst
Do While Not .EOF
DoCmd.OpenReport "R_Invoices_PDF", acViewPreview, , "[Invoice_Number]=" & ![Invoice_Number], acHidden
sFile = Nz(![Invoice_Number], "") & ".pdf"
sFile = sFolder & sFile
DoCmd.OutputTo acOutputReport, "R_Invoices_PDF", acFormatPDF, sFile, acExportQualityPrint
'If you wanted to create an e-mail and include an individual report, you would do so now
DoCmd.Close acReport, "R_Invoices_PDF"
.MoveNext
Loop
End With
Application.FollowHyperlink sFolder 'Optional / Open the folder housing the files
Error_Handler_Exit:
On Error Resume Next
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
Exit Sub
Error_Handler:
If Err.Number <> 2501 Then 'Let's ignore user cancellation of this action!
MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: cmd_GenPDFs_Click" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occured!"
End If
Resume Error_Handler_Exit
End Sub
I recall some issue with filtering the report. Thus, we filter the query that drives the report to return only data for a single invoice using a TempVars.
Here, Faktura means Invoice:
Private Sub FakturaPrint( _
ByVal PrintType As CdPrintType, _
Optional ByRef FullPath As String)
Const ReportName As String = "Faktura"
Const FileNameMask As String = "Faktura{0}.pdf"
Const FileIdMask As String = "kladde Job {0}"
Const CancelError As Long = 2212 ' Cactus TimeSag cannot print the object.
Const PrintError As Long = 2501 ' PrintOut was cancelled.
Dim Path As String
Dim FileName As String
Dim FileId As String
Dim PrintCount As Integer
Dim PrintCopy As Integer
On Error GoTo FakturaPrint_Click_Error
' Set filter on the source query of the report.
TempVars("FakturaID").Value = Me!FaktID.Value
Select Case PrintType
Case cdPrintPreview
DoCmd.OpenReport ReportName, acViewPreview, , , acWindowNormal
Case cdPrintPrinter
PrintCount = Nz(Me!UdskFakt.Column(2), 1)
If PrintCount < 1 Then
PrintCount = 1
End If
For PrintCopy = 1 To PrintCount
DoCmd.OpenReport ReportName, acViewNormal, , , acWindowNormal
Next
Case cdPrintPdf
Path = Environ("USERPROFILE") & "\Documents\"
FileId = Nz(Str(Me!Faktura.Value), Replace(FileIdMask, "{0}", Me!JobID.Value))
FileName = Replace(FileNameMask, "{0}", FileId)
' Return FullPath by reference for e-mail.
FullPath = Path & FileName
DoCmd.OutputTo acOutputReport, ReportName, acFormatPDF, FullPath, False, , , acExportQualityPrint
End Select
FakturaPrint_Click_Exit:
Me!TextForClipboard.SetFocus
Exit Sub
FakturaPrint_Click_Error:
Select Case Err.Number
Case CancelError, PrintError
' Printing cancelled by user.
' Ignore.
Case Else
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure FakturaPrint_Click of Sub Form_Faktura"
End Select
Resume FakturaPrint_Click_Exit
End Sub
It is not a loop, but you can probably easily abstract from that.

MS ACCESS 2007 - Deleting a specific record using an unbound value

I have a subfrom 'Crew' with 3 field text boxes inside of that named CrewName, KitNumber, and ActionDate. This form gets populated with data from a button. What I want to do is have a user enter a number, say "111111" in this unbound text field called 'ClearEntry' outside of the Crew subform. I then have a command button under that named 'ClearSelected' that, when clicked, will clear the corresponding record in my Crew subform. So basically I want to enter text in this unbound, hit the button, and have that number correspond with the same number in the Crew Subform, and delete the record in that form. My code I have now for the command button is below.
Private Sub ClearSelected_Click()
DoCmd.SetWarnings False
DoCmd.RunSQL = "DELETE FROM Crew WHERE KitNumber = '" & Me.ClearEntry & "'"
Crew.Form.Requery
End Sub
Can this be done?
The "argument not optional" compile error is caused by the = sign after DoCmd.RunSQL. Get rid of it:
DoCmd.RunSQL "DELETE * FROM Crew WHERE KitNumber = '" & Me.txtClearKitEntry& "'"
Then you will get an error complaining about "type mismatch in criteria" because Crew.KitNumber is numeric not text. So do not add the single quotes around Me.txtClearKitEntry.
DoCmd.RunSQL "DELETE * FROM Crew WHERE KitNumber = " & Me.txtClearKitEntry
However I'll suggest this approach instead of DoCmd.RunSQL. When you're not using RunSQL, you won't be motivated to turn SetWarnings off (False).
Private Sub ClearKitSelected_Click()
Dim strMsg As String
Dim strSql As String
On Error GoTo ErrorHandler
strSql = "DELETE FROM Crew WHERE KitNumber = " & Me.txtClearKitEntry
CurrentDb.Execute strSql, dbFailOnError
Me.Crew.Requery
ExitHere:
On Error GoTo 0
Exit Sub
ErrorHandler:
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure ClearKitSelected_Click of Form_Search"
MsgBox strMsg
GoTo ExitHere
End Sub
This was how I finally was able to get it to work correctly:
Private Sub cmdDelete_Click()
Dim strMsg As String
Dim strSql As String
If Me.Dirty Then
Me.Dirty = False
End If
On Error GoTo ErrorHandler
Const MESSAGETEXT = "Are you sure you wish to delete the current record?"
If MsgBox(MESSAGETEXT, vbYesNo + vbQuestion, "Confirm") = vbNo Then
Cancel = True
End If
strSql = "DELETE FROM Item WHERE ID = " & Me.txtID2
CurrentDb.Execute strSql, dbFailOnError
MsgBox "The Item list has been updated"
Clear
List40.Requery
ExitHere:
On Error GoTo 0
Exit Sub
ErrorHandler:
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure Delete of Items"
MsgBox strMsg
GoTo ExitHere
End Sub