Visual Report Writer and The Web (IX)
by
, 2-Jun-2013 at 01:30 AM (13826 Views)
In this ninth blog about Visual Report Writer and the Web I want to take you to the next report that can be found at the Live Demo website (European Server, USA server) named FileList (RDS). If this is the first blog you read I encourage you to read the eight 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) and 8: Sick Leave). 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
Sometimes you as programmer think that there are better ways to collect the data than a report writer or an SQL engine can come up with. Or faster ways. This is not always true but there are certainly moments that it is. For example if you have an OR construction in the data selection it might very well impossible for the report engine to use the most optimal way to collect the data. For these situations Visual Report Writer offers you the use of RDS as data source. RDS as abbreviation stands for Runtime Data Source and the developer collects the data in an array and passes this memory data to the report engine to be used as if it was a database. Next to "smarter" data collection there is another reason for using RDS; you can make a report on data that isn't really a database or very hard to access as a database. The report used for this ninth example is based on such a data-source; the famous filelist in DataFlex.
A RDS report starts with the row layout description. You define the columns of each row; the names, length and data-type of each row. For the filelist report this is "simple", there are 4 values known; table-number, root-name, display-name and logical-name. From documentation we can discover that the root-name is 40 characters, the display-name is 32 and the logical-name (since v17.0) is 31 characters in size.
The filelist report used in this example contains one function named Hidden. The function returns true if the first character of the display-name column starts with an '@' sign. This is a legacy feature of DataFlex. If the first character is an '@' sign the entry should not be shown to the user in a tool named DFQUERY (and later FlexQL and dbExplorer). You can use this feature for alias tables to reduce the number of tables to pick from in a report of program. As said it is a legacy option and modern tools (like Visual Report Writer) do not 'honor' this special feature itself. The report however does; If the function returns true the font italics setting is set to true.
Keep in mind that RDS reports require a programmer if other or more data is needed for the report where the other data-sources make it possible to teach/instruct an end-user in how to make/extend their reports using a standard edition (or later this year the enterprise edition) version of Visual Report Writer.
Integration
RDS reports can only be used succesfully if integrated with an application as their data needs to be placed in an array and passed to the report. If you don't do this the engine can only print test-data, not very interesting.
RDS integration is quite simple; you need to create an array and fill this with data. The array however is a bit strange if you look at array definitions. It has to be a jagged array (the 2nd dimension specified in the array definition cannot be fixed) but the 2nd dimension does need to be fixed in values and it needs to match the row layout in the report. In the filelist report 4 columns are defined which means you need to setup an array with 4 values in the 2nd dimension. If you don't do that the data-row will be skipped and the report looks untrustfull. Luckily the last value is the logical-name which needs to be an unique value in the filelist and therefore will 'never' be empty.
The array contents needs to be passed to the report by using the TableData method.Code:Variant[][] vData
The '0' in above statement is the table number used in the report. This is very often just 0 as it is very common to have only one table in an RDS report. However it is allowed to have multiple RDS tables and therefor you can pass a table number.Code:Send TableData C_USEMAINVRWREPORTID 0 vData
Let's take a look at the user interface. The report view consists of a tool-bar with buttons to generate the report and show the documentation about this report and integration. Below that there is a drop-down (cWebCombo) that allows you to select the ordering of the data. You can choose between table-number, root-name, display-name and logical-name.
Each of them can be ascending or descending and the checkbox (cWebCheckbox class) determines this.Code:Object oSortByCombo is a cWebCombo Set psLabel to "Sort by:" Set peLabelAlign to alignRight Set piColumnSpan to 5 Procedure OnFill Send AddComboItem 1 'Table Number' Send AddComboItem 2 'Root Name' Send AddComboItem 3 'Display Name' Send AddComboItem 4 'Logical Name' End_Procedure End_Object
The last user choice is a checkbox labeled "include hidden (protected) tables". This applies to the '@' sign rule explained above. If the checkbox is not selected any filelist entry starting (logical-name attribute) with an '@' sign is skipped.Code:Object oDescendingCheckbox is a cWebCheckbox Set piColumnIndex to 6 Set piColumnSpan to 2 Set psCaption to "Descending" End_Object
Like the Sick Leave Report this report is generated as an HTML string and displayed in a special control made for Visual Report Writer. You need to use version 3.0 or higher to use this control and feature. The report viewer class is connected to the report object and sends the message GenerateReportHTML to get the array of pages. This is coded as:Code:Object oShowHiddenCheckbox is a cWebCheckbox Set piColumnSpan to 4 Set piColumnIndex to 1 Set psCaption to "Include Hidden (protected) Tables" End_Object
The filelist information is collected in the method LoadData. This is not a standard routine although the name is used too when generating the interface from the integration wizard. In the LoadData method code is written to get the next filelist entry until no more entries are available.Code:Function GenerateReportHTML Returns String[] String sReportId String[] sData Integer iArgSize Get OpenReport to sReportId If (sReportId <> "") Begin Send LoadData Send SetSortOrder Get_Argument_Size to iArgSize Get ComReportHTMLPreview sReportId (iArgSize - 10) to sData Send CloseReport sReportId End Function_Return sData End_Function
Finally the user requested sorting is passed to the Visual Report Writer engine in the method SetSortOrder.Code:Procedure LoadData Variant[][] vData Handle hTable Integer iRow Boolean bShowHidden String sDisplayName Get GetChecked of oShowHiddenCheckbox to bShowHidden Get_Attribute DF_FILE_NEXT_USED of hTable to hTable While (hTable <> 0) Get_Attribute DF_FILE_DISPLAY_NAME of hTable to sDisplayName If ((bShowHidden) or ((Left (sDisplayName, 1) <> '@') and (not (bShowHidden)))) Begin Move hTable to vData[iRow][0] Get_Attribute DF_FILE_ROOT_NAME of hTable to vData[iRow][1] Move sDisplayName to vData[iRow][2] Get_Attribute DF_FILE_LOGICAL_NAME of hTable to vData[iRow][3] Increment iRow End Get_Attribute DF_FILE_NEXT_USED of hTable to hTable Loop Send TableData C_USEMAINVRWREPORTID 0 vData End_Procedure
First all existing sort fields are removed from the definition read from disk. Then the iSortDirection is set to the chosen value for ascending or descending. Based on the drop-down value the sorting is done on table-number, root-name, display-name or logical-name.Code:Procedure SetSortOrder Integer iSortOrder iSortDirection Boolean bDescending Send RemoveAllRecordSortFields C_USEMAINVRWREPORTID WebGet psValue of oSortByCombo to iSortOrder Get GetChecked of oDescendingCheckbox to bDescending If (bDescending) Begin Move C_VRWDescending to iSortDirection End Else Begin Move C_VRWAscending to iSortDirection End Case Begin Case (iSortOrder = 1) Send AddRecordSortField C_USEMAINVRWREPORTID '{FileList.Number}' iSortDirection Case Break Case (iSortOrder = 2) Send AddRecordSortField C_USEMAINVRWREPORTID '{FileList.Rootname}' iSortDirection Case Break Case (iSortOrder = 3) Send AddRecordSortField C_USEMAINVRWREPORTID '{FileList.DisplayName}' iSortDirection Case Break Case (iSortOrder = 4) Send AddRecordSortField C_USEMAINVRWREPORTID '{FileList.LogicalName}' iSortDirection Case Break Case End End_Procedure
This concludes the ninth blog about Visual Report Writer and the Web using the 17.1 Web Framework by Data Access Worldwide. We hope this helps you in making the decision how to do reporting now and in the future.