Visual Report Writer and The Web (XI)¶
In this eleventh blog about Visual Report Writer and the Web, I want to take you to the last report that has not yet been discussed, which can be found at the Live Demo website (European Server, USA server) named "Top 10 Sales Persons." If this is the first blog you are reading, I encourage you to check out the ten other blogs: 1. The Solution 2. Invoices Report 3. The Cleanup 4. The CustomerList 5. The OrderList 6. The Credit and Balances Overview 7. Inventory Stock Levels 8. Sick Leave 9. FileList (RDS) 10. Four Wine Data Based Reports
Meanwhile, we have released the Alpha II version of Visual Report Writer 3.0 and the 2.1+ Library only setup. The latter is needed to facilitate web reporting using the 17.1 DataFlex Web Framework, making it easy to replicate the demo website.
The Report¶
The report is both simple and complex. Its purpose is to show the 10 best-performing sales persons in a company. The data is collected from the WebOrder sample data. The report processes all orders and subtotals the extended price column of the order detail rows per sales person. It groups the data by sales person name while hiding the details section of the report (the order detail lines are not printed, but the formulas in the section are executed). In the details section, the extended price is used to create a running total value. To compare the results of a sales person, the total amount of sales and different sales persons is calculated in a sub-report executed in the page header section. This means that the data is read twice (once for the sub-report and once for the main report), which contributes to the report's perceived slowness. This report is a good candidate for adding charts in a future version of Visual Report Writer.
Integration¶
The report integration is similar to the integrations shown in the other blogs. The output is stored in a PDF file in the reports cache folder on the server and displayed in a cWebIFrame control. The checkbox (cWebCheckbox) allows the totalized sales figure for the other sales persons to be shown as an 11th value. The checkbox value is used to set a report parameter that determines whether the report footer section should be suppressed.
Procedure OnInitializeReport
Boolean bShowOthers
Integer iParameter
Get pbShowOthers to bShowOthers
Get ParameterIdByName C_USEMAINVRWREPORTID 'ShowOthers' to iParameter
Set psParameterValue C_USEMAINVRWREPORTID iParameter to bShowOthers
End_Procedure
A special feature of this report integration is the ability to show report statistics. The Visual Report Writer engine sends multiple event messages during report execution, passing information about load time, time to read and sort the data, and format the pages. This event is called OnReportStatistics. In the cVRWReport integration of this view, this method is used to collect the information in a web property.
Procedure OnReportStatistics Integer iType Integer iValue
Send HandleReportStatisticsValues of oStatisticsHandler False iType iValue
End_Procedure
The oStatisticsHandler object is an instance of the cWebObject class. In this object, a web synchronized property is defined to hold the information.
Object oStatisticsHandler is a cWebObject
{ WebProperty = True }
{ DesignTime = False }
Property String psReportStatistics
End_Object
Synchronized properties can only be created based on simple data types such as string, integer, etc. In this oStatisticsHandler object, a string is used to hold all the information about the report statistics. The values are stored in a value-pair format (type, separator, value), all concatenated into one string. The HandleReportStatisticsValues method finds the passed iType value and, if present, adds the iValue to the already stored value. If the iType value is not found, the member will be added. This is done with the following code:
Procedure HandleReportStatisticsValues Boolean bReset Integer iType Integer iValue
String sReportStatistics sOldValue sNewValue
Integer iEqPos iSemiColonPos iOldValue iNewValue
If (not (bReset)) Begin
WebGet psReportStatistics to sReportStatistics
If (Right (sReportStatistics, 1) <> '') Begin
Move (sReportStatistics - ';') to sReportStatistics
End
Move (Pos (String (iType) - '=', sReportStatistics)) to iEQPos
If (iEQPos > 0) Begin
Move (Pos (';', sReportStatistics)) to iSemiColonPos
Move (Mid (sReportStatistics, iSemiColonPos - iEqPos, iEqPos + 1)) to iOldValue
Move (iOldValue + iValue) to iNewValue
Move (String (iType) - '=' - String (iOldValue)) to sOldValue
Move (String (iType) - '=' - String (iNewValue)) to sNewValue
Move (Replace (sOldValue, sReportStatistics, sNewValue)) to sReportStatistics
End
Else Begin
Move (sReportStatistics - String (iType) - '=' - String (iValue)) to sReportStatistics
End
End
WebSet psReportStatistics to sReportStatistics
End_Procedure
The collected statistics information can be viewed by clicking the toolbar button for this. The toolbar button opens a cWebModalDialog object to display the information. For each possible statistics value, a cWebLabel object will be present. Looking at the report open, the object code is:
Object oReportOpen is a cWebLabel
Set psLabel to "Report Open:"
Set pbShowLabel to True
Set psCaption to '--- ms'
Set peLabelAlign to alignRight
Set psCSSClass to "StatisticsValue"
End_Object
The CSS class defined for this control is simple; it "only" makes the label bold.
#OWEBAPP .StatisticsValue .WebLabel_content {
font-weight: bold;
}
In the procedure to open the modal dialog, the string with statistics information is parsed with the following code:
Procedure ShowStatisticsDialog Handle hoReturnObj String sReportStatistics
Integer iStartPos iSemiColonPos iEqPos iType iValue
String sData
If (Right (sReportStatistics, 1) <> ';') Begin
Move (sReportStatistics - ';') to sReportStatistics
End
Move 1 to iStartPos
Move (Pos (';', sReportStatistics, iStartPos)) to iSemiColonPos
While (iSemiColonPos > 0)
Move (Mid (sReportStatistics, iSemiColonPos - iStartPos, iStartPos)) to sData
Move (Pos ('=', sData)) to iEQPos
Move (Left (sData, iEqPos - 1)) to iType
Move (Mid (sData, iSemiColonPos - iEqPos, iEqPos + 1)) to iValue
Send ShowStatisticValue iType iValue
Move (iSemiColonPos + 1) to iStartPos
Move (Pos (';', sReportStatistics, iStartPos)) to iSemiColonPos
Loop
Send Popup hoReturnObj
End_Procedure
The ShowStatisticValue method places the statistics value in the corresponding cWebLabel object. This is a large CASE statement.
Procedure ShowStatisticValue Integer iType Integer iValue
Case Begin
Case (iType = C_VRWReportOpen)
WebSet psCaption of oReportOpen to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWExecutionPlan)
WebSet psCaption of oReportExecutionPlan to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWReadRecords)
WebSet psCaption of oReadRecords to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWSortRecords)
WebSet psCaption of oSortRecords to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWFormatPage)
WebSet psCaption of oFormatPage to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWExecution)
WebSet psCaption of oReportExecution to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWDatabaseRefresh)
WebSet psCaption of oDatabaseRefresh to (String (iValue) + ' ms')
Case Break
Case (iType = C_VRWCountPages)
WebSet psCaption of oCountPages to (String (iValue) + ' ms')
Case Break
Case End
End_Procedure
Note: For version 3.0, the number of statistics values has been changed.
This concludes the 11th blog about Visual Report Writer integration for the web. In the next blog, I plan to discuss some remaining features of the Live Demo Website, such as login to gain edit rights.