I am trying to send separate Employees a PDF/page of their section/report. The information is based on their EmployeeID (which is text not long number). So each person has their balance information on a page then there's a page break, and then next page shows the next person's details. With the code below, it does email each of the employees one page but it so happens to only email the first person's page to EVERYONE. Is it possible to somehow automate each week so that each user is emailed his/her individual page of the report?
Another error is that the email pop up one by one so I have to press send each time for over 200 people, and that the email seems to be sending to the email but then followed by #mailto:the email# for example email#email.com#mailto:email#email.com#
I just started Access and have been copying and scraping code off of places I have found online. Many thanks in advance, if you can assist!
Have a great day!
Private Sub cmdSendAll_Click()
Dim rsAccountNumber As DAO.Recordset
Dim strTo As Variant
Dim strSubject As String
Dim strMessageText As String
Set rsAccountNumber = CurrentDb.OpenRecordset("SELECT DISTINCT EmployeeID, [Email] FROM [queAutoUpdate]", dbOpenSnapshot)
Debug.Print strTo
With rsAccountNumber
Do Until .EOF
DoCmd.OpenReport "test", _
acViewPreview, _
WhereCondition:="EmployeeID = '" & !EmployeeID & "'", _
WindowMode:=acHidden
strTo = ![Email]
strSubject = "Updated Balance "
strMessageText = "Text Here"
DoCmd.SendObject ObjectType:=acSendReport, _
ObjectName:="test", _
OutputFormat:=acFormatPDF, _
To:=strTo, _
Subject:=strSubject, _
MESSAGETEXT:=strMessageText, _
EditMessage:=True
DoCmd.Close acReport, "Unaffirmed Report", acSaveNo
.MoveNext
Loop
.Close
End With
End Sub
Your opening a report called test and then closing another report called "Unaffirmed Report". You need to open and close the same report, in this case "test".
DoCmd.Close acReport, "test", acSaveNo. This should fix the employee data not updating, since the report remains open on the first employee.
To directly send the message you need change EditMessage:=True to EditMessage:=False.
Check the docs:
https://learn.microsoft.com/en-us/office/vba/api/access.docmd.sendobject
Also if you need to test this, set outlook in Offline mode, and run your code, check the messages in your Outbox to see if they're as expected. You can delete the messages from the Outbox to prevent them from being sent. Once you're finished with testing you can set Outlook back to Online Mode.
Regarding the email address issue, this comes automatically when using hyperlinks in your controls. You'll need to strip the extra part out with strTo = Left(![Email],InStr(![Email],"#")-1). Check your data if this will be valid for all email addresses. For a more advanced solution you can look at this post https://codekabinett.com/rdumps.php?Lang=2&targetDoc=access-hyperlink-data-type.
Code provided as reference, please see the post for the explanation.
'copied from https://codekabinett.com/rdumps.php?Lang=2&targetDoc=access-hyperlink-data-type
Public Function GetHyperlinkFullAddress(ByVal hyperlinkData As Variant, Optional ByVal removeMailto As Boolean) As Variant
Const SEPARATOR As String = "#"
Dim retVal As Variant
Dim tmpArr As Variant
If IsNull(hyperlinkData) Then
retVal = hyperlinkData
Else
If InStr(hyperlinkData, SEPARATOR) > 0 Then
' I append 4 separators at the end, so I don't have to worry about the
' lenght of the array returned by Split()
hyperlinkData = hyperlinkData & String(4, SEPARATOR)
tmpArr = Split(hyperlinkData, SEPARATOR)
If Len(tmpArr(1)) > 0 Then
retVal = tmpArr(1)
If Len(tmpArr(2)) > 0 Then
retVal = retVal & "#" & tmpArr(2)
End If
End If
Else
retVal = hyperlinkData
End If
If Left(retVal, 7) = "mailto:" Then
retVal = Mid(retVal, 8)
End If
End If
GetHyperlinkFullAddress = retVal
End Function
Consider using the MS Outlook object library to send emails. Whereas DoCmd.SendObject is a convenience handler, you control more of the process with initializing an Outlook application object and creating an Outlook email object setting all needed elements.
However, with this approach you need to first export your filtered report to PDF and then attach to email for final send. See inline comments for specific details.
Dim rsAccountNumber As DAO.Recordset
' CHECK Microsoft Outlook #.# Object Library UNDER Tools/References
Dim olApp As Outlook.Application, olEmail As Outlook.MailItem
Dim fileName As string, todayDate As String, strEmail As String
todayDate = Format(Date, "YYYY-MM-DD")
Set rsAccountNumber = CurrentDb.OpenRecordset("SELECT DISTINCT EmployeeID, [Email] FROM [queAutoUpdate]", dbOpenSnapshot)
Set olApp = New Outlook.Application
With rsAccountNumber
Do Until .EOF
' SETTING FILE NAME TO SAME PATH AS DATABASE (ADJUST AS NEEDED)
fileName = Application.CurrentProject.Path & "\Balance_Report_" & !EmployeeID & "_" & todayDate & ".pdf"
' OPEN AND EXPORT PDF TO FILE
DoCmd.OpenReport "test", acViewPreview, "EmployeeID = '" & !EmployeeID & "'"
' INTENTIONALLY LEAVE REPORT NAME BLANK FOR ABOVE FILTERED REPORT
DoCmd.OutputTo acReport, , acFormatPDF, fileName, False
DoCmd.Close acReport, "test"
' CREATE EMAIL OBJECT
strEmail = ![Email]
Set olEmail = olApp.CreateItem(olMailItem)
With olEmail
.Recipients.Add strEmail
.Subject = "Updated Balance"
.Body = "Text Here"
.Attachments.Add fileName ' ATTACH PDF REPORT
.Send ' SEND WITHOUT DISPLAY TO SCREEN
End With
Set olEmail = Nothing
.MoveNext
Loop
.Close
End With
MsgBox "All emails successfully sent!", vbInformation, "EMAIL STATUS"
Set rsAccountNumber = Nothing: Set olApp = Nothing
Related
I'm placing my email body inside a table to easily edit the content. The problem is that there is some variables I need to use inside that body content.
For example:
I use the code bellow to send the email. And as you can see, my email body comes from a memo field inside my table (.HTMLBody = "" & Me.Html_Email_Body & "") and I need to use some variables inside the Html_Email_Body field like so:
(This is the text that I have inside my memo field)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head></head>
<body>
Hi " & Me:PersonName & ", how are you?
</body>
</html>
The output result is: Hi " & Me.PersonName & ", how are you?
And the output result should be: Hi Bob, how are you?
Is this possible?
(This is the code I use to send my emails)
Sub SendEmail_Click()
Dim NewMail As CDO.Message
Set NewMail = New CDO.Message
'Enable SSL Authentication
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
'Make SMTP authentication Enabled=true (1)
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
'Set the SMTP server and port Details
'To get these details you can get on Settings Page of your Gmail Account
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
'Set your credentials of your Gmail Account
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusername") = "mysite#gmail.com"
NewMail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "mypassword7"
'Update the configuration fields
NewMail.Configuration.Fields.Update
'Set All Email Properties
With NewMail
Dim strPath As String
strPath = ".mysite/wp-content/uploads/2017/07/myimage.png"
.subject = "this is the subject"
.From = "<mail#mysite.com>"
.To = Me.EMAIL
'.CC = ""
'.BCC = ""
.HTMLBody = "" & Me.Html_Email_Body & ""
.AddAttachment "https://mysite/temp/contacts.vcf"
End With
NewMail.Send
MsgBox ("This email was sent!")
'Set the NewMail Variable to Nothing
Set NewMail = Nothing
End Sub
I do this kind of thing in many of my applications. I insert Field References into my email templates and then use a routine I wrote to replace them dynamically with the correct values at runtime. In my case, this is usually done in a loop with a RecordSet that contains several people who are each receiving an individual copy of the email message and I am customizing the template for each recipient.
Here is a small sample email template:
<p>Hello [RecipFirstName],</p> This auto-generated email has been sent to notify you that:
<h4>Approval Mailed is <b>LATE</b>.</h4>
Approval Mailed Date: [ApprovalMailed_Date]
[ProjectTemplate1]
Then my code to fill the template looks like:
'[mBody] is a string that will be the Body of the email
'[templateBody] is a string that was previously set to the email
' template for the message being processed
'[rstProject] is a DAO.RecordSet that was previously set to the
' required dataset for my purposes
'Notice that I use a combination of [Replace] functions and
' my custom function [sitsProcessFieldReferences] to update the
' template with the appropriate values.
'In my case, replace CRLF in the template with <BR>
mBody = Replace(templateBody, vbCrLf, "<BR>")
mBody = sitsProcessFieldReferences(mBody, rstProject)
'The following examples use variables I have already defined and
' populated to replace the field refernces.
mBody = Replace(mBody, "[RecipFirstName]", FirstName)
mBody = Replace(mBody, "[RecipLastName]", LastName)
mBody = Replace(mBody, "[RecipFullName]", FirstName & " " & LastName)
mBody = Replace(mBody, "[ProjectTemplate1]", pTemplate1)
Finally the function that does the field reference replacement. Notice that I have a special case that if I name a field reference with "price" in the name, I want the replacement value formatted as Currency. You can customize this code for any situation. It just requires some pre-planning to keep a consistent naming convention for your field references.
This function takes an email template (or any text string) and searches it for field names matching any field in the RecordSet (enclosed in square brackets) and replaces that reference with the value from the corresponding field in the RecordSet
Public Function sitsProcessFieldReferences(ByVal orgString As String, rstFields As DAO.Recordset) As String
On Error GoTo Err_PROC
Dim ErrMsg As String
Dim fld As DAO.Field
For Each fld In rstFields.Fields
If InStr(fld.Name, "price") Then
orgString = Replace(orgString, "[" & fld.Name & "]", Format(Nz(fld.Value, 0), "Currency"))
Else
orgString = Replace(orgString, "[" & fld.Name & "]", Nz(fld.Value, ""))
End If
Next fld
Set fld = Nothing
Exit_PROC:
sitsProcessFieldReferences = orgString
Exit Function
Err_PROC:
Select Case Err.Number
Case Else
ErrMsg = "Module: " & strModName & vbCrLf
ErrMsg = ErrMsg & "Error: " & Err.Number & vbCrLf
ErrMsg = ErrMsg & "Line: " & Erl() & vbCrLf
ErrMsg = ErrMsg & Err.Description
DoCmd.Hourglass False
MsgBox ErrMsg, vbOKOnly + vbCritical, "Function sitsProcessFieldReferences"
Resume Exit_PROC
Resume
End Select
End Function
In your email template, you would change the following line:
Hi " & Me:PersonName & ", how are you?
to something like:
Hi [PersonName], how are you?
Then either do a Replace(emailTemplate, [PersonName], "Bob") if you have the replacement values already in a variable or something.
Or, if the value is in a RecordSet, you would change [PersonName] in the template to match the name of the field in the RecordSet that contains the value Bob and then use my custom function: sitsProcessFieldReferences(emailTemplate, YourRecordSet)
I manage to find the solution myself because I couldn't implement #Jericho Johnson although it was somehow useful...
What I did was setup a new variable (MyHTMLBody) for the email body and several replacements as I need (see bellow).
After that, I setup the .HTMLBody = MyHTMLBody this way, and now I can use some bookmarks in the HTML like this: Hi [r_name], how are you? This is your [r_email].
MyHTMLBody = Me.Body
MyHTMLBody = Replace(MyHTMLBody, "[r_name]", Me.Client_Name)
MyHTMLBody = Replace(MyHTMLBody, "[r_email]", Me.Client_Email)
.HTMLBody = MyHTMLBody
I'm really new to Access so I haven't heard of most of the commands for Access VBA, but I am pretty familiar with Excel VBA.
What I'm trying to do is save the attachment that was just entered into a table through a form. I've been looking at some examples online and trying to get it to work for me but the code is not moving the file to the folder. I do not get a debug error though.
Here is my current code. I know it is set to loop right now, where really I just want the last attachment in the table each time, but I don't know how to get only the last attachment. Either way, this current code doesn't move ANY attachments.
Private Sub cmdAddRecord_Click()
If MsgBox("Adding a new record will save the current form. You will not be able to edit this credit request. Would you like to continue?", vbQuestion + vbYesNo, "Save current record and open new form") = vbYes Then
MkDir "C:\Users\username\Desktop\IC Transfer Back Up Attachments\" & Me.txtRequestID & "-" & "Back Up Attachments" & " " & Format(Date, "MMDDYY")
DoCmd.RunCommand acCmdSaveRecord
Dim SaveFolder As String
SaveFolder = "C:\Users\username\Desktop\IC Transfer Back Up Attachments\" & Me.txtRequestID & "-" & "Back Up Attachments" & " " & Format(Date, "MMDDYY")
Dim rsParent As DAO.Recordset2
Dim rsChild As DAO.Recordset2
Set rsParent = CurrentDb.OpenRecordset("SELECT * FROM tblICTRequested")
Set rsChild = rsParent.Fields("BackUpAttachments").Value
Do Until rsChild.EOF
rsChild.Fields("FileData").SaveToFile SaveFolder
rsChild.MoveNext
Loop
DoCmd.RunCommand acCmdCloseWindow
DoCmd.OpenForm "frmICTRequested"
End If
End Sub
Most of this seems to make sense to me, but I'm not sure what I should put in the .Fields("FileData").SaveToFile line, since I don't have a field named "FileData" but I've tried all my existing fields to no avail.
For reference, here are some of the online links I have reviewed:
https://www.experts-exchange.com/questions/29005769/MS-Access-attachment-file.html
https://msdn.microsoft.com/en-us/library/office/ff191852.aspx
https://access-programmers.co.uk/forums/showthread.php?t=282135
Any tips? Much appreciated!
You're very close. I use a function like this:
Public Function SaveFileToDisk(FileName As String, FileData As DAO.Field2, Optional saveToFolder As String) As String
Dim templatePath As String
If saveToFolder = "" Or Not fso.FolderExists(saveToFolder) Then
saveToFolder = Environ("temp")
End If
templatePath = GetAvailableFileName(FileName, saveToFolder, True) 'A function to create a unique file name
FileData("FileData").SaveToFile templatePath
SaveTemplateToDisk = templatePath
End Function
It gets called like this:
Dim tempPath As String
Dim fileData as DAO.Field2
Dim folderToSaveTo as string
folderToSaveTo = "C:\some\folder"
set fileData = rsParent.Fields("BackUpAttachments")
tempPath = exporter.SaveTemplateToDisk("Name of file.ext", fileData , folderToSaveTo)
The attachment field is kind of like a recordset withing a field.
So with the help of someone, I changed the line:
Set rsParent = CurrentDB.OpenRecordset("SELECT * FROM tblICTRequested")
To:
Set rsParent = CurrentDB.OpenRecordset("SELECT * FROM tblICTRequested WHERE ID =" & Me.txtRequestedID)
This seems to be working perfectly for my purpose! Thank you to everyone who provided information!
I have an access macro that runs a set of Netezza queries and uploads the results to a database. It then opens and refreshes an Excel file that utilizes this data and saves the file in a couple of locations. Finally it composes an automated email and sends it to a distribution list. When I manually run the macro, everything works 100% perfectly.
In order to make my life a bit easier, I am using Windows Task Scheduler (Windows 10) to automatically fire the macro once a day, and this is where my issue lies. Task Scheduler fires the macro off without a hitch, all of the queries refresh, the excel files are saved, but the e-mail is not sent.
Here is the code SendOutlookEmail code that I'm using
Sub sendOutlookEmail()
Dim oApp As Outlook.Application
Dim oMail As MailItem
Dim SpDate As String
Dim Signature As String
Dim StrPath As String
Dim StrFilter As String
Dim StrFile As String
SpDate = Format(Now() - 1, "yyyy-mm-dd")
Set oApp = CreateObject("Outlook.application")
Set oMail = oApp.CreateItem(olMailItem)
With oMail
.Display
End With
Signature = oMail.HTMLBody
With oMail
.SentOnBehalfOfName = "My Email"
.To = "CCO Reporting"
.Subject = "AHT - ACW Dashboard - " & SpDate
.HTMLBody = "<span LANG=EN>" _
& "<font FACE=SegoeUI SIZE = 3>" _
& "The IB/OB AHT - ACW reports have been updated and placed in the following folder:" _
& "<br><br>" _
& "<a href='File Location'>File Location</a>" & "<br><br><br></font></span>" _
& Signature
'.Attachments.Add (StrPath & StrFile)
'.Display
.Send
End With
On Error GoTo 0
Set oMail = Nothing
Set oApp = Nothing
End Sub
Here is the task scheduler settings
Task Scheduler
Possibly Outlook just doesn't have enough time to send the message, as it instantly gets closed after the message is moved to the outbox (.send doesn't send the message as far as I know, but just moves it to the outbox and triggers a send for all items in there).
Try to manually add a send/receive, to make Access wait for Outlook to actually send the mails (add this to your vba before the Set oApp = Nothing):
' Synchronizes (ie sends/receives) OL folders.
' Ref: http://msdn.microsoft.com/en-us/library/ff863925.aspx
Dim objNsp As Outlook.NameSpace
Dim colSyc As Outlook.SyncObjects
Dim objSyc As Outlook.SyncObject
Dim i As Integer
On Error GoTo SyncOL_Err
Set objNsp = oApp.Application.GetNamespace("MAPI")
Set colSyc = objNsp.SyncObjects
For i = 1 To colSyc.Count
Set objSyc = colSyc.Item(i)
Debug.Print objSyc.Name
objSyc.start
Next
Set objNsp = Nothing: Set colSyc = Nothing: Set objSyc = Nothing
An Access DB I designed produces the run time error 2473 stating "Object or class does not support the set of events". The error is produced inconsistently, which makes it very hard for me to track it down.
The debugger stops on the following line of code when it appears:
'Open report containing code to create TOC with list of ISINs from above
DoCmd.OpenReport rptName, acViewPreview, , strWhere
Even when the error occurs, this code works fine for some reports, but produces the run time error for others. After opening up the report and the underlying queries in design mode, the run time error sometimes disappears, even though I have changed absolutely nothing in the code, the forms, or even updated the underlying data.
In an attempt to get at this problem, I have restored my DB to an earlier version where I know the problem still existed, but upon opening up the restored version, it no longer has a run time error either!
What could cause this behavior?
UPDATE:
Full code as contained in the Form
Sub cmdFundSelectionReport_Click()
'Gather selected ISIN and pass it to Fund Selection Report
Dim var As Variant
Dim sFund As String
Dim strWhere As String
Dim lst As Access.ListBox
Dim i As Integer
Dim rptType As Integer
'Create list of isin to send to report
Set lst = Me.libFilterSelection
rptType = Me.cmbReportType
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
For i = 0 To lst.ListCount - 1
If Not dict.Exists(lst.Column(1, i)) Then
dict.Add lst.Column(1, i), i
End If
Next i
Dim a As Variant
a = dict.keys
strWhere = "[ISIN] IN("
For i = 0 To dict.Count - 1
strWhere = strWhere & """" & a(i) & ""","
Next i
strWhere = Left(strWhere, Len(strWhere) - 1)
strWhere = strWhere & ")"
'Set dictionary back
Set dict = Nothing
Dim rptName As String
Select Case rptType
Case 2
rptName = "rptRDRSelectionList" '2 is the RDR List
'strWhere = strWhere & " AND Fund_Selection=2"
Case 3
rptName = "rptAsiaSelectionList" '3 Asia
'strWhere = strWhere & " AND Fund_Selection=3"
Case Else
rptName = "rptFundSelectionList" '0 = Fund Selection
'strWhere = strWhere & " AND Fund_Selection=0"
End Select
'Open Report for view
OpenReport rptName, strWhere
'Write Log
WritelogMessage Now & " | User: " & fncUserName & " | Report Created | ReportName: " & rptName
End Sub
Sub OpenReport(rptName As String, strWhere As String)
'Open report containing code to create TOC with list of ISINs from above
DoCmd.OpenReport rptName, acViewPreview, , strWhere
'Click through report so that TOC code is executed
Dim rptCurReport As Report
Set rptCurReport = Screen.ActiveReport
With rptCurReport
Application.DoCmd.SelectObject acReport, .Name
.Visible = True 'switch to false once code is ok
'Go through all pages
SendKeys "{End}", True
DoEvents
Application.DoCmd.SelectObject acReport, .Name
DoCmd.Close acReport, .Name, acSaveNo
End With
rptName = rptName & "TOC" 'Add TOC to get Table of Contents Report
''Check whether "Internal Use Only Flag" is set to true or false
'Dim bInternalUse As Boolean
'bInternalUse = Me.ckbInternalUse.Value
'Call modProcess.ChangeReportPicture("rptFundSelectionListTOC", "picInternalUse", bInternalUse)
'Open final report that includes the TOC as a subreport with same string of ISIN
DoCmd.OpenReport rptName, acViewPreview, , strWhere
SendKeys "{Home}", True
DoEvents
End Sub
I'm having trouble trying to export an Access report to PDF format. Basically, I'm working on an old (built in 2001) Access database that uses forms as a user interface. Currently, you can send jobs from a "Jobs" form into an "Invoice" form. Once all the jobs are there, you simply click "Invoice All", specify a date and number of copies and this prints using an Access report as the template.
I've been tasked with adding a save as PDF function, but being a web designer by trade, I have very limited knowledge of Access and VB, but I do know a (very) little amount of ASP.Net and C# (how I got given this task is story for another time...)
In my mind I've approached this by creating a new PDF button on the Access form where they print the invoices. My thoughts are that I could simply duplicate the code for the printing and update to output to a PDF file instead. I can kind of get this working, but not how I'd like.
The code for the print function is below:
Private Sub cmdOpenGroupInvoice_Click()
Dim db As DAO.Database
Dim rsGetCustomerInvoice As DAO.Recordset
Dim rsInvoice As DAO.Recordset
Dim rsInvoiceAll As DAO.Recordset
Dim lngCusID As Long
Dim lngJobNo As Long
Dim iCountInvoice
Dim lngInvoiceNo As Long
Dim iNumberCopies As Integer
Dim sSQLGetInv As String
Dim sSQLInv As String
Dim datInvoiceDate As Date
sSQLGetInv = "SELECT tblJobs.JobNo,tblJobs.NetDespatchRef, tblLoads.Sales, tblLoads.PODName, tblLoads.TotalSales, tblLoads.Cost, tblLoads.Profit, tblJobs.SendToInvoice, tblJobs.Invoiced, tblJobs.MarkForHistory, tblJobs.CustomerID" & vbCrLf _
& "FROM tblJobs INNER JOIN tblLoads ON tblJobs.JobNo = tblLoads.JobNo" & vbCrLf _
& "WHERE (((tblJobs.SendToInvoice)=Yes) AND ((tblJobs.Invoiced)=No) AND ((tblJobs.MarkForHistory)=No));"
Set db = CurrentDb
Set rsGetCustomerInvoice = db.OpenRecordset(sSQLGetInv, dbOpenDynaset)
If rsGetCustomerInvoice.EOF Then
Beep
If MsgBox("There are no jobs to invoice", _
vbCritical + vbOKOnly, _
"No Jobs To Invoice") = vbOK Then
Exit Sub
End If
End If
rsGetCustomerInvoice.MoveLast
Debug.Print rsGetCustomerInvoice.RecordCount
rsGetCustomerInvoice.MoveFirst
Do Until rsGetCustomerInvoice.EOF = True
Set rsGetCustomerInvoice = db.OpenRecordset(sSQLGetInv, dbOpenDynaset)
If rsGetCustomerInvoice.EOF Then
rsGetCustomerInvoice.Close
db.Close
Set rsGetCustomerInvoice = Nothing
Set db = Nothing
DoCmd.Close acForm, "frmInvoiceDate"
Exit Sub
End If
Debug.Print rsGetCustomerInvoice.RecordCount
datInvoiceDate = CVDate(txtInvoiceDate)
lngInvoiceNo = GiveMeAnInvoiceNo()
lngCusID = rsGetCustomerInvoice.Fields!CustomerID
Call AddNewInvoice(lngInvoiceNo, datInvoiceDate, True)
Debug.Print iCountInvoice
lngJobNo = rsGetCustomerInvoice![JobNo]
Call SendThisJobToSageAll(lngCusID, datInvoiceDate, lngInvoiceNo)
Call InvoiceAll(lngCusID, lngInvoiceNo)
Dim strPODName As String
If Not IsNull(rsGetCustomerInvoice!NetDespatchRef) Then
If IsNull(rsGetCustomerInvoice![PODName]) Then
strPODName = " "
Else
strPODName = rsGetCustomerInvoice![PODName]
End If
'Call NetDesTrackingJobCompleate(rsGetCustomerInvoice![NetDespatchRef], rsGetCustomerInvoice![JobNo], strPODName)
End If
iCountInvoice = iCountInvoice - 1
'Debug.Print I
iNumberCopies = txtNumberOfCopies
Do Until iNumberCopies = 0
DoCmd.OpenReport "rptInvoice2", acViewNormal, , "[Invoice No]= " & lngInvoiceNo
iNumberCopies = iNumberCopies - 1
Loop
Form_frmInvoicing.Requery
rsGetCustomerInvoice.MoveNext
Loop
DoCmd.Close acForm, "frmInvoiceDate"
rsGetCustomerInvoice.Close
db.Close
Set rsGetCustomerInvoice = Nothing
Set db = Nothing
End Sub
With my original plan outlined above, I updated the below section to output to PDF:
Do Until iNumberCopies = 0
DoCmd.OpenReport "rptInvoice2", acViewNormal, , "[Invoice No]= " & lngInvoiceNo
DoCmd.OutputTo acOutputReport, "", acFormatPDF, MyPath & MyFilename, True
iNumberCopies = iNumberCopies - 1
Loop
Now this works and it does attempt to output a PDF file. The trouble is, it's runs the report and creates an invoice for every job in the system, rather than applying the report to JUST the jobs which are marked for invoicing.
I'm hoping this is happening because I've put the code in the wrong location, but I have a gut feeling that it's more complicated than that.
It's a bit of a long shot posting it on here, but I really appreciate any help at this point. I've also tried to keep this as short as possible, so if there's any details which aren't clear, I'll help out.
That is quite convoluted, so I think the simplest thing to do, if you do not wish to dive in and tidy up, is to modify the query that the report is based on.
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("MyReportQuery")
sSQL = "SELECT Whatever FROM MyTable WHERE [Invoice No]= " & lngInvoiceNo
qdf.SQL = sSQL
DoCmd.OutputTo acOutputReport, "rptInvoice2", acFormatPDF, _
MyPath & MyFilename, True
Unless you have Access 2007 with the Save as PDF Add-on or 2010, you may be best installing say, cutePDF, and printing to the PDF printer using DoCmd.PrintOut
I asked the same question a couple of years ago on UtterAccess..
There is a free library to do exactly what you need here: http://www.lebans.com/reporttopdf.htm
My original thread at UA is here : http://www.utteraccess.com/forum/Automatically-PDF-send-t1353547.html
I successfully used the library for a couple of years in several projects, mainly to generate quotes and invoices.
Hope this helps
PG