How to print Reports as an Email in Dynamics NAV

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 🙂

Diagram of a simple IT infrastructure

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.

How to print by Email from a Cloud-ServiceTier

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)

I have compiled the complete source code with an example into a package. The zip-file is ready to download on mibuso.com .

More
articles

%d bloggers like this: