Nav2013 Enus Cssol 06
Nav2013 Enus Cssol 06
Module Overview
The Seminar module to this point includes the following:
These features are integrated into the standard application so that you can access
them from a new Seminar Management menu in the Departments area. The
next step is to create reports for the module.
Objectives
Prerequisite Knowledge
Before analyzing and implementing the report functionality that is covered in this
module, we will review the following concepts :
Lesson Objectives
Report Triggers
Each report object consists of several elements that can contain the following
triggers:
Each of these elements has a fixed number of event triggers that execute during
report execution. You must understand the order that some frequently used
triggers execute. The following list details the order in which these common event
triggers execute:
1. When a user starts the report, the OnInitReport trigger is called. This
is the first trigger that runs. It performs processing that is required
before any part of the report can run. If the Request page is needed,
the OnInitReport trigger runs before the Request page is
displayed. Use the OnInitReport trigger to initialize variables and to
populate default values on the Request page.
When there are no more data items, the OnPostReport trigger is called. Use this
trigger to do any necessary post processing, for example, cleaning up by
removing temporary files.
Report Functions
You can use only certain functions in reports. Use these functions in complex
reports. For a full listing of report functions, refer to the Microsoft Dynamics NAV
2013 Developer and IT Pro Help on the installation media or on MSDN. This
developer Help file also contains useful walkthroughs to assist you in familiarizing
yourself with Report Designer.
CurrReport.SKIP: Use this function to skip the current record of the current data
item. If a record is skipped, it is not included in totals and it is not printed.
Skipping a record in a report is much slower than never reading it at all. Therefore,
use filters as much as you can.
CurrReport.BREAK: Use this function to skip the rest of the processing of the
data item that is currently processing. The report resumes processing the next
data item. All indented data items under the data itemthat caused the break are
also skipped.
CurrReport.QUIT: This function skips the rest of the report; however, it is not an
error. It is a typical ending for a report. When you use the QUIT function, the
report exits without committing any changes that were made to the database
during the execution. The OnPostReport trigger will not be called.
This makes sure that any functionality that depends on the CurrReport.PREVIEW
function being FALSE is called correctly when doing the actual print. If you run a
client report definition (RDLC) report layout in preview mode and do not call the
CurrReport.PREVIEW function, then you can print from the Print Preview
window.
ProcessingOnly Report
A processing-only report is a report object that does not print, but only
processes table data. Processing table data is not limited to processing-only
reports. Reports that print can also change records. This section also applies to
those reports. You can specify a report to be "Processing Only" by changing the
ProcessingOnly property of the Report object. The report functions as it is
supposed to (processing data items); however, it does not generate any printed
output.
When the ProcessingOnly property is set, the Request page for the report
changes slightly, as the Print and Preview buttons are replaced with an OK
button. The Cancel and Help buttons remain unchanged.
• Decide which tables are read. These are the data items.
• Design the report so that most of the code goes into the
OnAfterGetRecord trigger.
• Use the INSERT or MODIFY functions in the tables, as appropriate.
• Use a dialog to show the user the progress and let the user cancel the
report.
• The Request page functionality that lets the user select options and
filters for data items is easily available in a report, but it is difficult to
program in a codeunit.
• The Report Dataset Designer helps you visualize the program
execution flow.
• Instead of writing code to open tables and to retrieve records, use
report data items to provide a declarative way to access data.
• A participant list
• A processing-only report that posts invoices
Lesson Objectives
Solution Analysis
The client's functional specifications require a Participant List report. This is a list
of enrolled participants for a seminar. This report should be available from both
the main Seminar menu and the Seminar Registration page.
Solution Design
The Seminar Report Selection page displays the available seminar reports.
Seminar Menu: Modify this menu by adding the following menu item to the
Reports Group (under Order Processing):
Functional Design
The information for the report originates from the Seminar Registration Header
table and the Seminar Registration Line table.
When users run this report, they select which Seminar Registration Headers to
include. For each Seminar Registration Header table, the program then prints
information from each corresponding Seminar Registration Line table.
Implementation of the Participant List report requires the creation of one new
table that is called the Seminar Report Selections table. You must also change
the Seminar Registration Header table .
A Participant List report is required for the RoleTailored client, along with a way
to select and run seminar reports. Create a Participant List report that lists all
registrations by seminar. Use the typical Header/Detail list format and logic. Then
create a way to selected seminar reports from a page.
Detailed Steps
1. Add a field to the Seminar Registration Header table (123456710).
No. Field Name Type Length Comment
40 No. Printed Integer Must not be
editable.
Detailed Steps
1. Create the Seminar Registration-Printed codeunit (123456702).
a. Set the property to specify the Seminar Registration Header
table as the source table for this codeunit.
b. Enter code in the appropriate trigger so that when the program
runs this codeunit, it does the following tasks:
Finds the Seminar Registration Header record.
Increases the No. Printed by 1.
Changes and commits the table.
FIND;
MODIFY;
COMMIT;
Detailed Steps
1. Create a new report.
a. In the Object Designer, click New to create the Seminar Reg.-
Participant List report (123456701).
6. Use the property of the columns so that captions are available for the
fields of both data items.
a. Set the Includecaption property to True for all columns.
7. Set the property for the report so that the caption is Seminar Reg.-
Participant List.
a. In the Report Dataset Designer goto the last row and click the
down arrow.
b. Open the Properties window, the report properties are displayed.
c. Set the Caption property to Seminar Reg.- Participant List.
8. Enter code in the appropriate trigger so that after the program gets
the record of the Seminar Registration Header table, the program
calculates the Instructor Name field.
a. Select the Seminar Registration Header data item and click F9.
b. In the OnafterGetRecord trigger type the following code:
CALCFIELDS(“Instructor Name”);
To render a report from inside the RoleTailored client, you must create a Visual
Studio client report definition (RDLC) report layout.
Task 1: Use Visual Studio Report Designer to create a layout for the
report.
The Header row in the table now contains the caption fields
for the fields from the Seminar Registration Line table.
e. In the second row of the table, in the first text box, right-click the
text box, and then select the following field from the shortcut
menu: [BilltoCustomerNo_SeminarRegistrationLine]
f. Repeat this for the following fields:
[ParticipantContactNo_SeminarRegistrationLine]
[ParticipantName_SeminarRegistrationLine]
The table should look like the “Table with Group Header Rows” figure.
Detailed Steps
1. Add a page header to the report.
a. In the Page Header, add four textboxes: one on the left side and
three on the right side.
b. In the text box on the left side of the page header, enter the
following value expressions:
=Parameters!SeminarRegistrationHeader.Value
c. In the three text boxes on the right side, add the following
expressions:
=Globals!ExecutionTime
=User!UserID
Detailed Steps
1. To add the Company Name to the report, the dataset must be
updated. Add an integer data item to the bottom of the data item
designer.
a. Make sure that the Integer data item is not indented.
b. Filter the Integer data item so that it only displays one record.
i. In the DataItemTableView propertie of the Integer data
item enter the following Value:
WHERE(Number=CONST(1))
=Last(Fields!CompanyInformation_Name.Value, "DataSet_Result")
Detailed Steps
1. Because of the new integer data item the dataset has changed. It now
has one additional row that contains the company name. Filter out
this row in the table.
a. Add a Filter to the Group in the Tablix to make sure that only the
following lines are allowed:
=Len(Fields!No_SeminarRegistrationHeader.Value) > 0
Detailed Steps
1. Save and Run the Report.
a. Save the report layout and close Visual Studio.
b. Save the report in the NAV Report Designer, and then accept the
changed layout. See the “Report 123456701 Rendered in
RoleTailored client” figure for an example.
Detailed Steps
1. Import the starter object.
a. In Object Designer, click File > Import.
b. Browse to the file Mod06\Labfiles\Lab 6.B - Starter - Report
Selection.fob.
Detailed Steps
1. Test the application.
a. If there are no Seminar Registration records, create one by
selecting Seminars > Order Processing > Registrations from
the main menu. Complete all fields in the General and Seminar
Rooms FastTabs and add at least two participants.
b. Use the Seminar Report Selection window to set up the Seminar
Reg.-Participant List as the report to run for Registration. To do
this, select Seminars > Setup > Report Selections from the
main menu. Select Registration as the Usage and 123456701 on
the first line for the Report ID. The report name should be filled
in automatically.
c. Open the Seminar Registration page again, and then view the
record prepared in Step 1. Click Print.
d. The Request page should open with the No. set to the current
registration. Select Print or Preview to print and check the
report.
e. Try to print the report by using different parameters and different
registration data to verify that it works correctly.
Lesson Objectives
Solution Analysis
This ProcessingOnly Report creates an invoice for each customer in a filter that is
specified by the user. The report has lines for each participant in a registered
seminar that falls within the filter set by the user. The user should also have the
option of either creating the invoices, or creating and posting them at the same
time.
This type of report is known in Microsoft Dynamics NAV as a batch job. A batch
job in Microsoft Dynamics NAV is a routine that processes data in batches, such as
the Adjust Exchange Rates Batch Job, or Batch Posting Sales Orders, Invoices, and
Credit Memos.
If you set up numerous orders, invoices, or credit memos, you can post them with
a batch job. You can post them at night or at another convenient time. Batch
posting invoices and credit memos functions exactly like orders.
Solution Design
Use the Seminar Ledger Entries to access all charges to invoice for posted
seminars. The report creates Sales Headers and Sales Lines as appropriate. If the
user selected the option to also post the invoices, the report runs the posting
process for sales invoices.
This report differs from the previous two reports because it is not a print report,
but is a ProcessingOnly report.
Detailed Steps
1. Import the report object.
a. In the development environment, open the Object Designer using
Tools > Object Designer.
b. Locate the Mod06\LabfilesLab 6.B - Starter.fob.
c. Select File > Import to import the report.
Detailed Steps
1. In Object Designer, locate report Create Seminar Invoices
(123456700), and then complete the C/AL code according to these
guidelines.
a. Verify the property to specify that this report is for processing-
only.
b. Verify a data item for the Seminar Ledger Entry table and set
the properties for the data item as follows:
i. Specify the Key in DataItemTableView property of the
data item to sort by the following fields:
Bill-to Customer No.
Document No.
Charge Type
Participant Contact No.
ii. Specify that the user can filter on the Bill-to Customer
No., Seminar No., and Posting Date.
iii. Specify the variable name of the data item as
SeminarLedgerEntry.
2. Verify that these global variables are defined for the report.
Name Data Type Subtype Length
Window Dialog
PostingDateReq Date
DocDateReq Date
CalcInvoiceDiscount Boolean
PostInvoices Boolean
NextLineNo Integer
NoOfSalesInvErrors Integer
NoOfSalesInv Integer
IF CalcInvoiceDiscount THEN
SalesCalcDiscount.RUN(SalesLine);
GET("Document Type","No.");
COMMIT;
CLEAR(SalesCalcDiscount);
CLEAR(SalesPost);
NoOfSalesInv := NoOfSalesInv + 1;
CLEAR(SalesPost);
NoOfSalesInvErrors := NoOfSalesInvErrors + 1;
END;
END;
INIT;
"No." := '';
INSERT(TRUE);
VALIDATE("Posting Date",PostingDateReq);
VALIDATE("Document Date",DocDateReq);
VALIDATE("Currency Code",'');
MODIFY;
COMMIT;
NextLineNo := 10000;
END;
6. Enter code into the appropriate trigger so that just before the data
item is run, the program performs these tasks.
a. In the OnPreDataItem trigger enter code that:
i. Shows an error if the PostingDateReq or DocDateReq is
empty by using the text constants Text000 and Text001.
ii. Opens a dialog window with the text constants Text002,
Text003, and Text004.
Code Example
IF PostingDateReq = 0D THEN
ERROR(Text000);
IF DocDateReq = 0D THEN
Window.OPEN(
Text002 +
Text003 +
Text004);
7. Enter code in the appropriate trigger so that after the program gets a
record for the DataItem, the program performs these tasks.
a. In the OnAfterGetRecord trigger enter code that:
i. If the No. of the Customer record differs from the Bill-to
Customer No., the program gets the Customer record
that corresponds to the Bill-to Customer No.
ii. If the Customer record is blocked for All or Invoice, the
NoOfSalesInvErrors increments by 1 (one).
iii. If the Customer is not blocked for All or is only blocked
for Invoice, the program proceeds with the following
tasks:
If the Bill-to Customer No. differs from that on the
current Sales Header record, the program updates
the dialog window with the new Bill-to Customer
No.
If the No. on the Sales Header is not blank, it runs the
FinalizeSalesInvoiceHeader function.
iv. The program then runs the InsertSalesInvoiceHeader
function and sets the Document Type field and the
Document No. field on the Sales Line to be those of the
Sales Header.
v. Updates the dialog window with the Sales Registration
No.
vi. Sets the No. of the Sales Line depending on whether the
Charge Type that is being posted is for an instructor,
room, or participant.
vii. Completes the following Sales Line fields as follows:
Document Type and Document No. from the Sales
Header
Line No. from the NextLineNo variable
Description from the Seminar Ledger Entry
Code Example
NoOfSalesInvErrors := NoOfSalesInvErrors + 1;
FinalizeSalesInvoiceHeader;
InsertSalesInvoiceHeader;
END;
CASE Type OF
Type::Resource:
BEGIN
SalesLine.Type := SalesLine.Type::Resource;
"Charge Type"::Room:
"Charge Type"::Participant:
END;
END;
END;
SalesLine.VALIDATE("No.");
Seminar.GET("Seminar No.");
ELSE
SalesLine.Description := Seminar.Name;
SalesHeader.TESTFIELD("Currency Factor");
SalesLine."Unit Price" :=
ROUND(
CurrencyExchRate.ExchangeAmtLCYToFCY(
WORKDATE,SalesHeader."Currency Code",
END;
SalesLine.VALIDATE(Quantity,Quantity);
SalesLine.INSERT;
END;
8. Enter code in the appropriate trigger so that when the program posts
the DataItem, it performs these tasks.
a. In the OnPostDataItem trigger enter code that:
i. Closes the dialog window.
ii. If the No. of the Sales Header is blank, the program
displays a message that states there is nothing to invoice.
iii. If the No. of the Sales Header is not blank, runs the
FinalizeSalesInvoiceHeader function.
iv. The program displays a message that displays the
number of errors that occurred, if any, or the number of
invoices that were created.
Code Example
Window.CLOSE;
MESSAGE(Text007);
FinalizeSalesInvoiceHeader;
IF NoOfSalesInvErrors = 0 THEN
MESSAGE(
Text005,
NoOfSalesInv)
ELSE
MESSAGE(
NoOfSalesInvErrors)
END;
9. Access the Request Page Designer by clicking View > Request Page.
a. Add an Options group to the Request page and include these
variables:
PostingDateReq
DocDateReq
CalcInvoiceDiscount
PostInvoices
b. Set the property for the Request page so that the page saves the
values after the page is closed.
c. Enter code in the appropriate trigger so that when the Request
page is opened, if the PostingDateReq and DocDateReq
variables are not filled, they are set to the work date and set the
CalcInvDisc value to the value of the Calc. Inv. Discount field in
the Sales Setup.
i. In the OnOpenPage trigger of the Request Page enter
the following code:
Code Example
IF PostingDateReq = 0D THEN
PostingDateReq := WORKDATE;
IF DocDateReq = 0D THEN
DocDateReq := WORKDATE;
SalesSetup.GET;
d. The Request Page will now resemble the Figure: REQUEST PAGE
OF CREATE SEMINAR INVOICES
Task 3: Testing
Detailed Steps
1. To test this part of the seminar module, complete the steps that are
described in the previous exercises. In particular, make sure that the
Customer who is associated with the registrations that are being
tested is set up correctly.
a. Click Seminars > Periodic Activities > Periodic Activities from
the main menu. The Create Seminar Invoices Request page
opens.
b. Enter data so that one or more posted registrations meet the
criteria. If there are no posted registrations, create one.
c. Click OK to run the ProcessingOnly Report.
d. Look at the Sales Invoices that were created. See that the header
and lines were created correctly based on the Seminar
information.
e. Expect to have one invoice per Bill-to Customer with a line for
each contact registered.
f. Check that the data flowed correctly from the registration to the
invoice.
g. Try running the Create Seminar Invoices process with the Post
Invoices Option marked and unmarked and verify that the Sales
Invoices are posted as indicated.
Module Review
Module Review and Takeaways
In this module, you created two reports. The first, Participant List, was a typical
report. The second report was a processing-only report that enabled you to create
invoices for customers with participants in completed seminars.
In the next module, you will add statistics to the Seminar module.
Sequencing Activity
Put the following steps in order by numbering each to indicate the correct order.
Steps
OnPreDataItem
OnPreDataItem
OnPostDataItem
OnPostReport
OnPreReport
OnAfterGetRecord
OnAfterGetRecord
OnInitReport
OnInitReport
OnPostReport
OnPreReport
OnPostDataItem
1. What report function would you use to skip the processing of one record in a
DataItem?
3. In what trigger do you first have access to the values that the user entered on
the Request page?
Sequencing Activity
Steps
5 OnPreDataItem
5 OnPreDataItem
9 OnPostDataItem
11 OnPostReport
3 OnPreReport
7 OnAfterGetRecord
7 OnAfterGetRecord
1 OnInitReport
1 OnInitReport
11 OnPostReport
3 OnPreReport
9 OnPostDataItem
1. What report function would you use to skip the processing of one record in a
DataItem?
MODEL ANSWER:
MODEL ANSWER:
In Codeunits, you must write all of the code to build the data record looping
mechanism. Report objects have this mechanism built in by default. It is much
easier to obtain user input by using a report object.
MODEL ANSWER:
The first trigger that runs after the user has completed the Request page is
the OnPreReport trigger. This trigger is used to evaluate the user's input
before it continues with the data items.