Dense Data or No Data
By default WebFOCUS only displays data that exists within the returned dataset. However, there are occasions when the end user requires that the end report shows all possible data values within a grouping, irrespective of whether they exist – i.e., show dense data rather than no data.
This article will discuss how to produce such a report and work through the requirements to the ultimate solution.
Requirement: Produce a report grouping Car Models within Country and Bodytype.
- All countries must be included.
- All bodytypes must be shown for each country whether they exist or not.
Of course, WebFOCUS can handle this easily by forcing ROWS within a BY phrase or COLUMNS within an ACROSS phrase. The code that is required to produce this could be:
SET NODATA=NONE
TABLE FILE CAR
SUM CAR
BY COUNTRY
BY BODYTYPE
ROWS 'CONVERTIBLE' OVER 'HARDTOP' OVER 'SEDAN' OVER 'ROADSTER'
BY CAR NOPRINT
END
(Thanks to Francis Mariani.)
However, even though this provides the required end result, it is rather restrictive and a possible maintenance overhead.
Take the situation when a new value is entered into the data for a bodytype of 'CABRIOLET' or the fact that 'COUPE' is missing from the forced list even though it already exists within the data. Each of these situations will require that the code is changed, together with any change-control requests that might be necessary!
It would be more productive if the code was written to cope with expanding data values, thereby "future-proofing" the code. All that would be required is to extract the data values and use them to build the 'ROWS' syntax dynamically.
By using Dialogue Manager within WebFOCUS, this becomes an easy process.
First we require all the current values:
TABLE FILE CAR BY BODYTYPE ON TABLE SAVE AS BODYTYPES FORMAT ALPHA END -RUN
We use SAVE instead of HOLD, as we do not require the master file description to be generated.
Next, we read all the values and construct our 'ROWS' syntax. Remember basic file-handling techniques using read ahead.
-SET &Rows = 'ROWS ';-READ BODYTYPES, NOCLOSE &Bodytype-REPEAT Read_It WHILE (&IORETURN EQ 0);-SET &Rows = &Rows | '''&Bodytype.EVAL''';-READ BODYTYPES, NOCLOSE &Bodytype-SET &Rows = IF &IORETURN EQ 0 THEN &Rows | ' OVER ' ELSE &Rows;-Read_It-RUN
An explanation of the process follows:
- Initialize a variable,
&Rows, that we will use to construct ourROWstatement. - Read the saved file in a read ahead operation to prime the
BodytypeandIORETURN(system) variables. - Initiate the read loop and make it dependant upon a successful read operation (
&IORETURN EQ 0). - Build the
&Rowvariable with each successiveBodytypevariable value. - Reread the saved values for the next value in our list.
- The important piece here is that is we have a successful read. Then we have a further value to add and, therefore, we will require the "
AND" syntax joiner. If&IORETURNdoesn't equal 0, then we have reached the end of the saved values and we do not require the "AND" syntax. - This line marks the end of the loop sequence.
Items to note about this Dialogue Manager code:
The value for the system variable, &IORETURN, will remain at zero while a read has been successful. |
|
The comma after the filename (BODYTYPES) negates the need to specify variable length or predeclaring a variable value. |
|
The NOCLOSE option keeps the status of the file open and read pointers intact between read operations. |
All that is needed now is to plug our newly formed variable into our report code:
SET NODATA=NONE TABLE FILE CAR SUM CAR BY COUNTRY BY BODYTYPE &Rows BY CAR NOPRINT END
To produce the final report:
PAGE 1 |
||
Country of Origin |
Manufacturer |
|
ENGLAND |
CONVERTIBLE |
JAGUAR |
COUPE |
NONE |
|
HARDTOP |
TRIUMPH |
|
ROADSTER |
NONE |
|
SEDAN |
JAGUAR |
|
SEDAN |
JENSEN |
|
FRANCE |
CONVERTIBLE |
NONE |
COUPE |
NONE |
|
HARDTOP |
NONE |
|
ROADSTER |
NONE |
|
SEDAN |
PEUGEOT |
|
ITALY |
CONVERTIBLE |
NONE |
COUPE |
ALFA ROMEO |
|
COUPE |
MASERATI |
|
HARDTOP |
NONE |
|
ROADSTER |
ALFA ROMEO |
|
SEDAN |
ALFA ROMEO |
|
JAPAN |
CONVERTIBLE |
NONE |
COUPE |
NONE |
|
HARDTOP |
NONE |
|
ROADSTER |
NONE |
|
SEDAN |
DATSUN |
|
SEDAN |
TOYOTA |
|
W GERMANY |
CONVERTIBLE |
NONE |
COUPE |
NONE |
|
HARDTOP |
NONE |
|
ROADSTER |
NONE |
|
SEDAN |
AUDI |
|
SEDAN |
BMW |
|
You can see the method of building the &Rows variable by viewing the 'ECHO'ed source:
TABLE FILE CAR
BY BODYTYPE
ON TABLE SAVE AS BODYTYPES FORMAT ALPHA
END
-RUN
0 NUMBER OF RECORDS IN TABLE= 18 LINES= 5
ALPHANUMERIC RECORD NAMED BODYTYPE
0 FIELDNAME ALIAS FORMAT LENGTH
BODYTYPE TYPE A12 12
BODYTYPE TYPE A12 12
TOTAL 24
-SET &Rows = 'ROWS ';
-READ BODYTYPES, NOCLOSE &Bodytype
- &Read_It= ( 0 EQ 0);
-SET &Rows = ROWS | '''' || CONVERTIBLE || '''';
-READ BODYTYPES, NOCLOSE &Bodytype
-SET &Rows = IF 0 EQ 0 THEN ROWS 'CONVERTIBLE' | ' OVER ' ELSE ROWS
'CONVERTIBLE';
- &Read_It= ( 0 EQ 0);
-SET &Rows = ROWS 'CONVERTIBLE' OVER | '''' || COUPE || '''';
-READ BODYTYPES, NOCLOSE &Bodytype
-SET &Rows = IF 0 EQ 0 THEN ROWS 'CONVERTIBLE' OVER 'COUPE' | ' OVER '
ELSE ROWS 'CONVERTIBLE' OVER 'COUPE';
- &Read_It= ( 0 EQ 0);
-SET &Rows = ROWS 'CONVERTIBLE' OVER 'COUPE' OVER | '''' || HARDTOP || '''';
-READ BODYTYPES, NOCLOSE &Bodytype
-SET &Rows = IF 0 EQ 0 THEN ROWS 'CONVERTIBLE' OVER 'COUPE' OVER
'HARDTOP' | ' OVER ' ELSE ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP';
- &Read_It= ( 0 EQ 0);
-SET &Rows = ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP' OVER | '''' ||
ROADSTER || '''';
-READ BODYTYPES, NOCLOSE &Bodytype
-SET &Rows = IF 0 EQ 0 THEN ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP'
OVER 'ROADSTER' | ' OVER ' ELSE ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP'
OVER 'ROADSTER';
- &Read_It= ( 0 EQ 0);
-SET &Rows = ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP' OVER 'ROADSTER' OVER
| '''' || SEDAN || '''';
-READ BODYTYPES, NOCLOSE &Bodytype
-SET &Rows = IF 1 EQ 0 THEN ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP'
OVER 'ROADSTER' OVER 'SEDAN' | ' OVER ' ELSE ROWS 'CONVERTIBLE' OVER 'COUPE'
OVER 'HARDTOP' OVER 'ROADSTER' OVER 'SEDAN';
- &Read_It= ( 1 EQ 0);
-Read_It
-RUN
TABLE FILE CAR
SUM CAR
BY COUNTRY
BY BODYTYPE
ROWS 'CONVERTIBLE' OVER 'COUPE' OVER 'HARDTOP' OVER 'ROADSTER' OVER 'SEDAN'
BY CAR NOPRINT
END
-EXIT
0 NUMBER OF RECORDS IN TABLE= 18 LINES= 13
Anthony has been working as a contractor in the UK market for 12 years but has been developing in WebFOCUS (formerly FOCUS) for 20 years. He has supplied services to the London office of Information Builders in both the technical support and professional services departments.