View RSS Feed

Development Team Blog

Visual Report Writer and The Web (XI)

Rate this Entry
In this eleventh blog about Visual Report Writer and the Web I want to take you to the last not yet discussed report that can be found at the Live Demo website (European Server, USA server) named top 10 sales persons. If this is the first blog you read I encourage you to read 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)) and 10: Four Wine Data Based Reports). Meanwhile we have been able to release the Alpha II version of Visual Report Writer 3.0 and the 2.1+ Library only setup. The latter one is needed to make the web reporting using the 17.1 DataFlex Web Framework easy and look like at the demo website.

The Report
The report is a simple but at the same time a complex report. The report purpose is to show the 10 best performing sales persons in a company. The data is collected from the WebOrder sample data. The report runs through all orders and sub totals the extended price column of the order detail rows per sales person. The report groups the data by sales person name 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 which is 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). This and a couple of other things make the report look slow. The report itself is a good candidate report for adding charts in a next version of Visual Report Writer.

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 at the server and shown in a cWebIFrame control. The checkbox (cWebCheckbox) makes it possible to show the totalized sales figure for the other sales persons as 11th value. The checkbox value is used to set a report parameter which is used to determine if the report footer section should be suppressed or not.
Procedure OnInitializeReport
    Boolean bShowOthers
    Integer iParameter
    Get pbShowOthers to bShowOthers
    Get ParameterIdByName C_USEMAINVRWREPORTID 'ShowOthers' to iParameter
    Set psParameterValue C_USEMAINVRWREPORTID iParameter to bShowOthers
The special feature of this report integration is the possibility to show report statistics. The Visual Report Writer engine sends multiple event messages during report execution passing information about load time of the report, time to read and sort the data, 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 webproperty.
Procedure OnReportStatistics Integer iType Integer iValue                
    Send HandleReportStatisticsValues of oStatisticsHandler False iType iValue
The oStatisticsHandler object is an instance of the cWebObject class. In the object a web synchronized property is defined to hold the information.
Object oStatisticsHandler is a cWebObject
    { WebProperty = True }
    { DesignTime = False }
    Property String psReportStatistics
Synchronized properties can only be created based on a simple data-type such as string, integer etc. In this oStatisticsHandler object a string is used which will hold all the information about the report statistics. The values are stored in a value-pair way (type, separator, value), all concatenated in one string. The HandleReportStatisticsValues method finds the passed iType value and if present will add the iValue value 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
        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
        Else Begin
            Move (sReportStatistics - String (iType) - '=' - String (iValue)) to sReportStatistics
    WebSet psReportStatistics to sReportStatistics
The collected statics information can be viewed by clicking the tool-bar button for this. The tool-bar button opens a cWebModalDialog object for showing the information. For each possible statistics value a cWebLabel object will be present. Looking at 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"
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
    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
    Send Popup hoReturnObj
The ShowStatisticValue method places the statistics value in the correct / 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
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 get edit rights.