=====================================================================
Keeping Groups Together on a Page
=====================================================================
PRODUCT: R:BASE VERSION:3.X,4.0,4.5
=====================================================================
AREA: Reports CATALOG: FORMS, REPORTS & LABELS
=====================================================================
Breakpoints in reports are used for categorizing, showing totals, and
generally, providing a clearer organization of database information.
Breakpoints have headers, footers and detail sections. Sometimes, the
break header will print at the bottom of page 2 and the break detail
information and the footer on page 3. Or the header and detail will
print on page 2 and the footer on page 3.
R:BASE reports consider the header, detail and footer sections of a
breakpoint to be separate. The report writer is designed to not split
a section across pages, but since each part of a breakpoint is
considered a separate section it won't automatically keep all three
parts of a breakpoint together on a page. Break header and footer
sections are a fixed size (number of lines), but the detail section
expands based on the amount of data (number of rows) to be printed.
Because the detail section can vary in size, all parts of a breakpoint
may not print on the same page.
The techniques described below will keep the header and footer and all
corresponding detail rows on the same page. If the three groups won't
fit on what's left of the page, a form feed is done. If you have lots
of detail lines, you may not be able to keep the header and footer
from splitting across pages.
One group per page
To have only one group or breakpoint print on each page of your report
simply specify a form feed before break header for the breakpoint on
the Create breakpoints screen off the Layout menu in Reports
Create/modify. However, you may have a situation with several small
breakpoints printing on one page, and you don't want any part of a
breakpoint split over two pages.
Fixed number of groups per page -- No detail section
If you have only break header and footer lines, no detail lines, you
can keep them together on a page by specifying a calculated number of
lines per page (under the Page settings screen off the Layout menu in
Reports Create/modify). To determine the number of lines per page for
break information, make the following calculations:
1. Total the number of marked lines for page header and footer
(PH, PF)
2. Subtract this total from the Liner per page setting
The result tells you how many lines per page you have for the break
information. To determine how many break groups you can fit in that
number of lines, perform these calculations:
3. Total the marked lines for the break header adn footer (H1, F1)
2. Divide the previous calculation (#2) by this total of marked break
lines
The result of calculation #4 is how many groups you can fit on a page.
Make sure this number comes out even, you don't want any remainder.
For example, there are 5PH lines and 1 PF line for a total of 6 lines
that will print every page. Subtract this number from 60, the default
Lines per page; 60 - 6 = 54. There are 54 lines available on each page
for printing break groups. If there are 3 H1 lines and 1 F1 line
defined, 13 groups will fit in 54 lines ( 54/4 = 13), but there are an
extra 2 lines per page left over. Subtract these leftover lines from
the default Lines per page setting, change it from 60 to 58. Then the
right number of groups will always print on a page and no group will
be split between pages. This technique uses R:BASE's automatic form
feed at the end of a page.
If you are printing a detail section as well as break header and
footer sections, use one of the following techniques to keep all of a
groups' information on the same page. Because the size of the detail
section can vary, you can't just calculate the page size.
Fixed number of groups per page -- With detail section
If your breakpoints are of relatively similar size, meaning that they
each take about the same number of lines per page, print a fixed
number of breaks or groups per page. Using the Concomp database as an
example, the transactions recorded in the Transdetail table have one
or two detail lines each. Build a report on the Transdetail table that
prints 6 groups per page and then form feeds. The breakpoint column
will be the transid column. Here are the steps:
First define the variables. There are five required.
1) vcnt INTEGER = (.vcnt + 1)
2) vbdetot = (COUNT(transid)) IN transdetail WHERE transid = transid
3) vbrkcnt INTEGER = (IFEQ(.vcnt, 1, .vbrkcnt + 1, .vbrkcnt))
4) vbreak INTEGER = (IFEQ(.vcnt, .vbdetot, IFEQ(.vbrkcnt, 6, (.vbreak
+ 1), .vbreak), .vbreak))
5) vpbreak INTEGER = .vbreak
Next, reorder the variables to place vpbreak first in the variable
list. It can't be defined until vbreak is defined, but for this
technique to work it needs to execute first.
The variable, vcnt, counts the rows in the table as the report prints
them. Reset it at the transid breakpoint. Vbdetot counts the total
number of rows that are in the group, it "looks up" the count. The
variable vbrkcnt counts of the number of breaks that have printed.
Reset vbrkcnt at the page.
The variable vbreak does most of the work. It decides when you have
printed the specified number of groups on a page, and then increments
itself. It works by comparing the number of rows the report has
counted (in the vcnt variable) with the number of rows the report
looked up (in the vbdetot variable). When these two values equal each
other, the report has reached the last row within a group. Then, the
report checks to see if the number of groups or breakpoints has
reached the number specified to print on a page. If yes, the variable
vbreak increments and breaks, causing a form feed. The variable
vpbreak makes sure the last row of the last break prints on the
correct page.
Since all expressions are processed in order starting with expression
one, vpbreak contains the value of vbreak from the previous row. It is
needed because vbreak is evaluated on the last row of data before the
data has printed. If the breakpoint was set up on vbreak, the last row
of the last break or group of the page would print on the top of the
next page. This is just what the report is designed to avoid.
After defining the variables, set up the rest of the report. Make
vpbreak the first breakpoint of the report and choose to reset the
variable vbrkcnt. In addition, answer Yes to Form feed before break
header for the vbpreak breakpoint. Define transid as the second
breakpoint. Reset the variable, vcnt, at this break.
The report must have a header line, H1, marked for vpbreak. This line
will act like part of the page header, it will only print once at the
beginning of each page. You can put page header information on it, or
it can be left blank. There is no need for an F1 line.
For the transid break, set up the header (H2), detail (D) and footer
(F2) sections as you like. Define other variables for transaction
totals or detail amounts, put in text for headings and footer
information and place your fields locations just as you would in any
other report.
ZERO must be set ON for the report variables to initialize and
evaluate properly. Also, since the variable vpbreak references a
variable below it in the variable list, the referenced variable,
vbreak, must be initialized prior to printing the report. Do this at
an R> prompt with the command SET VAR vbreak INTEGER, or in an
application, insert a Custom action before the Print action. The
custom code entered is SET VAR vbreak INTEGER.
The report prints as many breaks as you specified per page! To change
the number of breaks printed per page, just change the number
specified in the vbreak variable (in this example, the number is 6).
Varied number of groups per page -- With detail section
Another way to keep break groups that include detail together on a
page is to look at the number of lines left on the page and compare
that with the number needed for the group. This is similar to the
method you can use when you aren't printing a detail section. Use a
copy of the previous example's report to see how to set up this
report. Most of the work is done with variables. In fact, most of the
variables are the same. However, you need an extra variable and the
expression changes slightly on two others.
1) vcnt INTEGER = (.vcnt + 1)
2) vbdetot = (COUNT(transid)) IN transdetail WHERE transid = transid
3) vbrkcnt INTEGER = (IFEQ(.vcnt,1,.vbrkcnt + 1,.vbrkcnt))
4) vbrkpgsiz INTEGER = (IFEQ(.vcnt,1, (IFGT(.vbrkcnt,1,(.vbrkpgsiz +
.vbdetot + 2), (.vbrkpgsiz + .vbdetot + 6))), .vbrkpgsiz))
5) vbreak INTEGER = (IFEQ(.vcnt,.vbdetot,(IFEQ(.vbrkpgsiz,50,(.vbreak
+ 1), (IFGT(.vbrkpgsiz,50,(.vbreak+1),.vbreak)))),.vbreak))
6) vpbreak = .vbreak
Next, reorder the variables to place vpbreak first in the variable
list. It can't be defined until vbreak is defined, but for this
technique to work it needs to execute first.
The variable, vcnt, counts the rows in the table as the report prints
them. Reset it at the transid breakpoint. Vbdetot counts the total
number of rows that are in the group, it "looks up" the count. The
variable vbrkcnt counts of the number of breaks that have printed.
Reset vbrkcnt at the page.
The variable vbrkpgsiz keeps track of how many lines have printed on
the page. Before you define vbrkpgsiz, make the following two
calculations. The expression contains these two calculated numbers.
1. Total the number of lines marked for the page header (PH) and page
footer (PF sections and the number of header (H1) and footer (F1)
lines marked for break 1, vpbreak (the number is 6 in the example.).
2. total the number of lines marked for the break header (H2) and
footer (F2) for the transid breakpoint (the number is 2 in this
example.).
Vbrkpgsiz evaluates as follows:
"(IFEQ(.vcnt,1," . - check the vcnt variable. If vcnt is 1, the
report is at the start of a new break group and the nested ifgt
function is evaluated.
If vcnt is not 1, the value of vbrkpgsiz doesn't change.
"IFGT(.vbrkcnt,1,". If vbrkcnt is 1 (the report is at the top of a new
page), then vbrkpgsiz increments itself with the calculated number of
lines in the page header/footer sections (calculation #1 above) and the
number of detail lines (stored in the vbdetot variable) for the first
breakpoint on the page -- ".vbrkpgsiz + .vbdetot + 6".
If vbrkcnt is greater than 1, then the report is on a break in the
middle of a page and vbrkpgsiz needs to be incremented with the number
of lines marked as headers and footers for the transid break and the
number of detail lines (vbdetot) -- ".vbrkpgsiz + .vbdetot + 2".
This appears confusing, but what is basicall means is: add the page
header lines at the top of the page; add the break header and detail
lines at the start of each break of stay the same.
The variable vbreak does almost as much work as vbrkpgsiz. It decides
when the specified number of lines have been printed on a page, and
then it increments itself. Vbreak evaluates as follows.
"(IFEQ(vccnt,.vdbetot"- compares the number of rows the report
has counted (in the vcnt variable) with the number of rows the looked
up (in the vbdetot variable)
When these two variables equal each other, the last row within a group
has been reached and the nested function is evaluated.
"( IFEQ(.vbrkpgsiz,50,(.vbreak + 1)
IFGT(.vbrkpgsiz,50,(.vbreak + 1)"
checks to see if the numver of lines printed (vbrkpgsiz) has reached
the number of specified to print on a page (50). If vbrkpgsiz is
greater than or equal to 50, vbreak is incremented.
The variable vpbreak makes sure the last row of the last break prints
on the correct page.
Since all expressions are processed in order starting with expression
one, vpbreak contains the value of vbreak from the previous row. It is
needed because vbreak is evaluated on the last row of data before the
data has printed. If the breakpoint was set up on vbreak, the last row
of the last break or group of the page would print on the top of the
next page. This is just what the report is designed to avoid.
After defining the variables, set up the rest of the report. Make
vpbreak the first breakpoint of the report and choose to reset the
variable vbrkcnt. In addition, answer Yes to Form feed before break
header for the vbpreak breakpoint. Define transid as the second
breakpoint. Reset the variable, vcnt, at this break.
The report must have a header line, H1, marked for vpbreak. This line
will act like part of the page header, it will only print once at the
beginning of each page. You can put page header information on it, or
it can be left blank. There is no need for an F1 line.
For the transid break, set up the header (H2), detail (D) and footer
(F2) sections as you like. Define other variables for transaction
totals or detail amounts, put in text for headings and footer
information and place your fields locations just as you would in any
other report.
ZERO must be set ON for the report variables to initialize and
evaluate properly. Also, since the variable vpbreak references a
variable below it in the variable list, the referenced variable,
vbreak, must be initialized prior to printing the report. Do this at
an R> prompt with the command SET VAR vbreak INTEGER, or in an
application, insert a Custom action before the Print action. The
custom code entered is SET VAR vbreak INTEGER.
You now have two new ways to produce reports that can group your data
neatly on a page and provide valuable information in a well organized
and clearly formatted style.
PH
PH Transaction Report
PH Page: 1
H1
H2 Transid: _______
D Model: _______ Units: _______ Price: __________
F2 Total Price: __________________
PF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -