Business requirement
My user wanted to be able to run a report for which the data could be dynamically grouped and sorted depending on some choice the user made upon starting up the report. According to the choice made, some other Sections should appear in between the grouped report data blocks.
Solution
Create a new BaseEnum, let’s call it ProjCust, with the different sorting and/or grouping possibilities, for example one to group by ProjId and one to group by CustAccount.
Create the report Class.
Define in the classDeclaration a DialogField and variable to handle the different sorting/grouping possibilities for the report.
public class TutorialGroupReport_GroupReport
extends RunBaseReport
{
DialogField dialogReportBy;
ADUProjCustDlvDate reportBy;
#localmacro.CurrentList
reportBy
#endmacro
}
In the dialog method, the possibilities to sort/group the report data is shown.
public Object dialog()
{
DialogRunbase dialog = super();
;
dialog.addGroup("@SYS1046");
dialogReportBy =
dialog.addFieldValue(TypeId(ProjCust),
reportBy,
"@SYS55014");
return dialog;
}
In the getFromDialog method, store the sorting/grouping option chosen by the end user
public boolean getFromDialog()
{
;
reportBy = dialogReportBy.value();
return super ();
}
Create a method to return the option chosen by the end user.
ProjCust reportBy()
{
return reportBy;
}
Create an updateQuery method, which will adapt dynamically the report Query based on the option chosen by the end user
public Query updateQuery()
{
Query query;
QueryBuildDataSource queryBuildDataSource;
QueryBuildRange queryBuildRange;
;
query = queryRun.query();
queryBuildDataSource =
query.dataSourceTable(tableNum(ProjTable));
switch (this.reportBy())
{
case ProjCust::ProjId:
queryBuildDataSource.addSortField(
fieldNum(ProjTable,ProjId));
break;
case ProjCust::CustAccount:
queryBuildDataSource.addSortField(
fieldNum(ProjTable,CustAccount));
queryBuildDataSource.addSortField(
fieldNum(ProjTable,ProjId));
break;
default: // In default, error.
throw error(strFmt("@SYS27147",
this.toString()));
}
return query;
}
Call the updateQuery method in the run method.
void run()
{
;
this.updateQuery();
super();
}
Add the other appropriate methods to the class, such as a lastValueElementName, pack, unpack, description and main method.
Create the Report and the Design of it.
Add your report Class and the report DataSource to be grouped/sorted dynamically as variable the classDeclaration
public class ReportRun extends ObjectRun
{
TutorialGroupReport_GroupReport tutorial_GroupReport;
ProjTable projTable;
}
Assign the caller to the report Class variable in the init method.
public void init()
{
super();
tutorial_GroupReport = element.args().caller();
}
In the fetch method you can change the sorting/grouping dynamically based on the choice of the end user and if necessary add additional design stuff.
public boolean fetch()
{
QueryRun queryRunProjTable;
ProjId parentProjId;
CustAccount custAccount;
;
queryRunProjTable = new QueryRun(
tutorial_GroupReport.updateQuery());
this.queryRun(queryRunProjTable);
while (queryRunProjTable.next())
{
projTable = queryRunProjTable.get(
tableNum(ProjTable));
switch (tutorial_GroupReport.reportBy())
{
case ProjCust::ProjId:
if (projTable.ParentId != parentProjId)
this.execute(1);
parentProjId = projTable.ParentId;
break;
case ProjCust::CustAccount:
if (projTable.CustAccount != custAccount)
this.execute(2);
custAccount = projTable.CustAccount;
break;
default: // In default, error.
throw error(strFmt("@SYS27147",
this.toString()));
}
this.send(projTable);
}
return true;
}
Continue reading......