BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Daniel
Obsidian | Level 7

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

1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
SAS Super FREQ

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

1 REPLY 1
Cynthia_sas
SAS Super FREQ

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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 1 reply
  • 5075 views
  • 2 likes
  • 2 in conversation