You are on page 1of 36
codeunit 50101 Sendkeportyéma41 ‘ [Eventsubscriber(Objecttype: :Codeunit, Codeunit::ReportManagenent, “OndfterDocumentPrintReady", > true, true)] procedure OndocunentPrinteady(ObjectIype: Option “Report”, "Page"; Objectid: Integers ‘bjectPayload: 3sondbject; DocumentStrean: TnStrean; var Success: Boolean); SwTPmail: Codountt "SMTP Mail"; PeincerNareToken: 3sonToken} PrinterNane: Text; ‘objectaneToken: IsonToken; bjectiane: Text; DocunentTypeToken: 3sonTokens DocunentIypeParts: List of [Text]; MailManagenent: Coceunit “Mail Management”; SendFron: Tex FileNane: Tex Recipients: List of [Text]; begin begin 1/ Step 1: Before doing anything, St 4s important to check the current Success value 4 success then exit; 11 Step 2: Wake sure code only runs for reports 1 ObjectType = ObjectType: Report then begin 1/ Step 3: Get report object payload information bjectPayloae.cet(‘printernane”, PrinterNanetoken); PrinterNare := PrintertaneToken.AsValve() .ASText(); Af PrinterNane = ‘My Printer then begin ObjectPayload.Get(‘objectnane", dbjectNaneToKen); ObjectNane := OdjectNaneToken.Asvalue() .AsText(); ObjectPayload.cet("docunenttype', Document TypeToken); U1 step 4: Build the email nessage DocunentTypeParts :+ Document TypeToken.AsValue() ASText().SpLit(’/")5 FileExtension := OocueentTypeParts..Get(OocumentTypeParts.Count); Recipients.Add(nyprintertGbusinesscentral -omicrosoft.com'); SendFrox := MailManagenent .GetSendercnatladdress(); SWTPMai1.CreateMessage("Sender’, SendFron, Recipients, ‘Mello this is your report", “Please take a look"): SWTPHail.AddAttacnnentStrenn(OocunentStrean, ObjectNane + '.’ = Fileéxtension); U1 step 5: Send the enail for print SHTPHal1.Send; end; end; 4, Atthis point, you can compile and publish/install the extension on a tenant to test First, make sure that SMTP email is set up on the tenant (see Set Up Email in the Application Help). Then, on the Printer Selections page, set a report to use ‘My Printer’, and then run and print the report, About the report payload The event subscriber receives the printer payload and combines it with the report metadata, like the report’ ID. This combination is the report payload, The content of the report itself is received as a stream object. You add code to define how and where to send the report payload for printing. In this example, it's sent as an email version": 2, description” :(defauit=""], “duplex”: [default=false], color": [default=false), lefaultcopies" :[default=1], papertrays c « papersourcekind: Upper’ | 2, “paperkind”: a4" | 9, units": [defaulte"HI"], elghe™:(default-0), width”: [default-2], ult-false] andscape": [de There are few required attributes, such as version and papertrays The papertrays attribute must contain at least one paper tray setup, which in turn must include the attributes papersourceking and paperkind . For more information about the attributes, see Printer Payload. Using the ReadFrom method to create the payload The following example illustrates how to create a payload by using the ReadFrom method, codeunit $0101 SetupPrinter? « LEventsubscrsber(abjectType: :Codeunit, Codeunit::"Reporttanagenent”, “OnafterSetupPrinters', "*, true, true) procedure SetupPrinters(var Printers: Dictionary of (Text[258], IsonObject]); Payload: Isondbject begin 1/ Step 1: Read the payloaé from the text Payload. ReadFron(*{*version":1,"papertrays": (papersourcekind”:"Custon", "paperkind”:"Custon", "width" :236,"height":322, units’ {"papersourcekind": "Upper", "paperkind”:"A4"}, oH); 11 step 2: Add the printer to the dictionary Printers.Add("My Printer", Payload); end Select the paper tray A printer can have several paper trays. fa report doesn't specify which paper tray to use or the specified paper tray isn't present in the printer's setup, a default paper tray is used, The default paper tray is the first one defined in the papertrays list You can change the paper tray for an existing report by subscribing to the onaftersetPapertrayForReport event and setting a value for a oefauitPage parameter. [eventsubscriber(objectType: :Codeunit, Codeunit::"ReportManagenent", ‘OnAFterGetPaperTrayForReport', "', true, true)] procedure GetPaperTrayForseport (Repo LastPage: Integer) Integer; var FirstPage: Integer; var DefaultPage: Integer; var As an alternative, if you're creating a new report, you can set a paper tray by specifying PanerSourceDefaultPage property. Oriana ee a 0) ae a) This article describes how to use the OnAfterSetupPrinters and OnAfterDocumentPrintReady events to set up different printers for reports. Overview This article uses a simplified printer extension example for sending reports to an email printer. The example creates a printer extension that sets up a single email printer. Users can then assign the printer to reports from the Printer Selections page in the client. In this article, you will © Create two codeunits, one that subscribes to the OnAfterSetupPrinters event and another that subscribes to the OnAfterDocumentPrintReady event ‘© Use the SMTP Mail and Mail Management codeunits that are part of the base application for sending the report via email Set up printers using the OnAfterSetupPrinters event This section describes how to use the OnAfterSetupPrinters event to set up a printer. When completed, users can select the printer from an the Printer Selections page. Getting started 1, Create an AL project for the printer extension. See Getting Started with AL 2. Create a codeunit to use for subscribing to the OnAfterSetupPrinters event. 3. Create a method that subscribes to the OnAfterSetupPrinters event. Atthis point, your code would look something like this: codeunit S000 SetupPrinter ‘ [eventsubscriber(objectType::Codeunit, Codeunits:"RoportHenagenart", ‘OnAftersatupprinters’, °*, ‘true, true) procedure OnsetupPrinters(var Printers: Dictionary of [Text[250], Isondbject]); begin end For more information about subscribing to events, see Subscribing to Events, 4, Now you can start adding code to the event subscriber method to create the printer payloads, In this example, you set up a printer named 'My Printer’ that has two paper trays: Ad and Custom. There are two ways of setting values for a payload JSON object. You can add properties (key-value pairs) by Using the Add method, as shown in the example, Or, you can use the ReadFrom method to read the JSON, data from the string into a JsonObject variable (see Using ReadFrom to create the payload). they select from the Printer Selections page. The OnAfterSetupPrinters event isa global integration event that is published from codeunit 44 Report Managements. It has the following declaration Lintegrationevent(false, f21se)] Local procedure OnAfterSetupPrinters (var Prin rs: Dictionary of [Text[250], Isondbjec: Ds The Printers parameter is a Dictionary of (Text, Text type that includes a collection of key-value pairs that define different printer setups. The key specifies a name for the printer. The value is a JSON object that specifies settings supported by the printer. The settings include information like paper size, paper trays, default copies, and more. The JSON object is referred to as the payload. The OnAfterSetupPrinters event is raised when the following operations occur: ‘© When you open a page that uses the virtual table Printer as its source. ‘© From page 64 Printer Selections in the base application, when you access the Printer Name field for selecting a printer for a report. This field has a lookup to the Printer table. ‘¢ From a report request page, when you select the Print or Preview action for a report. But only ifthe report is set up to use a specific printer from the Printer Selections page ‘OnAferDocumentPrintReady You subscribe to the OnAfterDocumentPrintReady event to specify what happens when the user selects the Print action on a report request page. You use OnAfterDocumentPrintReady event subscribers to provide Instructions on how and where to send to the report for printing. For example, with email printing, the ‘OnAfterDocumentPrintReady event subscriber would construct and send an email to a target printer. The OnAfterDocumentPrintReady event is also a global integration event that is published from codeunit. 44 Report Managements. Ithas the following declaration: Integrationévent(False, false)] local procedure onafterbacurentPrintheady(ObjectIype: Of "age" ObjectPayload: Isondbject; DocumentStrean: InStream; var Success: Boolean); enor objectid: Integers The event is raised when the use selects the Print action on the request page of a report. Two parameters of Interest are DocumentStream and ObjectPayload. DocumentStream is an Upstream object that contains the report data to be printed. The ObjectPayloadis a IsonObject type object that combines the printer payload and report metadata, The report metadata includes information like the company name, MIME type, views, and ‘more. This combination is referred to as the report payload, Development Overview To develop a printer extension, you create codeunits that subscribe to the OnAfterSetupPrinters and ‘OnAfterDocumentPrintReady events, Plus, you would typically add other objects to support the printing. For ‘example, you could create a table that stores printer setups and a page that enables users to manage them. Standard formats ‘The following table describes the standard formats that are available for the AutoFormatExpr property when the AutoFormatType property is set to 10. STANDARD FORMAT FORMAT DESCRIPTION EUROPE DECIMAL EXAMPLE US DECIMAL EXAMPLE ° - 1 2 - 3 4 76543,21- 7654321- «Point of Comma> ° XML format 7654321 7654321 See Also AutoFormatType Property AutoFormatExpression Property DecimalPlaces Property AUTOFORMATTYPE PROPERTY DECIMALPLACES PROPERTY ° Set to the number of decimal places ‘that you want to display for the value Setting the AutoFormatExpression property With the following setup, the DecimalPlaces property is ignored AUTOFORMATTYPE PROPERTY AUTOFORMATEXPRESSION PROPERTY 1 Set to return a currency code, such as USD or IDR. The blank currency code denotes LCY and i the default value, 2 Set to return a currency code such as USD or IDR The blank currency code denotes LCY and is the default value, USAGE DESCRIPTION Use this configuration when you want to format the decimal value according the Standard Format 0 (whieh is the default format) with a specific number ‘of decimal places For example, ifthe value is 3 US decimal, -76543.21 and you set the DecimalPlaces property to 0 , then the value appears as 76,543. The properties wil look lke tis: USAGE DESCRIPTION Use this configuration when you want to format the data as an amount. For ‘example, a sales order will use two decimals when the currency i defined a5 US dollar and no decimals when the ‘currency is defined as IDR (Indonesian rupiah. For example This is similar to the previous ‘configuration where the AutoFormatType property is set to 1. except you use ths configuration when you want to format the data as 3 unit amount, develop the layout. Without the font, the report won't show the barcode. But if you then test the report in an online sandbox. it will be shown on the report. See Also Request Pages Creating an RDL Layout Report Creating a Word Layout Report Developing Extensions AL Development Environment Adding Barcodes to Reports PLT rn [APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later This article explains how to add barcodes to reports using the barcode functionality in Business Central. Overview The barcode functionality lets you convert an alphanumeric value in a report dataset into a barcode on a generated report. The functionality is provided by the Barcode module of the System Application. The module includes the objects and tools that you need to add barcodes to reports. Using the API, you create barcode font providers for generating data strings as barcodes. A barcode provider includes a library of different barcode fonts and symbologies. As part of the provider, you add barcode font encoders that convert data strings to the specific font specification and symbology. For more information about this module, see the AL Extensions on GitHub. Business Central online comes equipped with a barcode provider and fonts from IDAutomation. So, you can start adding barcodes to reports right away. For a description of the availabe fonts, see Barcode Fonts with Business Central Online To start adding barcodes to reports, follow the instructions in the next sections. Setting up Business Central on-premises With Business Central on-premises, there are couple tasks you'll need to do before you can start adding barcodes to your reports. 1. Get the barcode fonts that you want to use on reports. You can get barcode fonts from any font provider. If you use the IDAutomation fonts, you can skip the next step and use the builtin IDAutomation barcode font provider. 2. Create your own barcode font provider with encoders for the fonts ‘Adhere to the interface in the Barcode module, Consider contributing to the open-source project if you do. 3, Install the fonts on the Business Central Server computer or machine. Install the fonts in the Business Central Server instance installation folder. By default, the folder is, CAProgram Files\Microsoft Dynamics 365 Business CentrahXXX\Service Encoding a string in AL To representa string as a barcode in a report, encode it according to the symbology you want, The Barcode ‘module has encoder methods in codeunit 9215 IDAutomation 1D Provider. You can use these encoders with barcode fonts from IDAutomation Use the validsteinput procedure to validate whether a string can be encoded in a given symbology, and then the Encoderont procedure to do the actual encoding, Use table 9203 Barcode Encode Settings to configure smaller variations in how different symbologies work. For example, you can enable an extended character set or checksums in Code39, or change the code set used in 18. Right-click the cell that is under the caption that you just created, choose Expression. In the Category column, select Fields (DataSet_Result), and then in the Values column double-click DocumentType_SalesHeader. Choose the OK button. Verify that the Set expression for: Value box contains the following value: Fields ioocunent Type. Salesteader. Value 19, Repeat steps 15 through 18 and add the following captions and the corresponding fields. cation ‘CORRESPONDING FIELD No SslesHeaderCaption No SalesHeader PostingDate_SalesHeaderCaption PostingDate,SalesHeader PricesindudingVAT.SalesHeaderCaption PricesincludingVAT_SalesHeader Amount SalesHeaderCaption “Amount, SalesHeader 20. Select the first two rows and in the Properties window, set the BackgroundColor property to Lime. 21, Select the data row (last row), in the Proper Turquoise. 5 window, set the BackgroundColor property to Viktor will now set a filter that hides empty rows, ‘To set fiter hide empty row 1. Select any row from this table, right-click the shaded border to the left of the table, and then choose Tablix Properties 2. Choose the Filters tab and then choose the Add button. 3. In the Expression list box, select No_SalesHeader, set Operator to >, set Value to0, and then choose the OK button 4, Save the report. Building and Running the Report Viktor will run the report to view how it looks like. For this, do the following 1, Make sure that the “startupobjectta™ is set to the Id of the report object and the “startupobjectType* to Report in the launch. json file, 2, Press the F5 key to compile and run the report in Dynamics 365 Business Central 3. Ifyou have not disabled the UseRequestPage Property you will be shown a request page in the Web Clie The following illustration shows an example of the request page that is displayed when the report is run, you choose the Preview button on the request page, the report will be displayed with the RLD layout Just created, Viktor can now add advanced features to the report. He can add features such as displaying the company name and logo on every page on the report, He might also want to add features that enable users to apply filters on the request page, The following illustration shows EntryNo and the EntryType cells directly under the CustomerNo cell i fxm Peni 28, Repeat steps through 27 to put the Transaction No, and Journal Batch Name captions and fields under the Description data. This creates a blank cell under the CurrencyCode field. 29, Select the third row and set the BackgroundColor property to Yellow and then set the BackgroundColor property of the fourth row to Khaki Viktor will now hide all empty cells and add the totals to the footer row. To hide empty cells Vil ‘add a filter that selects rows that have [EntryNo] value that are greater than zero, ‘To hide empty cells and add totals 1, Select the first row, rightclick the shaded border to the left of the row, choose Rew Group, and then choose Group Properties. 2. Inthe Group Properties window, select the Filters tab, and then choose the Add button. 3. Set Expression to [EntryNo_CustLedgerEntry], change Text to integer, set Operator to >, set Value 100, and then choose the OK button. filter that is set applies to the other rows in the table. 4, In the Group Properties window, under the EntryNo_CustLedgerEntry} {ers tab, verify that the Expression box contains Viktor will now add the total of the amount field to the footer row of the table, format the cells and hide the total cell if customer ledger entry is not available, 5. In the last row of the table, right-click the empty cell under the Amount (LCY) field, and then choose Expression 6, Inthe Category column, select Fields (DataSet_Result) in the Values column double-click ‘Amount _CustLedgerEntry, and then change the expression in the Set expression for: Value box to the following value: «sun(Fields inount_CustLedgerEntry. Value) . Choose the OK button 7. In the Properties window, locate the Format property, choose the drop-down arrow and select Expression 8, In the Expression window, enter the following formatting expression in Set expression for: Value box Fields Arount,custLedgerEntryFormat Value . Choose the OK button. NOTE Alternatively, you ields(DataSet) * this value by double-clicking Amount_CustLedgerEntryFormat in the Values field of ry. 9. Select the two empty cells to the left of the tatal cell, rightclick the cells, and then choose Merge Cells. 10. Right-click the merged cell, choose Expression, choose the Parameters category, and then set the caption to Total_Caption 11. Set the BackgroundColor property of the cells that contain the total and total caption to Red. 10, " 12, 13, 14, 15, 16, another data row to the table. You now have one header row and two data rows. Delete the first row (header row) in the table and then insert columns in the table so that the total number of columns is eleven, Choose the first data row, right-click the shaded border to the left, choose Add Group, and then choose Parent Group, Inthe Tablix group window, select Group by, select EntryNo_CustLedgerEntry from the drop-down list. Select Add group header, and then choose the OK button Right-click the first row, choose Insert Row, and then choose Inside Group — Above. This header will hold the captions for the Customer Ledger entries Right-click the cell in the row1, column 2, and then choose Expression to open the Expression window. In the Category column, select Parameters and then in the Values column double-click EntryNo_CustLedgerEntryCaption. Note that the Set expression for: Value box contains the following value: -Parareters!EntryNo_CustLedgeréntryCaption, Value Modify the expression to the following value: -First (Parancters|Entryio_CustLedgerEntryCaption.Value) Repeat steps 9 through 11 to add captions for the table cells in the rest ofthe first row as shown in the following table, coun ‘CAPTION EXPRESSION 3 CustomerNo_CustledgerEntryCaption 4 PostingDate,CustLedgerEnteyCaption 5 DocumentType_CustLedgerEntryCaption 6 DocumentNo_CustLedgerEntryCaption 7 Description CustLedgerEntryCaption 8 Skip this cll You wll se this cel ater 3 CurrencyCode,CustLedgertnteyCaption 10 ‘Amount. CustLedgerntryCaption " OriginalAmtLCY.CustLedgerEnteyCaption RemainingAmtl.c¥_CustLedgerEntryCaption Right-click the left-most grouping cell (the cell that contains the EntryNo_CustLedgerEntry field) in the table, select Text Box Properties, in the Text Box Properties window, select the Visibility tab, under the Change display options, select the Hide option. Select the first row in the table, in the Properties pane, under Fill, set the BackgroundColor property toDim Grey, Right-click the cell in the row2, column 2, and then choose Expression to open the Expression window. In the Category column, select Fields (DataSet_Result), in the Values column, double-click 10, " 12, 13, groups. Select the remaining table row, right-click the shaded border on the left, choose Insert Row, and then choose Below to insert another table header row. Repeat step 6 to insert a third table header row. There should now be three header rows in the table. Right-click the first cell row 1, column 1) in the table, and then choose Expression to open the Expression window. In the Category column, select Parameters, in the Item column, verify that Al is selected, and then in the Values column, double-click No_CustomerCaption. Verify that the Set expression for: Value box contains the following value: ranetersiNo_CustonerCaption.value . This cel will display the customer No. caption in the report. Modify the expression to. =Finst(Paraneters!Na_CustonerCaption.value) . Choose the OK button. NoTE {All caption fields must begin with First so thatthe fist value forthe caption fields in the dataset i retrieved and used as caption. If the First function is not used, the report wll return the current value for afield, The current value however may be incorrect. For example, the cutrent value could be emp. Right-click the second cell (row 1, column 2) in the table, and then choose Expression to open the Expression window. In the Category column, select Field(DataSet_Result), in the Item column verify that Allis selected, and then in the Values column double-click No_Customer. Verify that the Set expression for: Value box contains the following value Fields No_custoner.value . Choose the OK button, This cell will display the Customer No, Repeat steps 8 through 12 to the enter captions and values in the following cells. NOTE ‘Columns 1 and 3 will contain the captions and columns 2 and 4 will contain the values. Row column cAPTION vaLue 2 1 Name_CustomerCaption None 2 2 None Name_Customer 1 3 ‘Address. CustomerCaptio None 1 4 None Address. Customer 2 3 PhoneNo_CustomerCapti None 2 4 None PhoneNo_Customer 3 3 EmailCustomerCaption None Ineludecaption = true; > colunn(No_SalesHeader; "No.") ‘ IneludeCaption = true; ) colunn(Pastingvate_Salesiesder; “Posting ate") ‘ IneludeCaption = true; > colum(PricestncludingVAT_SalesHeader; “Prices Including VAT") 4 TIneludeCaption = true; d colunn(Aount_Salesteader; Amount) ‘ IneludeCaption = true; > 11 These labels will be used later as captions in the report layout. labels ‘ Sales_pocunent_caption = ‘sales Documents"; Tetal_Caption = "Total"; Designing the Visual RDL Layout for the Report Next Viktor will design an ROL layout for the report by using Visual Studio Report Designer. He will set properties for the report and the report elements, format the report, and then add the data to the report. ‘To design the RDL layout forthe report 1, Build the extension (Ctrl+Shift+8) to generate the Hysol Report.rdi file, and then open the file with Visual Studio 2019. 2, Right-click anywhere outside the report (in the shaded area) and then choose Add Page Header. 3. Right-click anywhere outside the report (in the shaded area), and then choose Report Properties. 4, In the Report Properties window, choose the Page Setup tab. In the Paper size section, under Orientation, choose Landscape, and then choose the OK button, 5. On the View menu, choose Toolbox. Select the List control, and then chaase the body of the report to ‘add the List control to the report. This control will contain and group all the data, 6. Move the List control to the top of the report body and resize it to cover the whole report body. 7. Right-click the middle of the List controls, and then click on the box to open the Rectangle Properties. 8. In the Rectangle Properties window, choose the Fill tab, in the Fill Color list color pallet, select Datattemlink = "Custoner No.” = field( "No. column(Entryho_CustLedgerentey; “Entry No. ‘ IneludeCaption = true; ? colunn(Customerto_CustLedgerentry; "Custorer No.") i Tncludecaption = true; y colunn(PostingoateCustLedgerEntry; “Posting ate") ‘ Ineludecaption = true; > colunn(bocurentType_CustLedgerEntry; “Document Type") ‘ IneludeCaption = true; > colunn(DocurentNo_CustLedgerentry; “Document No.") « Tncludecaption + true; ? colunn(Description_custLedgerEntry; Description) ‘ Includecaption = true; > colunn(Currencycode_CustLedgerentry; “currency Code’ ‘ Includecaption = true; colunn(Anount _CustLedgerEntry; Amount) « TIneludeCaption = true; » colunn(OniginalAntlcy_custLedgerEntry; "Original Ant. (LCY)") ‘ Includecaption = true; > colunn(RenainingARtlcy_CustLedgentry; “Resaining Ant. (LCY)") « TneludeCaption = true; » dataitem(vetcustLedger; “Detailed Cust. Ledg. Entry") « batartentableview = sorting( “entry no. DatarterLink = "Cust. Ledger Entry No.” = field("Entry No."), “Customer No.” = #lela(*custoner No.); column(EntevMe DetailedCustLedatntry: “Entry No.") The following illustration shows an example of the second page of the report. Defining the Dataset Viktor starts by creating an empty report object by using the AL Language extension in Visual Studio Code. You can use the shortcut treport_ to create the basic layout for a report object He sets the DefaultLayout Property to RDLC to specify that he will use an RDL layout for the report and the RDLCLayout Property to ‘HyAbLReport.ré1" , the name of the rdl fle he will use for the layout. Viktor will now design the dataset to display customers and their transaction details This is defined within the dataset partof the report object ‘Adding Data Items and columns The datasets for the data model will come from four tables: customer , cust. Ledger Entry , Detailed Cust. Ledger Entry ,and Sales Header . Viktor will create a data item for each table with the cataiten control. Moreover for each table, he will add the fields that he wants to display on the report. Each field is given bya colum control, defined inside the corresponding data item. The hierarchy of the dataicen and column controls is important because it will determine the sequence in which data items are linked, which in turn will control the results. Working from top-to-bottom, you start by adding the cataizer control for first table that you wantin the dataset, then add column controls far each table field that you want to include in the dataset. For the next table, you add another cataiten control that is embedded within the first dataiten control, then add column controls as needed. You continue this pattern for additional tables and fields. Defining Properties for the Data Items ‘Once Viktor has specified the dataitem and column elements he will define the appropriate properties. He sets the DataltemTableView Property in each data item to sort the table view based on a specific field He also sets the RequestfilterFields Property to automatically include a specific field on the filter tab of the request page. For more information about request pages, see Request Pages. Now, Viktor uses the DataltemLink (Reports) Property to set a link between one or more fields of the dataitem tables. Links determine which records to include in the dataset based on the values of a common field between dataitems. This property must be set on the lower dataitem of the report object. For each of the column controls he adds the IncludeCaption Property and sets it to True. This property specifies to include the caption of the fields in the dataset of a report. Finally, he sets the PrintOnlylfDetail Property to True on a data item to print data only if at least one af its child data items generates output. report $0123 HyAdlReport « Defaultlayout = RDLC; RoLCLayout = ‘NyRDLReport rd"; dataset 4 davaiten(Custorer; Customer) « coluan(Wame; Nate) < y 4, Build the extension (Ctrl+Shift+B), The »yRoLReport.rdl_ file will be created in the root of the current project. 5. Open the generated report layout file in Microsoft SQL Server Report Builder. 6, Edit the layout by inserting a table. 7. Add the Name column from the Datasets folder into the table and save the rd file. 8, Back in Visual Studio Code, press Ctrl+FS to compile and run the report in Dynamics 365 Business Central You will now see the generated report in preview mode NOTE If the report layout is not generated, open the settings.Jeon from Visual Studio Code. Use Ctrl+Shift+, then choose Preferences: Open User Settings, locate the AL Language extension. Under Compilation Options, ‘choose Edit in settings,json and add the folowing line: “al. conpilationoptions": { “generateeporttayout™: true ? ™ From the Business Central client, you can export report results a5 raw data to a Microsoft Excl file. The fle contains all columns of the dataset, but without the layout applied, Use the fle to help validate that the report returns the expected ‘data, and to ensure thatthe report layout controls match the dataset value types. To export areport, run the report and. select the Send to > Microsoft Excel Document (data only) on the request page, For more information, see Working with Reports - Send to Excel. See Also Report Design Overview Report Object Creating a Word Layout Report See Also Report Design Overview Report Object Creating an RDL Layout Report Creating a Word Layout Report eet dit Online When you create anew report, there are two tasks main tasks. First, you define the report dataset of data items and columns. Then, you design the report layout. These steps will show how to create a report based on a Word layout. For more information about the report object, see Report Object. Create a Word layout report The following example extends the Customer List page with a trigger that runs the report as soon as the Customer List page is opened. NoTE ‘The Different first page and Different odd and even options for headers and footers in Word aren't supported for HTML conversion. Ifyou select either of these options, the header and footer won't appear in rendered output, such as an Email Body. 1. Create a new extension to the Customer List page that contains code to run the report and a report object by adding the following lines of code: pageextension 58128 MyExtension extends “Custoner List” { ‘erigger OnopenPoge(); begin report. Run(Report: :MyWloraReport): ends d report $0124 MyWoréReport ‘ Defaulttayout = Word; Woratayout = ‘NyWordReport docx’; 2. Build the extension (Ctrl+Shift+B) to generate the MyWordReport docx file 3. Add the Customer table as the data item and the Name field as a column to the report by adding the following lines of cade to the report. For more information about defining a dataset, see Report Dataset. Testing Reports aes Testing your report requires you to run it and to verify the data output. This practice helps you ensure that your customers are presented with complete and accurate data, Before extensions, the output of a report was saved to a file, but extensions deployed to Dynamics 365 Business Central cannot access the file system and therefore must save the output of a report to a stream. Codeunit 131007 Library - Report oataset offers a high-level API for running and testing the output of reports that does not require direct access to the file system, Example The following example shows how to initialize the codeunit 131007 Litrary - Report oataset by using the fusfeporstndtoad method. This method is preferred as it will run the report and initialize the Library - Report Dataset codeunit To verify the output, call either the Assertelesentuithvaluetxists or the AssertElenenthithvalueNotéxist_ method. The ather methods in the library should work as well if they do not contain “Tag" in the name. RUNREQUESTPAGE and [RequestPageHandler] are optional and you can use them when you want to open the request page. ™ you want to run the report separately and load the data from the input stream manually, you can use the LoadoataFrorinstrese method. codeunit 50105 MyReport Testing « Subtype = Test [rest] [WandLerFunct ions “RenittanceacviceJournalRequestagetiandler)) procedure TestingReposts(); wmiParameters: Texts LibraryReportdataset: Codeunit "Library - Report dataset"; Gendournalline: Record "Gen. Journal Line™; begin 11 Run the Report Remittance Advice - Journal. xmiparaneters := Report RunRequestPage(Report::"Remittance Advice - Journal"); Libraryfeportbataset. AurReportindLoad(Report::"Renittance Advice - Journal", GenJournalLine, xmiParameters); 1) Verifying Total. Amount on Report. LibraryReportoataset .AssertElesenthithvalueExists(‘Ant_GenJournalLine", GenJournalLine.Anount) ; ends [RequestPagetandler} procedure ResittanceadvicezournalRequestPageHandler(var Reaittancesdvice3ournal: TestRequestPage 395); begin 1/ Enpty handler used to close the request page. Ke use default settings ends Any changes done in the handler above will result in the xeiParaneters being changed and applied Substituting Reports aes Edit Online Contrary to pages and tables, extensibility is not yet supported for report objects in Business Central. Therefore, if you want to make any changes to the dataset or the layout of a base application report, you must create a new version of the report and apply the changes on the new object. Then you can override the base report with your ‘own customized version by subscribing to the OnAfterSubstituteReport event published by Codeunit 44 — ReportManagement, How to substitute a report for another report To substitute a report, you create a method and subscribe it to the OnAfterSubstituteReport event, as shown in the code below. The onsubstitutereport_ method replaces the report specified by the Reportta with the one Given by the Newteportta parameter In this example the “Customer - List” report will be substituted for “hy New Custoner - List” codeunit $0100 “Substitute Report” « [eventSubscriber(objectType: :Codeunit, Codeunit::ReportManagenent, ‘OntfterSubstituteteport’, "', false, faise)) ‘cai procedure OnsubstituteReport(Reportld: Integer; var Neweportid: Integer) begin Af Reportta = Report::"Custoner - List then NeweportId := Report::"My New Custones - List"; For more information on how to subscribe to events, see Subscribing to Events. When the OnAfterSubstituteReport event is raised, the event subscriber method is called and the substitution takes place. NoTE ‘The event is called OnAfterSubstituteReport to match the patter followed by other events in the ReportManagement codeunit, but the subscriber willbe invoked before the substitution takes place The OnAfterSubstituteReport event is raised when 1. The user activates a page action that runs the report to be substituted, that s, an action that has the RunObject Property set to the report. 2, The reports invoked from the Tell Me window, 3, The reports called by one of the following static methods: Run Method © RunModal Method # SaveAstitml Method © SaveAsxml Method # SaveAsPaf Method © Saveaséxcel Method NOTE For Business Central on-premises, the Business Central Web Server configuration fle (navsettingsson) includes @ setting called useacditionalsearchterms that enables or disables the use of additional search terms by the Tell me. For more information, see Configuring Business Central Web Server Instances, Example The following example creates a simpleitenList page and sets a usagecategory property to the page, so that the sinplertertist page is discoverable through search using the Tell me feature. Also, the example sets the [AdeitionalSearchTerns property to add two search terms for the page. page 50210 Sinpleitentist « Pagetype SourceTable = Item; Usagecategory = Lists; ‘AccessByPernission = page SimpleltenList = X; Applicationtrea = All; ‘AdéitionaisearchTerms = ‘product, merchandise’; Layout ‘ area(content) « aroup(Genera}) ‘ #el6("Wo."5"N0.") (3 ‘ield(Nane; Name) #eld(Description;Description) ? d > y Optional settings In addition to making a page or report searchable, you can control the access of an object by providing Read, Insert, Modify, Delete, and Execute (RIMDX) permissions by adding the AccessByPermission property Likewise, control the application area access on the specified object by adding the Application Area Property The AccessByPermission property and ApplicationArea property are the optional settings, which can be applied with the UsageCategory property. These settings are used to set restrictions on an object when you ‘enable the Search functionality. Working in the Dynamics NAV Development Environment NoTE Dynamics NAV Development Environment is DISCONTINUED AFTER: Business Central Spring 2018, If you are using the Dynamics NAV Development Environment, you can also set UsageCategory, AdditionalSearchTerms, AccessByPermission, and ApplicationArea properties on pages and reports to control their search ‘After you change these properties by using the Dynamics NAV Development wironment, before the changes Adding Pages and Reports to Tell me ae) line The Business Central client includes the Tell me feature that lets users find objects and online help articles by entering search terms. When you have added a page or 2 report in your extension, you most likely want it to be discoverable to users in Tell me. In AL, you make a page or report searchable from Tell me by setting the UsageCategory property in code. The UsageCategory setting will make the page or report searchable, and the value chosen for the setting will further sub categorize the item. ‘TELL ME WHAT YOU WANTTO DO 7x = ‘On current page (Business Manager) & customer Register 3 new customer, BE Register Customer Payments Process your customer payments by matching amounts received on your bank account Win, Go to Pages and Tasks ‘Show ail 46) > Customers sts > Customer Disc. Groupe ‘Administration > Customer Order Status Tasks Go to Reports and Analysis ‘Show al (50) Customer Labels Reports and Analysis [Customer Listing Reports and Analysis [F_ Customer Register Reports and Analysie Documentation ‘Show all (20) © Tansterrina and Postina Cost Entries Before you define cost allocations, you must understand where cost entries come from. © Manually Adjust the Costs of items ‘Yu can adjust the inventory valuation of an item using the FIFO or Average costing meth. ® Managing inventory Costs ‘Cost management. also referred 10 as “costing”, i concerned with recording and reportin.. Get from Microsoft AppSource ‘Show all (48) D1 yamic commerce Shipping Cons Wanageenpnng cot Srey Dynamics 365 Business Cet, Advanced Inventory Count Simpify inventory counts with comprehensive data entry, reconciliation. posting and anal.. Cash Basis Accounting Cath Basi Accounting ROOT OnaftersubstituteReport oat Root onafteriiascustomLayaut ROOT OnafteretPrintertane ROOT OnopenPage RooT OnafterGetcurrkecord CATLD ontnstRepor’ CHILD onopenPage CHILD onclosePage CAILD onPreseport CTLD onAttersetPaperTrayForReport CHILD MasterRecord - OnPrebatalten pase CHILD MasterecardLines - onPrenat: CHILD MasterRecordLines - OndfterGetRecord 102 CHILD MasterRecordLines - onPostoatalten CHILD MasterRecord - OnPostJatalten CHTLD onaFteriascustontayout CHILD onPosthepore ROOT onqueryCiosePage ~-Pae RoaT onctosePage Pace oat onPreReport ROOT OnAfterGetPaperTrayForReport ROOT MasterRecord - OnAfterGetecord 2 ROOT MasterRecordtines - OnPredatartem RooT MasterRecordLines - OnAfterGetRecord 101 ROOT MasterRecordLines - OnPostDatalten RooT MasterRecord ~ OnPostoatarten ROOT OnPostReport ROOT Ontergedacusent Report Key design guidelines and considerations Multiple-preview mode ‘© Avoid the following implementations: ©. Set global variables in page triggers © Use the OnQueryClose page trigger to change global variables in the report © Depend on instance methods to be called to set state variables before report invocation © The request pages that have savevalues property set to false Ifyou have reports that use any of these implementations, refactor them to ensure report content renders as expected NOTE Ifa legacy report depends on global variable state, the developer can use a single instance codeunitto transfer variable state between the two running instances. The state isthe set inthe primary object and read from the chil object For more information about the flow, see Request page and preview triggers and operations. ‘© Only visible user interface elements are transferred to the preview in child instances. User interaction triggers from the visible request page, like lookup, validate, and other page triggers, aren't invoked in head-less request page flow in the child instance. Design these triggers so that they PREVIEW MODE DESCRIPTION preview & dose The preview & close made isthe only mode supported in Business Central 2020 release wave 1 (version 16) and ‘earlee This mode invokes the preview action within the current report instance, referred to asthe primary instance In this mode, the request page closes when the user previews the report. The user wil then have to run the report again ifthe preview doesnt show the expected result. In the client, a request page that uses this mode will include the Preview & Close button ‘multiple-preview ‘The multiple-preview mode was introduced in Business Central 2020 release wave 1 (version 17). It provides users the abilty to preview a report mukiple times, without dosing the request page. When the preview action is selected, the mode frst captures the vakies in the visible request page controls and fers, Then it invokes a new report instance, refesred to asthe child instance to generate the preview ‘document based on the settings. The request page in the ‘original report instance will remain available after the user doses the preview window. In the cent, a requ the Preview button age that uses this mode wil include For more information to help your design, see Xey Design Guidelines and Considerations. How the mode is set By default, reports use the multiple-preview mode. The mode is determined by two report properties: SaveValues and AllowScheduling, as outlined in the following table: SAVEVALUES ALLOWSHEDULING = TRUE ALLOWSHEDULING = FALSE SaveValues = true Multiple-preview Preview & close Preview & close Preview & close Visible and head-less request page flows There are two different request page flows that can be invoked in the process: a visual request page and a head- less request page. The request page flow used will depend on various design factors. Each type has a different trigger sequence, The visual request page flow is used on the request page instance that appears for the user in the client. In this case, the triggers are executed on the primary instance, The head-less request page flow shows the triggers that are executed when a report runs without a visible request page. The head-less flow occurs under the follawing conditions: In the child instance, when a report uses the multiple-preview mode ‘When a report is scheduled to run in the background ‘© When a reportis invoked with the request page XML data in the parameter list ‘When a report that doesn't have an enabled request page. The following diagram highlights the basic trigger sequence for a request page for the two possible request pages. cancel the report run. If you decide to continue, then the OnPreReport Trigger is called, At this point, no data has yet been processed, When the On?reReport trigger has been run, the first data item is processed unless the processing of the report was ended in the OnPreReport trigger. ™ For more information about the print triggers and operations, see Developing Printer Extensions in Business Central. How dat sms are processed Data items are processed one after the other, each in the same way. When there are no more data items, the OnPostReport Trigger is called to do any necessary post processing, for example, removing temporary files. The process for each data item is as follows: 1, Before the first record is retrieved, the OnPreDataltem Trigger is called, 2, Data item records are processed one ata time, Processing a record involves executing the record triggers and outputting data, After a record is retrieved from the data item, the OnAfterGetRecord (Data Items) Trigger is called. If there's an indented data item, its records are also processed. After the last record in the indented data item, the control returns to the point from which processing was started. In the case, it's the next record of the data item on the next highest level 3. After the last record has been processed, the OnPostataltem Trigger is called, Request page and preview triggers and operations The section outlines the triggers and operations that are related to the report request page and report preview, The following diagram illustrates the main trigger and operation sequence. The focus is on the triggers and actions related to the request page invocation and button actions, See the sections that follow for details about some of the concepts shown, Report Triggers and Runtime Operations PE et) line This article describes the triggers and operations that are executed when a reportis run. The triggers and operations will depend on a few things, lke: ‘* Whether the report has request page ‘* What action the user takes on the request page, like preview, print, and schedule ‘© What preview mode the report uses ‘Some triggers are invoked in the report, while others are invoked on the request page, Understanding the sequence of the triggers and operations will help you design reports that work as expected. Overall report trigger and operations For starters, look at the following diagram that illustrates the general overall flow when a report is invoked, The {low is broken down even further in the next section, which discusses triggers and operations related to request pages ™ For information about how to enter fiter criteria on the request page, see Fitering inthe Business Central application help. Defining a requestpage section (On reports, in addition to defining the filter options by setting the sequestrilterrields property, you can add a requestpage section. In this section, you can set the SaveValues property to true in order to save the values that the end user enters on the request page. When the report is run again, the end user will have the option to Use previously defined filters. You can also add a 1ayout to the request page, specifying an Options section to perform checks. NOTE With request pages that have SaveValues = true , users can preview the report multiple times in the client and the request page remains open. If savevalues ~ false or omitted, a Preview & Close action appears on the request page. In this case, the request page closes once the report has been previewed. requestoage ‘ SaveValues = trues Layout € area(content) 4 roup(options) 4 Caption = “options; Fleld(Postingbate; Postingoatereg) ‘ Applicationtrea = asic, Suite; caption = ‘Posting Oate"; ToolTip = ‘Specifies the posting date for the invoice(s) that the batch Job creates. this fleld must be filled in.) ) > » trigger OnopenPage() begin if PostingbateReq = ab then Postingoatereq := Workate; end; Postingvatereq: Date; See Also Report Object Report Extension Object INX=re 0 [1a |6 (19 ae a) A request page is a page that is run before the report or XMLport starts to execute. Request pages enable end users to specify options and filters for a report and an XMLport. Request pages are defined as part of designing a Report object, a Report Extension Object, or an XMLport object. The syntax is shown further down in this topic. You design the filters on request pages by using the following report and XMLport properties: PROPERTY DESCRIPTION uestFiterHeading Property Sets a caption for the request page tab that i related to a report's data item or an XMLport’ table element, estFiterHeadingML Property Sets the text used as a RequestFiterHeading Property for 3 request page tab. uestFiterfields Property ‘Specifies which columns are automatically included on the tab of the request page that i related to a report's data item or an XMLpor’s table element. The user can set filters fon these columns. NoTE Request pages for XMLports are not supported by the Business Central Web cient in versions prior to Dynamics 365 Business Central 2019 release wave 2. Ifyou try to run an XMLport with a Request page from the web dient in these versions, you receve an error that the XMLport page type is not supported, Alternatively, XMLport request pages do work in the Dynamics NAV Client connected to Business Central By default, a request page is displayed, unless the UseRequesiPageis set to fatse ; then the report or XMLport will start to print as soon as its run. In this case, end users can't cancel the report or XMLport run. tis stil possible to cancel the report or XMLport, but some pages may print By default, without having set anything else a request page will always display the following buttons: # Send to © Print © Preview © Cancel Additionally, you can add more options on the request page to allow the end user to filter the data displayed. Filtering on request pages The columns that you define as _RequestFiiterFields are shown on the request page and can be used for filtering the data before viewing or printing the report. NoTE COnly on the Windows clent,fitering is possible even if Requestriltertields is not set Defining a Report Dataset Te rn You use a report object in the AL Language development environment to define the data model, or dataset, of a report The dataset determines the data that is extracted or calculated from the Dynamics 365 Business Central database tables that can be used in a report, For more information, see Report Object. You build the report dataset from data items andl columns. A data item is a table A column can be: © Afieldin a table # Avariable # An expression © Atext constant Typically, data items and columns correspond to fields in a table, When the reportis run, each data item is iterated forall records in the underlying table, Filters are applied and the dataset is created, When a report is based on more than one table, you must set relations between the data items so that you can retrieve and organize the data You can also extend a dataset from an existing report, to add more columns for example. For more information, see Report Extension Object. Snippet support Typing the shortcut trepert will create the basic layout for a report object when using the AL Language extension in Visual Studio Code. ™ Use Ctrl+Space to trigger IntellSense and get assistance on code completion, parameter info, quick inf, and member lists Example The following example adds the custoner table as the data item and the custonertane and Conpanyilane as fields of a column to the report. For more information on creating a report, see Creating a Report. dataset € ataiten(custoner; Custoner) ‘ colunn(CustonerNanes CustomerNane) « y colunn(Conpanytiane; Conpanyilane) c y tablee « fension 50200 GMOFood extends SaseFoodTable fselds ‘ F1e14(100; “Gt0 Free"; Boolean) { } felé(101; organsc; Boolean) { } fleld(103; calories; Decimal) « DecinalPlaces = 3; > Fiels(182; Producerso; Integer) ( ) table 58202 Prosucer « DataPerCompany = false; Fields ‘ Field(1; 19; Integer) (> Flela(2; Nave; Text[256]) { ) y The report extension - FoodExtension ‘As we have seen in the previous sections, the base table saseFoodrable was extended with the GHoFood extension, To reflect that change, it makes sense to extend the FooaRepost_ to enable displaying the additional set of fields that were added; both to the existing FoodTable and to the new table Producer . To do that, we need to se a report extension object. For more information, see Report Extension Object. In the dataset element, three new columns are added to the Fooarable dataitem, and a new dataites element is introduced that adds columns corresponding to the reports source table. rreportextension $0280 FoodExtension extends FoodReport « apLcLayout = "ExtendedFoodReport.rdl"; ‘ add(Fooatable) ¢ coluan(cia_free; "cho Free") {> colunn(Organic; Organic) { } column(Calories; Calosies) { } » addeinst(nestaurart) € aataiten(Producer; Producer) ‘ Datartemtink = 19 = Feld(Preducert9); DatattemLinkteFerence = FoodTable; colunn(ProducerNane; Name) { } ? y The example code above illustrates how additive changes t bles that are used on reports can use report Report Extension Example ae a) The following topic illustrates how an existing table and reportis extended by using extension objects. The code snippets shown in this example do not provide a full end-to-end scenario that can be deployed, but illustrates the way to extend existing functionality by using the Table Extension Object and Report Extension Object. The base table - BaseFoodTable The report extension will be based on the following base table which holds information about food and specific details that applies to that. The color field in this table is an enum, which is defined with the Foodcolor enum. next table 50100 BaseFoodTable « bataclassification = ToBeClassified; DataPercompany = false: fields ‘ fLele(1; Nave; Text[256]) { ) fielé(2; Colors Enum Foodolor) { } fel6(3} Flavours Text[256]) { ) Fiela(4: “Vegan Foiendly"; Boolean) { } Fiel6(5) “Vegetarian Friencly"; Boolean) ( ) Fiel6(7; Price; decimal) « DecimalPlaces = 25 > Fiela(s; Restaurant; Tnteger) (} ? keys ‘ key(PK Mane) c Clustered = true; » > Defining an enum - FoodColor The Foodcolor enum enables selecting a descriptive color of an item in the GaseFoodrabe ‘ustones table to the Customer - Top 10 List report. For a more advanced example, see Report Extension Example. The example also illustrates how a new field added to the report extension, can be modified using the onseforeattersetRecord trigger. For more information about report extension dataset triggers, see Report Extension Data Set Modify triggers. NOTE Inside the requestpage element, you cannot modify any properties, Using the onznstReport. trigger isnot supported for report extensions. The onPreneport and onPostReport triggers are run after the orginal reports equivalent triggers. ‘tableextension $0120 CustonerTablefxt extends Custoner « fields ‘ ‘Field(5e109; MyField; Integer) « Dataclassification = ToBeClassified; > ? y rreportextension Sei1@ MyExtension extends “Custoner - Top 18 List™ « cataset ‘ aed(integer) € 11 a6 existing field fron base table to dataset ccolunn(frondaseTable; Custoner.GLN) { } 1/ add Fielé From table extending Custoner ‘coluan(fronaaseTabletxt; Customer. syField) ( ) > add(custoner) « U1 add a new Field to the dataset coluan(netweight; netweight) { ) » snodify(custoner) ‘ 11 modify the new, added field ‘rigger OnBeforeaftercetRecord() begin Sf (weightInPounds) then begin netWeight := netweight * 2.25 lend else begin netWeight := netweight end end > ? equestpage { Layout € addafter(show) ‘ 1/ add Field fron table extension to request page eld(FronBaseTableéxt; Custoner.ayFielé) { ) actions { ? ? abel ‘ Lbelnone = ‘LabeLText", conment = °Foo', MaxLength ~ 999, Locked = trues » ‘trigger OnPreReport(); CCoptiontanagenent : Codeunit 42; bein Custrilter := Captionanagenent.GettecordFilterskithcaptions (customer); ons Formataddr : Codeuntt 365) custrilter 1 Texts Ccustaddr : ARRAY [8] OF Text(5@]; Custoner_ListCaptiontbl : Label ‘Customer - List; CcurrReport_PageNocaptionlbl : Label ‘Page's Custoner_Custoner_Post ing GroupCaptiontbl : Label ‘custoner Posting Group’; Customer Custoner_ise_GroupCaptionLbl : Label “Cust. /Item Disc. Gr."; Custoner_inveice Dise CodeCaptiontbl : Label ‘Invoice Disc. Code"; Ccustoner_Custoner_Price GroupCaptionLbl : Label "Price Greup Code ‘customer Paynent_Teras_Codecaptiontbl : Label ‘Paynent Teras Code ‘ustoner_Currency_CodeCaptionib : Label ‘Currency Code"; Total_LC¥_Captiontbl + Label “Total (L015 ™ From the Business Central client, you can export report results as raw data to a Microsoft Excl file. The fle contains all columns of the dataset, but without the layout applied, Use the fle to help validate that the report returns the expected ‘data, and to ensure thatthe report layout controls match the dataset value types. To export a report, run the report and select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see Working with Reports Send to Excel, See Also Report Extension Object, Request Pages Creating an RDL Layout Report Creating a Word Layout Report ‘Adding Help Links from Pages, Reports, and XMLports Page Extension Object Page Properties Developing Extensions AL Development Environment , column (CurrReport_PagenNo;custoner."n0.") } colunn(Custoner_Tablecaption cust ilterjTableCaption +": ' + cust > colunn(cust#iiter;custriiter) > olunn(customer_No;"No.") ) colunn(custoner_Custoner_Posting Group;"Custoner Posting Group") } Ccolunn(Custoner_Custorer_pise_Group;"Custoner ? colunn(Custoner_Involce_Dis¢ Code; "Invoice Disc. Code") ) olunn(Custoner_Custoner Price Group;"Custower Price Group") isc. Grove") } colunn(Custonen_Fin_change_Terms_Code;"Fin. Change Teras Code") > colunn(Custoner_Paynent_Teres_Code;"Payment Terms Code") ) column (Customer Salesperson Codes "Salesperson Code") ) colunn(customer_Currency_ Cod turrency Cod ? colunn(customen_Credit_Linit LCV; "Credit Limit (LeY)") DecimalPlaces-2:0; ) colunn(custoner_Balance_Lc¥s"Balance (LCY)") ? colunn(custaddy_a;custaddr{1]) ? colunn(CustAdde_2;CustAddr(2}) ) colunn(custAdér_3;custadér{3]) ) coluan(custAddr_43¢ustadde4]) > colunn(custAaddr_5;Custddr(5]) ) column (Custoner_Contact; contact) snn(Custoner_Phone_No;"Phone No.") colunn(custaddn_6;Custaddr(6]) > colunn(custaddr_7;custaddr(7]) IMPORTANT ROL layouts can result in slower performance with document reports, regarding actions that are related to the user interface (for example. lice sencing emails) compared to Word layouts. When developing layouts for document reports, we recommend that you design Word layouts instead of RDL. With Word layouts, reports are not impacted by the security constraints on sandbox appdomains lke they are with ROL layouts, From a service perspective, RL layouts are rot trusted, so they will run in a sandbox appdomain that only ives for the current report invocation, ‘Word report layout You create Word layouts by using a Word Document, Word layouts are based on a Word document that includes a custom XML parts that represents the report dataset. For more information, see Creating a Word Layout Report. See Also Reports Report Object Report Extension Object, Report Data Type Creating an RDL Layout Report Creating a Word Layout Report Request Pages Report Extension Object Creating a Report Request Pages Creating an RDL Layout Report Utilizing Read Scale-Out for Better Performance

You might also like