Focal Point
[SHARING] - Calculate space remaining on a page for PDF

This topic can be found at:
https://forums.informationbuilders.com/eve/forums/a/tpc/f/7971057331/m/6717020196

January 06, 2019, 08:10 PM
MAK
[SHARING] - Calculate space remaining on a page for PDF
Good Morning and Happy New Year to you all.

I am again trying to repay all you good folks on this forum who provide a lot of innovative solutions for what seem like insurmountable problems with WebFOCUS.

So I thought I would share a solution to an issue I encountered.

The issue is.

We have a number of student reports that are combined based on certain parameters into a Compound PDF. The reports have a number of lines in the header that contain fields followed by data extracted from the database.
These are then repeated through the report.

The requirement was for WebFOCUS to determine whether multiple reports or sections could fit on a single page. If not then a new page needed to be started, without overflowing.

This would have been straight forward if we had the ability to use NOSPLIT in the PDF however this function is not incorporated for Compound PDF's.

Working closely with Karen Piippo from APAC support (Many thanks to Karen as I could not have done this without her) we came up with a solution using MacGyver. It is this solution I wish to share.
So whilst it uses the CAR file it should reproducible to fit any scenario that requires this type of behavior.

To see the different behavior of the code you can change the number '40' to '10' in the section

COMPUTE LINES_REMAINING/I5 = 40 - TOT_LINES_SECT;

(This should appear on line 39).

Hope this helps someone in the future.

*** My apologies for the size of the paste ****

-SET &ECHO=ALL;
SET PRINTPLUS=ON
APP PREPENDPATH IBISAMP
-*------------------------------------------------------
-* This section is the MacGyver Master File but is being
-* used as the Data File
-*------------------------------------------------------
FILEDEF FOCMCGYV DISK c:\ibi\apps\ibisamp\focmcgyv.mas
-RUN
-*------------------------------------------------------


JOIN BLANK WITH COUNTRY IN CAR TO BLANK IN FOCMCGYV AS J1
DEFINE FILE CAR
BLANK/A1 WITH COUNTRY=' ';
LINES_SECT_SUM/I5 = 1;
-*--------------------------------------------------------
-* LINES_SECT_SUM establishes a counter
-*--------------------------------------------------------
END


TABLE FILE CAR
PRINT

COMPUTE LINES_SECT/I5 = IF COUNTER EQ LAST COUNTER THEN (LINES_SECT + 1) ELSE 1;
-*-------------------------------------------------------------------------------
-* Accounts for static number of lines per section for the heading. Needs to be
-* adjusted to fit your number of lines in each heading.
-*-------------------------------------------------------------------------------
COMPUTE TOT_LINES_SECT/I5 = IF COUNTER EQ 1
THEN (19 + LINES_SECT)
ELSE IF COUNTER EQ 2 THEN (7 + LINES_SECT)
ELSE IF COUNTER EQ 3 THEN (17 + LINES_SECT)
ELSE (12 + LINES_SECT);
-*-------------------------------------------------------------------------------
-* Total Number of lines per page example '40 lines per page'
-*--------------------------------------------------------------------------------
COMPUTE LINES_REMAINING/I5 = 40 - TOT_LINES_SECT;

BY BLANK
BY COUNTER
BY HIGHEST 1 LINES_SECT
-*-------------------------------------------------------------------------------
-* 4 assumes the number of sections in the report. Also needs to be adjusted to
-* meet your report requirements
-*-------------------------------------------------------------------------------
WHERE COUNTER LE 4;
-*-------------------------------------------------------------------------------
-* IMPORTANT - This is based on the car file. Additional work will be required for
-* the detailed section of each report. This will depend on how you are extracting
-* the data and from where.
-*---------------------------------------------------------------------------------
ON TABLE HOLD AS HOLD1
END
-RUN
-*------------------------------------------------------------------------------------
-* This section handles the page breaks and acts as the function NOSPLIT
-*-----------------------------------------------------------------------------------
TABLE FILE HOLD1
PRINT
COMPUTE NEW_PAGE/A1 = IF TOT_LINES_SECT LT LAST LINES_REMAINING
THEN 'N'
ELSE 'Y';
TOT_LINES_SECT
LINES_REMAINING


COMPUTE PAGE_NO/I5 = IF COUNTER EQ 1 THEN 1 ELSE IF NEW_PAGE EQ 'Y' THEN LAST PAGE_NO + 1
ELSE LAST PAGE_NO;
BY BLANK
BY COUNTER
BY HIGHEST LINES_SECT
ON TABLE SET HOLDLIST PRINTONLY
ON TABLE HOLD AS HOLD2

END
-RUN

JOIN CLEAR *
JOIN BLANK WITH COUNTRY IN CAR TO ALL BLANK IN HOLD2 AS J10
DEFINE FILE CAR
BLANK/A1 WITH COUNTRY=' ';
END

TABLE FILE CAR
PRINT
COMPUTE TEXT/A20='This is some text'; AS ''
BY PAGE_NO PAGE-BREAK NOPRINT
BY COUNTER NOPRINT
BY COUNTRY AS ''
-*-------------------------------------------------------------------------------------------
-* This section shows how the counter is used based on the number of rows in the heading
-*-------------------------------------------------------------------------------------------
ON COUNTER SUBHEAD
" "
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"Compound report 1"
"-----------------"

WHEN COUNTER EQ 1

ON COUNTER SUBHEAD
" "
"Compound report 2"
"Compound report 2"
"Compound report 2"
"Compound report 2"
"Compound report 2"
"-----------------"

WHEN COUNTER EQ 2

ON COUNTER SUBHEAD
" "
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"Compound report 3"
"-----------------"

WHEN COUNTER EQ 3

ON COUNTER SUBHEAD
" "
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"Compound report 4"
"-----------------"

WHEN COUNTER EQ 4

ON TABLE SET PAGE-NUM NOLEAD
ON TABLE SET ASNAMES ON
ON TABLE NOTOTAL
ON TABLE PCHOLD FORMAT PDF
HEADING
"Page
<TABPAGENO"

ON TABLE SET STYLE *
INCLUDE = warm,
$
ENDSTYLE
END

This message has been edited. Last edited by: MAK,


WebFOCUS 8203M
O/S Windows 7
January 08, 2019, 10:20 AM
FP Mod Chuck
Hi MAK

Thank you for sharing this! Good One


Thank you for using Focal Point!

Chuck Wolff - Focal Point Moderator
WebFOCUS 7x and 8x, Windows, Linux All output Formats
January 09, 2019, 09:15 AM
Wep5622
Interesting approach. Thanks for sharing.

One suggestion: Instead of writing:
FILEDEF FOCMCGYV DISK c:\ibi\apps\ibisamp\focmcgyv.mas

Use:
FILEDEF FOCMCGYV DISK ibisamp/focmcgyv.mas


That makes the example more portable. In our case, for example, or WebFOCUS installation was done on D:.

Also, is focmcgyv.mas a file that gets installed by default on systems these days? We don't have it (8.1.03).
We do have a little fex copied (and improved upon) from these forums quite a while ago that creates a McGyver file on the fly, though, so adapting your example was easy enough.

I think what we're really missing in WF is a set of functions to calculate the width, height and the cut-off points of a line and a page given an area width and height respectively, based on given font metrics (face, size, variant).
I'm sure there are some libraries in existence that (FreeType, Windows API, etc.), in combination with some C, could help us create user-defined functions for this... We'd still be guessing at how much extra space WF adds around the text though. Built-in functions would be best.


WebFOCUS 8.1.03, Windows 7-64/2008-64, IBM DB2/400, Oracle 11g & RDB, MS SQL-Server 2005, SAP, PostgreSQL 11, Output: HTML, PDF, Excel 2010
: Member of User Group Benelux :
January 09, 2019, 10:50 AM
DWaybright
Thanks for sharing.

It seems a rather complex way to get to what you need. Compound reports can be complicated on their own without adding all the MacGyver stuff.

I agree with Wep5622 -- we really need a set of built-in functions to give us cut-off points for line and page. Or maybe make the NOSPLIT option work for compound reports.


WebFOCUS 8.2.03 (production), 8.2.06 (testing)
AppStudio, InfoAssist
Windows, All Outputs