BookmarkSubscribeRSS Feed
Calcite | Level 5
I'm working on a multi-page and multi-table/page report. With my macros and everything I've got it looping nicely and I've used ODS PDF text=" " to make titles for each of my proc outputs. I use the system title statement as the report title to repeat on every page.

The problem comes with the first proc report output on each page. The ods text title that goes with it puts the text before the systemtitle. Is there a way to get SAS to do the systemtitle THEN my ODS text?

My fall back is to simulate a system title with ODS text. Is that my best option?
SAS Employee
I'm very interested in your situation. Would it be possible for you to send me some code snippets and output? Please email me at

Calcite | Level 5
Can do. I'll post a snippet and send you the complete (macro-rific) code via email. I have your address.

The code below gives me :
BHCS and Facility Rates
this is the systemtitle
[proc report]... etc.

this is the code that calls other macros.

ods pdf file="c:\temp\&filename. unit detail report.pdf" style=ndnqi
pdftoc=1 bookmarklist=show startpage=no contents=no;

title1 c=red "this is the systemtitle";

footnote1 "
^{style ^{unicode 2588}^{unicode 2588}^{unicode 2588}} = Below or at 25th Percentile^{nbspace 8}
^{style ^{unicode 2588}^{unicode 2588}^{unicode 2588}} = 26th-50th Percentile^{nbspace 8}
^{style ^{unicode 2588}^{unicode 2588}^{unicode 2588}} = 51st-75th Percentile^{nbspace 8}
[no fill] = Above 75th Percentile"
footnote2 j=l h=10pt c=gray "Facility values are the median of all the units which make up that unit type. BHCS is average of facility values.";
footnote3 j=l c=gray h=10pt 'Benchmarks are from the NDNQI "All Hospital" Report, 2009 Q1'
j=r h=8pt "Prepared %sysfunc(today(),mmddyy8.) Baylor IHCRI";

%make_detail_table(measure=totalfall_rate, label=Falls per 1000 Patient Days, my_fmt=monyy5., meas_fmt=8.2);
ods pdf startpage=now;

%make_detail_table(measure=injfall_rate, label=Injury Falls per 1000 Patient Days, my_fmt=monyy5., meas_fmt=8.2);

ods pdf close;


Here is the start of the macro "make_detail_table"

%macro make_detail_table(measure=, label=, my_fmt=, meas_fmt=);
%let numtype=Percentages;
%if "&measure."="totalfall_rate" or "&measure."="injfall_rate" %then %let numtype=Rates;


* ods label and text for page and table titles;
ods proclabel "System/Facility &label.";
%if "&unittype."="n/a" %then %do;
ods pdf text="^{style [fontsize=14pt color=cx0077D4 fontweight=bold] Non-NDNQI Units - &label.} ";
%else %do;
ods pdf text="^{style [fontsize=14pt color=cx0077D4 fontweight=bold] &unittype. Units - &label.} ^n";
ods pdf text="^2n^{style [outputwidth=100% just=c fontsize=12pt color=black] BHCS and Facility &numtype.} ^2n";

* make system/facility table;
proc report data=use_for_detail nowd
style(report)=[font_size=8pt rules=all bordercolor=darkgray cellpadding=2pt ]
where &measure.^=. and unit_name=" " and unit_type="&unittype.";
columns order_fac facility month_year,( &measure. &measure._qtile );

/* end snippet of macro */
Calcite | Level 5
For anyone searching in the future... Here is the answer that ScottH came up with. Works. Just need to put a "startpage=now" in before the "ODS text=".

"We allow people to put text before titles on page 1 because we process
that before we see the table coming down the pipe. It’s a timing issue.

Put an "ods pdf startpage=now;"
before the first call to "%make_detail_table"

For example…using your code.."

ods pdf startpage=now; (this is the new line I want you to add)
%make_detail_table(measure=totalfall_rate, label=Falls per 1000 Patient Days, my_fmt=monyy5., meas_fmt=8.2);
ods pdf startpage=now;

%make_detail_table(measure=injfall_rate, label=Injury Falls per 1000 Patient Days, my_fmt=monyy5., meas_fmt=8.2);
ods pdf startpage=now;
Calcite | Level 5
I have a different problem that comes from the same need to use the ods pdf text option as a title. I tried several different solutions, and the whole macroific method JenHarper used is the closest to meeting all my needs except for one problem.

My output produces several tables on each page with a pdf text= to create the titles. Sometimes, one of the tables may not have any results and should not be present. Using titles=, the title only prints with the corresponding output. However, as I am using pdf text=, the text is there regardless of the output leaving my final output with titles for different tables and only one table.

Aside from a "If blank, then no data to report'" is there an easy way suppress pdf text= if the following table is blank?
You have discovered one of the differences between TEXT= and a SAS Title statement. Since the ODS <destination> TEXT= is independent of what follows, there is no automatic option to do what you want.

However, there have been many previous forum postings on how to use the SAS Macro Facility to test whether a table was successfully created (if the number of OBS is 0 or if the table does not exist). You can extend this type of Macro program to conditionally issue your ODS TEXT= statement using %IF logic.

Calcite | Level 5
Thanks Cynthia.

The %if option is what I just started trying and it is working; albiet a bit more code than I wanted to add for each table.
Ah, well, that's why I love modular design. With the Macro facility, you do not have to repeat the code over and over. You could have 1 little macro to test the number of obs or existence of a table and then you could just call that macro over and over again. Then, you could follow that macro call with another macro call that only issued the ODS PDF TEXT statements. I'd probably keep the strings for text= in another set of macro variables that could be conditionally used based on the table name or something like that.

Fluorite | Level 6
For a couple of PDF reports, I used ODS PDF TEXT= to generate all of the titles via a macro routine. Just run it immediately after a new page. That way I could change them or insert subtitles at any time.
Super User
You don't mention which procedures you are using to create the tables. One solution if using PRINT, REPORT or TABULATE might be using the PRETEXT= style option. This places text before the table but after titles. If the table isn't generated then the PRETEXT isn't either.

I use this in TABULATE to provide "titles" to individual tables when generating multiple tables with a single call to the procedure.


Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.


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
  • 9 replies
  • 6 in conversation