Skip to content

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.