Printing Reports using an Email may sounds a little bit weird at first. But, for ServiceTiers that are hosted in a Cloud-environment, it’s actually useful.
If you are just keen to see the code on how to print Reports using Emails, click here.
Now, in the IT-age of Cloud, it is a common environment. The ServiceTier of Dynamics NAV is hosted on a Cloud-Server (i.e. Azure). More and more companies are utilizing this setup. It is a popular service, due to the benefit of reducing on-site costs to maintain a server-infrastructure. By using server-hosting in the cloud, a lot of specialized knowledge is not necessary anymore (i.e. security of access to server, cooling, hardware-failure, electricity backup etc.).
What is the challenge for Dynamics NAV
Due to the distributed approach, connectivity to local hardware is lost. The Desktop- and Web-Client of Dynamics NAV are still executed in the local-network (thankfully). That means, that the local Client has technical access to local hardware. But the ServiceTier, which runs in the Cloud, not. For example, local printer do not have a connection to the Server on which the ServiceTier runs. And this means, it is impossible to print in any kind of task executed by the Job Queue (or NAS).
The following diagram demonstrates a simple infrastructure. Please bear the quality and lack of details. I’m not an infrastructure guy 🙂
Of course, Microsoft provides tools to solve this problem. But sometimes, an easier approach is convenient.
Modern multi-functional printer
Most printer of today are multi-functional: Scan, multi-size print, duplex print and connectivity by Email. Most people will have used a printer, with which it was possible to scan a document and send it by Email. These kind of multi-functional printer do allow the other way around also: Send a document by Email and print it.
The implementation varies by manufacturer. Xerox implements the pull-variant: create an Email-address in the local Active Directory and setup Username and password in the printer. The printer checks for new Emails in a given interval. HP on the hand does use the push-approach. To send an Email to your printer you have to setup the service online. HP will generate and host an Email-address. The Email-address is connected then to the printer.
I have created a Codeunit to enable printing for distributed environments like described above. This Codeunit can pick up every Report and send it to a printer using an Email. The main function is called “Print2Email”. The following parameter are available:
- pReportID : The Report ID
- pTableNo: The Table No. of the first DataItem of the Report
- pRecordView: The set of records to print. It must be the SourceTableView-format
- pUserID: optional User ID to lookup the printer settings
Because it is necessary store the Email-address(es) somewhere, I have decided to add a new field to the Table “Printer Selection”. This allows me to configure different printer per Report. Additionally, it is thinkable to apply only one Email-address to all print-requests. The function utilizes the built-in SMTP-function of Dynamics NAV (So, yes – a valid SMTP-setup must exist).
The below code demonstrates the main function.
Print2Email(pReportID : Integer;pTableNo : Integer;pRecordView : Text;pUserID : Text) IF pRecordView = '' THEN EXIT; // get E-Mail from Printer Selection PrinterSelection.SETRANGE("Report ID", pReportID); IF pUserID <> '' THEN PrinterSelection.SETRANGE("User ID", pUserID) ELSE PrinterSelection.SETRANGE("User ID", USERID); IF PrinterSelection.ISEMPTY THEN PrinterSelection.SETRANGE("User ID", ''); IF NOT PrinterSelection.FINDFIRST THEN PrintReport := TRUE; IF PrinterSelection."E-Mail" = '' THEN PrintReport := TRUE; // Prepare record reference RecordRef.OPEN(pTableNo); RecordRef.SETVIEW(pRecordView); VarRecordRef := RecordRef; RecordRef.CLOSE; // print report, in case no Email available IF PrintReport THEN BEGIN REPORT.RUNMODAL(pReportID, FALSE, FALSE, VarRecordRef); EXIT; END; // define location and name FileLocation := TEMPORARYPATH; FileName := 'Report'+FORMAT(pReportID)+' '+FORMAT(CREATEGUID)+'.PDF'; // create PDF IF NOT REPORT.SAVEASPDF(pReportID, FileLocation+FileName, VarRecordRef) THEN REPORT.SAVEASPDF(pReportID, FileLocation+FileName, VarRecordRef); // Email handling SMTPSetup.GET; SMTPMail.CreateMessage(SMTPSetup."User ID", SMTPSetup."User ID", PrinterSelection."E-Mail", FileName, '', FALSE); SMTPMail.AddAttachment(FileLocation+FileName, FileName); SMTPMail.Send; // delete pdf ERASE(FileLocation+FileName)