The SAS Output Delivery System and reporting techniques

PROC REPORT COMPUTE AFTER _PAGE_ in ODS RTF destination

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 17
Accepted Solution

PROC REPORT COMPUTE AFTER _PAGE_ in ODS RTF destination

Good afternoon,

When I try the following code, I get two ODS output files. The PDF one will have the footer line of the table repeated on each page, while the RTF one will not:

ODS RTF STYLE=DEFAULT FILE="TEST.RTF";

ODS PDF STYLE=DEFAULT FILE="TEST.PDF" UNIFORM;

PROC REPORT DATA=SASHELP.DEMOGRAPHICS NOWD;

     COLUMNS REGION NAME POP;

     DEFINE REGION / GROUP;

     COMPUTE BEFORE _PAGE_;

        LINE "This is my table title";

     ENDCOMP;

     COMPUTE AFTER _PAGE_;

        LINE "This is my table footer";

     ENDCOMP;

RUN;

ODS _ALL_ CLOSE;

I know that the ODS PDF destination has an extra "UNIFORM" that does lead to the desired result (without it, the presence of the footer is unpredictable it seems! In this case, the footer appears on pages 5, 6 and 7 - out of 7 - of the PDF document if I remove the UNIFORM option). Is there any explanation for this behavior and is there any way to obtain the same result in the RTF file as in the PDF file?

Sincerely,


Daniel


Accepted Solutions
Solution
‎11-01-2011 03:17 PM
SAS Super FREQ
Posts: 8,861

Re: PROC REPORT COMPUTE AFTER _PAGE_ in ODS RTF destination

Hi:

  You are talking about the fundamental differences between a PDF file (in which every page is considered to be a separate table and UNIFORM makes sure that every page's table is treated the same way.) In RTF, on the other hand, the RTF specification says that a table can span multiple pages. It doesn't matter whether the table takes up 1 page or multiple pages. Of course if the table DID take up 1 page then you would see the behavior that you want. However, for a table that takes up multiple pages, the footer will appear on the last page. (COMPUTE BEFORE _PAGE_ works the way you want for RTF).

  In order to mimic what PDF does (treat every page as having a separate table) most folks make a "dummy" or "fake" page break variable and instead of doing COMPUTE AFTER _PAGE_, you would do a COMPUTE AFTER FAKEVAR; block that would put your footer. This does mean a bit of testing to be sure that you set the right number of obs for every group. See the code sample below.

cynthia


** make a "fakevar" for page breaking;
** may have to test the number used here;
** I picked 30 but probably could have used 31 or 32;
data demo_alt;
  set sashelp.demographics;
  fakevar = ceil(divide(_n_,30));
run;
           
ods listing;
proc print data=demo_alt;
var fakevar region name pop;
run;
          
options orientation=portrait;
ods listing close;
ODS RTF  FILE="c:\temp\TEST.RTF";
ODS PDF FILE="c:\temp\TEST.PDF" UNIFORM;
          
PROC REPORT DATA=demo_alt NOWD;
     COLUMNS fakevar REGION NAME POP;
     define fakevar / order noprint;
     DEFINE REGION / order;
     COMPUTE BEFORE _PAGE_;
        LINE "This is my table title";
     ENDCOMP;
     break after fakevar / page;
     COMPUTE AFTER fakevar;
        LINE "This is my table footer value of fakevar=" fakevar;
     ENDCOMP;
RUN;
      
ODS _ALL_ CLOSE;

View solution in original post


All Replies
Solution
‎11-01-2011 03:17 PM
SAS Super FREQ
Posts: 8,861

Re: PROC REPORT COMPUTE AFTER _PAGE_ in ODS RTF destination

Hi:

  You are talking about the fundamental differences between a PDF file (in which every page is considered to be a separate table and UNIFORM makes sure that every page's table is treated the same way.) In RTF, on the other hand, the RTF specification says that a table can span multiple pages. It doesn't matter whether the table takes up 1 page or multiple pages. Of course if the table DID take up 1 page then you would see the behavior that you want. However, for a table that takes up multiple pages, the footer will appear on the last page. (COMPUTE BEFORE _PAGE_ works the way you want for RTF).

  In order to mimic what PDF does (treat every page as having a separate table) most folks make a "dummy" or "fake" page break variable and instead of doing COMPUTE AFTER _PAGE_, you would do a COMPUTE AFTER FAKEVAR; block that would put your footer. This does mean a bit of testing to be sure that you set the right number of obs for every group. See the code sample below.

cynthia


** make a "fakevar" for page breaking;
** may have to test the number used here;
** I picked 30 but probably could have used 31 or 32;
data demo_alt;
  set sashelp.demographics;
  fakevar = ceil(divide(_n_,30));
run;
           
ods listing;
proc print data=demo_alt;
var fakevar region name pop;
run;
          
options orientation=portrait;
ods listing close;
ODS RTF  FILE="c:\temp\TEST.RTF";
ODS PDF FILE="c:\temp\TEST.PDF" UNIFORM;
          
PROC REPORT DATA=demo_alt NOWD;
     COLUMNS fakevar REGION NAME POP;
     define fakevar / order noprint;
     DEFINE REGION / order;
     COMPUTE BEFORE _PAGE_;
        LINE "This is my table title";
     ENDCOMP;
     break after fakevar / page;
     COMPUTE AFTER fakevar;
        LINE "This is my table footer value of fakevar=" fakevar;
     ENDCOMP;
RUN;
      
ODS _ALL_ CLOSE;

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 1 reply
  • 922 views
  • 1 like
  • 2 in conversation