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

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

Related

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.

VBA/Microsoft Access Macro - SELECT from all tables, export results to flat files

I am trying to write a macro in Microsoft Access to accomplish the following:
For a list of linked tables (ODBC connection):
-SELECT top 10 records
-export results of each query to either Excel or CSV file of title [table_name] + suffix, i.e., "tablename1_10", "tablename2_10", etc. to a designated folder
======================
UPDATE:
======================
I now have a script, which despite my previous error with the ODBC connection, works when I do not try to declare an ODBC Connection String and declare "qdf.Open".
Macro below, with small edits for anonymity:
Sub queryAllTables()
Dim tables() As String
tables = Split("<table names>", ",")
For Each element In tables
Dim elm As String
elm = element
Call sExportTop10(elm, "<folder>", False)
Next element
End Sub
Sub sExportTop10(strTable As String, strFolder As String, blnExcel As Boolean)
On Error GoTo E_Handle
Dim strFile As String
Dim strSQL As String
If Right(strFolder, 1) <> "\" Then strFolder = strFolder & "\"
strFile = strFolder & strTable
strSQL = "SELECT TOP 10 * FROM [" & strTable & "];"
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
For Each MyQueryDef In CurrentDb.QueryDefs
If MyQueryDef.Name = "qdfExport" Then
CurrentDb.QueryDefs.Delete ("qdfExport")
Exit For
End If
Next
Set dbs = CurrentDb()
Set qdf = dbs.CreateQueryDef("qdfExport")
qdf.ReturnsRecords = False
qdf.SQL = strSQL
qdf.OpenRecordSet
If blnExcel = True Then
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "qdfExport", strFile & "_10.xlsx", True
Else
DoCmd.TransferText acExportDelim, , "qdfExport", strFile & "_10.csv", True
End If
sExit:
On Error Resume Next
Exit Sub
E_Handle:
Msg = "Error # " & Str(Err.Number) & " was generated by " _
& Err.Source & Chr(13) & Err.Description
MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
Resume sExit
End Sub
I would suggest that you create a procedure that does the exporting to Excel/CSV, and then you can call it each time to do the exporting. In addition, you will need a Query called "qdfExport" that you will use to modify the SQL to get the top 10 records. Some VBA would look like:
Sub sExportTop10(strTable As String, strFolder As String, blnExcel As Boolean)
On Error GoTo E_Handle
Dim strFile As String
Dim strSQL As String
If Right(strFolder, 1) <> "\" Then strFolder = strFolder & "\"
strFile = strFolder & strTable
strSQL = "SELECT TOP 10 * FROM [" & strTable & "] ORDER BY 1 ASC;"
CurrentDb.QueryDefs("qdfExport").SQL = strSQL
If blnExcel = True Then
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "qdfExport", strFile & "_10.xlsx", True
Else
DoCmd.TransferText acExportDelim, , "qdfExport", strFile & "_10.csv", True
End If
sExit:
On Error Resume Next
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sExportTop10", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
And you would then call it as:
call sExportTop10("tblPrintID","C:\test",False)
Which would export the top 10 records from a table called "tblPrintID" to a CSV file in the folder "C:\test".
In the procedure, I have used ORDER BY 1 in the SQL, which ensures that the data is sorted by the first field, which is where the primary key is always located in my tables. If there is no order in the table, then there is no guarantee what order will be used.
Regards,

Email each account their own pdf report gets run time error 3265

Please see code below that returns a run-time error 3265 due to the line:
strTo = !email_address1
however, if i changed it to
strTo = !AccountNumber it will populate in the outlook email To: line properly but i need the email address, not the account number - do i need to define email_address1? it is a short text field in my query/report. if so, how do i define it? totally new to access.
Option Compare Database
Sub Mac1()
Dim rsAccountNumber As DAO.Recordset
Dim strTo As Variant
Dim strSubject As String
Dim strMessageText As String
Set rsAccountNumber = CurrentDb.OpenRecordset("SELECT DISTINCT AccountNumber, email_address1 FROM [P3_DVP_UnAffirmed_Report_for_En Query]", dbOpenSnapshot)
With rsAccountNumber
Do Until .EOF
DoCmd.OpenReport "Unaffirmed Report", _
acViewPreview, _
WhereCondition:="AccountNumber = '" & !AccountNumber & "'", _
WindowMode:=acHidden
strTo = !Email_Address1
strSubject = "Invoice Number "
strMessageText = "Text Here"
DoCmd.SendObject ObjectType:=acSendReport, _
ObjectName:="Unaffirmed Report", _
OutputFormat:=acFormatPDF, _
To:=strTo, _
Subject:=strSubject, _
MESSAGETEXT:=strMessageText, _
EditMessage:=True
DoCmd.Close acReport, "Unaffirmed Report", acSaveNo
.MoveNext
Loop
.Close
End With
End Sub
In your SELECT list you should specify the email_address1 field so:
Set rsAccountNumber = CurrentDb.OpenRecordset("SELECT DISTINCT AccountNumber, email_address1 FROM [P3_DVP_UnAffirmed_Report_for_En Query]",dbOpenSnapShot)

Rule does not run when a new email comes in

I worked out the code below to save an attachment to an email, to a mapped network drive, based on the subject line. However the rule in Outlook 2010 (xp OS) doesn't work when a new email comes in. It doesn't save it to the specified location. When I run the rule manually it works great.
I have enabled all macros. restarted Outlook no change. I have made macros prompt when running. It prompts when a new email comes in. I hit enable no save, no error that it didn't save.
Public Sub SaveAttachments2(mail As Outlook.MailItem)
On Error GoTo GetAttachments_err
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim f As String
Dim strSubject As String
Dim w As Integer
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
For Each Item In Inbox.Items
strSubject = Item.Subject
f = strSubject
Rem MkDir ("Z:\OPERATIO\AS400_Report\" & f)
For Each Atmt In Item.Attachments
FileName = "Z:\OPERATIO\AS400_Reports\" & f & "\" & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
'commented out and added rule option to delete the item
Next Atmt
'Item.Delete
GetAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
GetAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveAttachments2" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
'added next because of compile error
Next
End Sub
You cannot change standalone VBA by simply adding (mail As Outlook.MailItem).
Public Sub SaveAttachments2(mail As Outlook.mailItem)
Dim Atmt As attachment
Dim FileName As String
Dim f As String
f = Trim(mail.Subject) ' Removes spaces at ends. This is a big problem.
On Error Resume Next
MkDir ("Z:\OPERATIO\AS400_Report\" & f) ' Creates a folder if it does not exist
On Error GoTo GetAttachments_err
For Each Atmt In mail.Attachments
FileName = "Z:\OPERATIO\AS400_Reports\" & f & "\" & Atmt.FileName
Atmt.SaveAsFile FileName
' Fails on subjects with illegal characters.
' For example when RE: and FW: in the subject the folder cannot be created.
Next Atmt
GetAttachments_exit:
Exit Sub
GetAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveAttachments2" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
End Sub
See here if illegal characters cause problems creating folders. Save mail with subject as filename

Outlook Macro to save attachments from public mailbox

I have the following macro, it all works fine but I would like it to read a public mailbox instead of the inbox, I would also like it to move the emails that have been processed to a different folder:
Option Explicit
Sub SaveSubFolderAttachments()
On Error GoTo SaveAttachmentsToFolder_err
' Declare variables
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim varResponse As VbMsgBoxResult
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set SubFolder = Inbox.Folders("Test") ' Enter correct subfolder name.
i = 0
' Check subfolder for messages and exit of none found
If SubFolder.Items.Count = 0 Then
MsgBox "There are no messages in folder.", vbInformation, _
"Nothing Found"
Exit Sub
End If
' Check each message for attachments
For Each Item In SubFolder.Items
For Each Atmt In Item.Attachments
FileName = "S:\SME folder\Registrations\NKC Test Email Extract\" & _
Format(Item.CreationTime, "yyyymmdd_hhnnss_") & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
Next Atmt
Next Item
' Show summary message
If i > 0 Then
varResponse = MsgBox("I found " & i & " attached files." _
& vbCrLf & "I have saved them into the S:\SME folder\Registrations\NKC Test Email Extract\ folder." _
& vbCrLf & vbCrLf & "Would you like to view the files now?" _
, vbQuestion + vbYesNo, "Finished!")
' Open Windows Explorer to display saved files if user chooses
If varResponse = vbYes Then
Shell "Explorer.exe /e,S:\SME folder\Registrations\NKC Test Email Extract\", vbNormalFocus
End If
Else
MsgBox "I didn't find any attached files in your mail.", vbInformation, "Finished!"
End If
' Clear memory
SaveAttachmentsToFolder_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
' Handle Errors
SaveAttachmentsToFolder_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachmentsToFolder_exit
End Sub
By "public mailbox", do you mean another user's mailbox? Use GetSharedDefaultFolder instead of GetDefaultFolder.