![]() |
![]() |
|||||||
|
Login Change Info Logout
DOWNLOADS |
by Russell VanBlon
Problem: This article will explain how to prevent widowed group headers and footers from appearing in Crystal Reports. The knowledge base at http://support.crystaldecisions.com/ attempts to provide a solution for this problem in articles C2000972 and C2000973. However, these articles describe how to prevent widowed headers OR widowed footers, not both together, which is what is really needed in a report. Article C2005815 describes a method similar to what is described here by counting lines in a report, but again, it only applies to widowed headers. This article will show you how to modify any report to prevent widowed headers and widowed footers from being printed. What are Widowed Group Headers and Widowed Group Footers?Sometimes, when a report prints, new groups begin near the bottom of a page. This causes the group header to appear at the bottom of the page with no details. The details associated with that group header then print on the next page. This is known as a “widowed” group header or “orphaned” group header. Similarly, there could be just enough room on a page to print the details, causing the group footer to print at the top of the next page with no associated details. This is a “widowed” group footer. Crystal Reports has an option called ‘Keep Group Together’ that prevents headers and footers from printing in this manner. However, when groups are printed with more than a couple of lines of detail, a large amount of whitespace will appear since this option moves the entire group to the next page instead of moving only one detail line. The solution below will guide you through the process of modifying your report to print at least one detail line for every group header and footer. Prior Solution Attempts:The method used on Crystal’s knowledge base to solve this problem involved adding sections to the group header or footer and copying the details into these extra sections. They wrote two different articles, the first fixed widowed headers, and the other widowed footers. If you go through the steps in both articles so as to fix both problems at once, a problem arises which only occurs when you have a group with one line of detail at the bottom of a page. The articles also only apply to reports with a single group. So if you have multiple layered groups, you’re out of luck with their solution. In the Crystal Reports designer, there is an option called “Keep Group Together”. This option works great with only one problem. If you have large groups, they will often be pushed to the next page entirely, leaving large amounts of white space in the report. For those of us who need our reports to appear professional, this doesn’t cut it either. Solution:From here on, it is assumed that you have a basic familiarity with Crystal Reports designer. There are two reports you can download to aid you in fixing your own report. One is called Generic Report, the other is that same report which includes the fixes so that it has no widowed headers or footers. All the example reports and the database used by these reports can be downloaded from this link: crystalreports_widow.zip You should extract the contents of the zip file to the directory: c:\crystalreports_widow. The zip file contains these files:
In order to rid a report of widowed headers and footers, we need to know how many lines can fit on a page. To do that, you will need to take a few minutes to set up your report. First, make sure you have the “Snap To Grid” checkbox turned on in the File|Options dialog. You need to set the height of all sections in your report, and this is much easier with this option turned on. Notice that when you turn on this option, and you drag a vertical “tab” in the report designer up or down, the tab moves a uniform distance as you move it. This uniform distance between tab movements is one twelfth of an inch. The “tabs” referred to here are shown in the following screenshot, circled in red.
Now, to find out how many lines will fit on a page, all section heights have to be a constant size. This is where the tabs help us. Set each section of your report to a constant height using the tabs. Some guidelines to follow when doing this are:
In “Generic Report – Fixed – 3 Layers.rpt”, a predetermined height of 3 units was chosen for the detail section and report footer. The group headers and footers in this report were set to a height of 6 units. The three sections in this report that are not sized like this are the page header, page footer, and report header since it is hidden. The following movie clips give an example of how the sizing is done. There is a lot of emphasis on sizing your report sections here because it is very important that it is done right in your report for the next steps to work correctly. Observe in the movie clips that once the tabs are set to the correct height, the lower bar of each section is moved up as far as possible, which leaves only half of the tab viewable once it is in place. Once the sections of your report are sized like they should be, you need to know how many lines will fit on each page of your report. To do that, create a formula to count the lines: @CountLines+1 WhilePrintingRecords; NumberVar CountLines := CountLines + 1 If certain sections take up more space than another section you need to create a separate formula for that section. For example, if the Group Footer is twice the height of the Details section, create this formula: @CountLines+2 WhilePrintingRecords; NumberVar CountLines := CountLines + 2 Place the @CountLines+x formulas in each corresponding section of your report, depending on the section height you chose for each section when sizing them. Create another formula to reset the counter for each page: @ResetCountLines WhilePrintingRecords; NumberVar CountLines := 0 Place this counter in the Page Header section. This ensures that line counting returns to 0 at the beginning of each page. Make sure you don’t have the “Keep Group Together” (found under Report | Change Group Expert | Options) option turned on for any group. With these formulas in place, you should be able to preview your report and see line numbers. The last line number you see on your report is how many lines can fit on a page. Make a note of this number. The rest of the necessary formulas will now be discussed. Your report formulas will vary, depending on how many layered subgroups you have, the height of your groups, as well as the name of your database fields. Please note that the formulas about to be described are for reports that have 3 layered groups. Insert the following formula into the Page Header Section: @CounterConstants BeforeReadingRecords; NumberVar TotalLinesInReport := 37; NumberVar GH1Height := 2; NumberVar GH4Height := 2; NumberVar GH4Height := 2; NumberVar DetailHeight := 1; NumberVar GF3Height := 2; NumberVar GF2Height := 2; NumberVar GF1Height := 2; NumberVar ReportFooterHeight := 1; NumberVar LinesRequiredInGroup1ForSingleDetailLine := GH1Height + GH4Height + GH4Height + DetailHeight + GF3Height; NumberVar LinesRequiredInGroup1ForManyDetailLines := GH1Height + GH4Height + GH4Height + DetailHeight; NumberVar LinesRequiredInGroup2ForSingleDetailLine := GH4Height + GH4Height + DetailHeight + GF3Height; NumberVar LinesRequiredInGroup2ForManyDetailLines := GH4Height + GH4Height + DetailHeight; NumberVar LinesRequiredInGroup3ForSingleDetailLine := GH4Height + DetailHeight + GF3Height; NumberVar LinesRequiredInGroup3ForManyDetailLines := GH4Height + DetailHeight; NumberVar LinesRequiredInDetailsForLastDetail := DetailHeight + GF3Height; This formula contains constants used by other formulas in the report. For “Generic Report.rpt”, the total lines was found to be 37, seen above. This means that 37 lines, each with a height of 3 twelfths of an inch, can fit on each page. The height of sections in the report are set according to how they were sized. This height is 2 for the group headers and footers, and 1 for the detail section. Also notice that each group requires a different number of lines, depending on how many detail lines are left to print. This is because a group with a single detail line will require enough room on the page for the group header, detail, and footer which follows, where a group with more than one detail line only requires room for the group header and one line of detail. Also insert this formula into the Page Header Section. @CounterVariables BeforeReadingRecords; NumberVar TotalRecordsPrinted := 0; NumberVar Group1DetailsPrinted := 0; NumberVar Group2DetailsPrinted := 0; NumberVar Group3DetailsPrinted := 0; NumberVar LinesRequired := 0; These are counters used for each section of the report. The next formula also goes in the Page Header Section:
@InitReportLines
WhilePrintingRecords;
NumberVar ReportRecordsTotal := count
({SimpleData.CategoryC});
This formula counts the total number of lines in the report. It is only needed if you use the report footer section. Insert the following formula in Group Header #1:
@InitGroup1Lines
WhilePrintingRecords;
NumberVar Group1DetailsTotal :=
count({SimpleData.CategoryC},
{SimpleData.CategoryA});
Insert the following formula in Group Header #2:
@InitGroup2Lines
WhilePrintingRecords;
NumberVar Group2DetailsTotal :=
count({SimpleData.CategoryC},
{SimpleData.CategoryB});
Insert the following formula in Group Header #1, Group Header #2 and Group Header #3 (i.e. in ALL Group Header sections):
@InitGroup3Lines
WhilePrintingRecords;
NumberVar Group3DetailsTotal :=
Count({SimpleData.CategoryC},
{SimpleData.CategoryC});
1. On the Format menu, click 'Section'. This opens the Section Expert. 2. Under the 'Sections' list, click the Group Header #1 section. 3. Beside the 'New Page Before' check box, click 'X+2'. This opens the Conditional Formatting Formula Editor. Type this formula:
WhilePrintingRecords;
NumberVar LinesRequired := 0;
if (1 = (NumberVar Group3DetailsTotal -
NumberVar Group3DetailsPrinted))
then
( // If there is one detail left to print
LinesRequired := NumberVar
LinesRequiredInGroup1ForSingleDetailLine;
if (1 = (NumberVar Group2DetailsTotal -
NumberVar Group2DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF2Height;
if (1 = (NumberVar Group1DetailsTotal -
NumberVar Group1DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF1Height;
if (1 = (NumberVar ReportRecordsTotal -
NumberVar TotalRecordsPrinted))
then LinesRequired := LinesRequired +
NumberVar ReportFooterHeight
)
else ( // If there are multiple details left to print
LinesRequired :=
NumberVar LinesRequiredInGroup1ForManyDetailLines;
);
NumberVar CountLines >
(NumberVar TotalLinesInReport - LinesRequired)
1. On the Format menu, click 'Section'. This opens the Section Expert. 2. Under the 'Sections' list, click the Group Header #2 section. 3. Beside the 'New Page Before' check box, click 'X+2'. Type this formula:
WhilePrintingRecords;
NumberVar LinesRequired := 0;
if (1 = (NumberVar Group3DetailsTotal -
NumberVar Group3DetailsPrinted))
then (
LinesRequired := NumberVar
LinesRequiredInGroup2ForSingleDetailLine;
if (1 = (NumberVar Group2DetailsTotal -
NumberVar Group2DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF2Height;
if (1 = (NumberVar Group1DetailsTotal -
NumberVar Group1DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF1Height;
if (1 = (NumberVar ReportRecordsTotal -
NumberVar TotalRecordsPrinted))
then LinesRequired := LinesRequired +
NumberVar ReportFooterHeight
)
else (
LinesRequired := NumberVar
LinesRequiredInGroup2ForManyDetailLines;
);
NumberVar CountLines >
(NumberVar TotalLinesInReport - LinesRequired)
1. On the Format menu, click 'Section'. This opens the Section Expert. 2. Under the 'Sections' list, click the Group Header #3 section. 3. Beside the 'New Page Before' check box, click 'X+2'. Type this formula:
WhilePrintingRecords;
NumberVar LinesRequired := 0;
if (1 = (NumberVar Group3DetailsTotal -
NumberVar Group3DetailsPrinted))
then (
LinesRequired := NumberVar
LinesRequiredInGroup3ForSingleDetailLine;
if (1 = (NumberVar Group2DetailsTotal -
NumberVar Group2DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF2Height;
if (1 = (NumberVar Group1DetailsTotal -
NumberVar Group1DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF1Height;
if (1 = (NumberVar ReportRecordsTotal -
NumberVar TotalRecordsPrinted))
then LinesRequired := LinesRequired +
NumberVar ReportFooterHeight
)
else (
LinesRequired := NumberVar
LinesRequiredInGroup3ForManyDetailLines;
);
NumberVar CountLines >
(NumberVar TotalLinesInReport - LinesRequired)
1. On the Format menu, click 'Section'. This opens the Section Expert. 2. Under the 'Sections' list, click the Details section. 3. Beside the 'New Page Before' check box, click 'X+2'. Type this formula:
WhilePrintingRecords;
NumberVar LinesRequired := 0;
if (1 = (NumberVar Group3DetailsTotal -
NumberVar Group3DetailsPrinted))
then (
LinesRequired := NumberVar
LinesRequiredInDetailsForLastDetail;
if (1 = (NumberVar Group2DetailsTotal -
NumberVar Group2DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF2Height;
if (1 = (NumberVar Group1DetailsTotal -
NumberVar Group1DetailsPrinted))
then LinesRequired := LinesRequired +
NumberVar GF1Height;
if (1 = (NumberVar ReportRecordsTotal -
NumberVar TotalRecordsPrinted))
then LinesRequired := LinesRequired +
NumberVar ReportFooterHeight
);
NumberVar Group1DetailsPrinted :=
Group1DetailsPrinted + 1;
NumberVar Group2DetailsPrinted :=
Group2DetailsPrinted + 1;
NumberVar Group3DetailsPrinted :=
Group3DetailsPrinted + 1;
NumberVar TotalRecordsPrinted :=
TotalRecordsPrinted + 1;
if (NumberVar Group1DetailsPrinted =
NumberVar Group1DetailsTotal) then
Group1DetailsPrinted := 0;
if (NumberVar Group2DetailsPrinted =
NumberVar Group2DetailsTotal) then
Group2DetailsPrinted := 0;
if (NumberVar Group3DetailsPrinted =
NumberVar Group3DetailsTotal) then
Group3DetailsPrinted := 0;
NumberVar CountLines >
(NumberVar TotalLinesInReport - LinesRequired)
With these formulas in place, no conditions should occur that allow for widowed headers or footers to appear.
|
|
|
|||||||||||||||||||||||
|
Questions or Comments? devcentral AT iticentral DOT com PRIVACY POLICY |