Sunday, October 24, 2021

Crystal report with Dynamic Column

 The objective of this article is to provide a process that can be followed to develop a crystal report with dynamic columns using parameterized column fields and formula fields. 

Before going for this the developer has to decide the maximum number of columns he/she has to display and as per the no. of columns the size of the paper. The developer can define the size of the paper by selecting the Printer Setup in the File menu.

 
There are two ways to display the columns in Crystal Report dynamically. The default is using the infamous Cross Tab component and the other is using parameterized columns. But there are certain limitations to this. 

Where the cross tab does not provide complete control to each individual cell value, for using dynamic columns, the developer has to decide the maximum no columns in design time and all the field values should be of the same data type.
 
Let's take an example of a yearly report where the developer has to create such a report when executed will display only those month values as columns, which are selected with "Total" immediately next. So the view may look like :
 
If the sales of products selected from Mar 2006 to May 2006.
 
Product NameMarAprMayTotal
Pro 1128990191
Pro 2209970199
Grand Total32188160390
 
Same way if the end results for different scenario :
  1. If the date is between Jan 2006 - Aug 2006
     
    Product Name  Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Total

  2. If date is between Jun 2006 - Nov 2006
     
    Product Name  Jun  Jul  Aug  Sep  Oct  Nov  Total
Note: These instructions only work if all the attribute fields are of the same data type as they will be dynamically interchanged using a logic statement. 
 
It seems most of the attribute fields will be of a String data type. We can create formulas in our report that will convert numbers to text using the ToText function. Then, simply use the formula instead of the database field. 

Or, if our organization uses Views or Queries as a data source, convert the data type on that end.
 
Steps to create a report with dynamic columns...
 
1) Determine the maximum number of columns the report page can handle. Or determine the reasonable number of attributes an end-user would want to see. (Consider a report with 50 columns of attributes. It would be unreadable.)
 
2) Create a string parameter for every attribute column on the report. Do not set the default values at this time (see next step).
 
3) Open Note Pad (on your desktop under accessories). Type all possible attributes starting in the top right corner with one below the other (see below).
 
None
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
Total
 
Keep in mind, these will be listed in the picklist and displayed on the report as column headings. The value "None" is important. It will be used in a logic statement, later in these instructions. Save the file (as a text file, .txt) in a shared location all users of the report can access (or on the CE server if using Enterprise).
 
Name the file similar to the .rpt file name combined with the word "attributes" or "parameter" so it is easy to locate.
 
4) Edit each parameter created in step 2 and do the following:
 
Click on "Set default values".
 
Report1.gif
 
Click on "Import pick list".
 
Report2.gif
 
Browse to locate the text file you just created in step 3.
  
Click OK. The list is automatically populated with the values in the text file.
 
5) Create empty formulas for the detail fields. The Design will look something like this...
 
Row Num Product name {?Month1} {?Month2} {?Month3}{?Month4}........................{?Total}
 
{rownum} {db.ProdName} {@mon.1-Detail} {@Mon.2-Detail} {@Mon.3-Detail}.............{@Total-Detail}
 
images3.gif
 
Just use the Insert Fields box and create the formulas upfront. Leave them empty. Place them on the Design Tab. Then use the Insert Fields box to edit them later.
 
6) Edit the Mon.1-Detail field. Enter the following logic...
 
(assuming the Stored Proc or View returning column names as ProdName Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
if {?Month1}= "JAN" then {DB.JAN}
 
else if {?Month1}= "FEB" then {DB.FEB}
 
else if {?Month1}= "MAR" then {DB.MAR}
 
else if {?Month1}= "APR" then {DB.APR}
 
else if {?Month1}= "MAY" then {DB.MAY}
 
else if {?Month1}= "JUN" then {DB.JUN}
 
else if {?Month1}= "JUL" then {DB.JUL}
 
else if {?Month1}= "AUG" then {DB.AUG}
 
else if {?Month1}= "SEP" then {DB.SEP}
 
else if {?Month1}= "OCT" then {DB.OCT}
 
else if {?Month1}= "NOV" then {DB.NOV}
 
else if {?Month1}= "DEC" then {DB.DEC}
 
------ add the total field value if applicable
 
else 0;
 
Save the formula changes, but don't exit the formula editor. Copy the entire logic statement, then exit.
 
7) Edit {@Mon.2-Detail}. Paste the logic statement from step 6 into the Formula editor. Use Find/Replace in the formula Editor to find "?Month1" and replace with "?Month2".
 
Then save the change. Repeat this process for the remaining column detail formulas.
 
Note: In the case of Total field it will start from the second field onwards. So to display the Total value add the line below (in case if the second column will be counted as the total column)
 
else if {?Month2}= "Total" then {@Month_Det1}
 
Same way for all other columns also add .....
 
else if {?Month3}= "Total" then {@Month_Det1} +  {@Month_Det2} If 3rd will be the Total column
 
else if {?Month4}= "Total" then {@Month_Det1} +  {@Month_Det2} + {@Month_Det3} if 4th col will be the Total and so on.. 
 
8) You may also want to add conditional formatting to suppress the columns that are not used. To do this you need to edit each field in the column (header and detail).
 
Start with Column 1's heading...
 
Right-click on the parameter field, {?Column 1}.
 
Select the Format field.
 
On the Common tab find Suppress at the top.
 
Report4.gif
 
Go to the right and click on the "X+2" button. Enter the following logic in the Format formula editor:
 
Report5.gif
 
if {?Month1}="None" then true else false;
 
Save, but don't close. Copy the statement. Close the Format formula editor.
 
Repeat on the {@Month.1-Detail} field using the pasted statement.
 
Repeat on the remaining columns, but remember to change the column number in the logic.
 
9) To add a running total for each column select a new running total field as display below
 
Report6.gif
 
Select the parameterized field to sum up and in the type of summary field select Sum from the dropdown.
 
Repeat the same process for all the columns as displayed above and also suppress them as per the condition (Refer Sec 8 to make a conditional suppress).
 
How it works :
 
1) The column heading will display the parameter value selected by the user. It will display just as you typed it into the default value list when creating the parameter.
 
Example :
 
In the example below I am displaying the records of references during the month of Aug and Sep 2006 including the total and grand total value.
 
Select Aug for the month1 parameter field
 
Report7.gif
 
Repeat it to select Sep for month2 parameter field and Total for month3 field. And select From Date and To date as 1st Aug 2006  - 30th Sep 2006.
 
2) The detail section will display the corresponding attributes for each item record based on the parameter values provided at run time.
 
On execution of this report, it will display like the below
 
images4.gif

No comments:

Post a Comment

No String Argument Constructor/Factory Method to Deserialize From String Value

  In this short article, we will cover in-depth the   JsonMappingException: no String-argument constructor/factory method to deserialize fro...