The SAS Output Delivery System and reporting techniques

Automatic generation of table titles in long PDF reports

Reply
New Contributor
Posts: 3

Automatic generation of table titles in long PDF reports

[ Edited ]

Dear Community,

 

I'm looking for a way to automatically generate table headers throughout long pdf reports.

 

Now, I'm writing the titles manually, which is time-consuming and error-prone (SAS V9.3 on Windows 8.1, ODS PDF and/or ODS RTF):

 

ods proclabel 'Table 1 - Patient Disposition - Full Analysis Set';
title5 j=C  f=Courier h=9pt 'Table 1';
title6 j=C f=Courier h=9pt 'Patient Disposition - Full Analysis Set';
title7 j=C f=Courier h=9pt 'Population:  Full Analysis Set';
footnote1 j=l  f=Courier h=9pt "DS_T_01.sas     &date" j=r '    Page ^{thispage} of ^{lastpage}';
proc report data = tlf.dS_t_01  nowd style(report)=[font_size=8pt font=(Courier)]

 

 

Is there a way to automatize the generation of table titles by writing a dataset that contains the header information linked to the reported data (eg. tlf.dS_t_01 || Table 1 || Patient Disposition || Full Analysis Set)? Or do you have any other suggestions?

 

Thanking you in anticipation,

Row

SAS Super FREQ
Posts: 8,814

Re: Automatic generation of table titles in long PDF reports

Hi:
Using Macro variables is one way to automate the insertion of titles and footnotes. It is easy using CALL SYMPUT or CALL SYMPUTX to make macro variables from observations/columns in a SAS dataset.

cynthia
Super User
Super User
Posts: 6,842

Re: Automatic generation of table titles in long PDF reports

What part of it do you want to automate?

A simple first step is to pull out the parts that change as macro variables.

 

%let tableno=1;
%let desc=Patient Disposition;
%let pop=Full Analysis Set;
%let pgm=DS_T_01.sas;
%let dsn=tlf.dS_t_01;

Then the code that generates the titles/ods statements can be boilerplate.

 

 

ods proclabel "Table &tableno - &desc - &pop";
title5 j=C  f=Courier h=9pt "Table &tableno";
title6 j=C f=Courier h=9pt "&desc - &pop";
title7 j=C f=Courier h=9pt "Population:  &pop";
footnote1 j=l  f=Courier h=9pt "&pgm     &date" j=r '    Page ^{thispage} of ^{lastpage}';
proc report data = &dsn  nowd style(report)=[font_size=8pt font=(Courier)]

 

New Contributor
Posts: 3

Re: Automatic generation of table titles in long PDF reports

Thank you a lot and sorry for my late answer, I had plenty of other urgent stuff to manage.

 

My problem is that I have created a data set which connects the name of the table to be reported with a series of information, as shown above.

 

Let's assume this data set looks like this:

Input

 

Now I am looking for an automated way to tell the program to recognize a row by the value of DSN and put in there all the other information contained in the same line. The result would be, as Tom figured out, a set of macro variables with the information of DESC, POP, PGM.

 

Do you have an idea?

 

Thank you!

SAS Super FREQ
Posts: 8,814

Re: Automatic generation of table titles in long PDF reports

I would use either DATA step and CALL SYMPUTX for the macro variable creation or I would use PROC SQL with INTO for the macro variable creation. It is quite easy to create macro variables from SAS datasets. It really depends on how you plan to write the rest of the program to use the macro variables -- because it sounds to me like you will want to generate a different report file for every DSN or every row. And the code you've posted only shows the PROC REPORT code for one report -- it doesn't show any ODS statements or a macro program to run the REPORT code multiple times.

Since you're using Page X of Y and ESCAPECHAR, that implies you are using either ODS RTF or ODS PDF, but you didn't show any ODS statements so that is a guess.

cynthia
New Contributor
Posts: 3

Re: Automatic generation of table titles in long PDF reports

Yes, I am going to generate separate PROC REPORTs for every row / every DSN. The reports themselves are not automated, since the the reported tables are of different structure, so I write them manually. The thing I want to be automated is the generation of headers and footnotes. All this happens within ODS PDF / ODS RTF. It looks like this:

options nobyline number missing="";
ods escapechar='^';
ods listing close;
ods rtf file =
"&out\FAS_Tables_.rtf"
                style = journal startpage=yes  toc_data

CONTENTS=YES;
ods noproctitle;

title;


ods proclabel "Table 1.0 	Subject disposition: Recruiting, Enrollment, Analyis-Set and First patient in";
title5 j=C  f=Courier h=9pt 'Table 1.0	: Recruiting, Enrollment, Analyis-Set and First patient in';
*title6 j=C f=Courier h=9pt 'Subject Disposition';

footnote1 j=l  f=Courier h=9pt "Reference:" ;
footnote2 j=l  f=Courier h=9pt "ana_TFL_V01-00.sas		&sysdate9.";
%maxpage(data=forreport_rek_enrol_FPI);
proc report data = forreport_rek_enrol_FPI  nowd style(report)=[font_size=8pt font=(Courier)]
									style(header)=[font_size=8pt font=(Courier)]
									style(column)=[font_size=8pt font=(Courier)]
									style(lines)=[font_size=8pt font=(Courier)] 
									contents = "" ;
	column mypage group variable colTotal  ; 
	define mypage/ order noprint ; 
	define group /order order = internal noprint;
	define variable / display 'Variable' order=data group; 
	define colTotal / display '' center ;
	break after group / skip;
	
		break before mypage/ contents = "" page;
	compute after _page_ ; 
		_page+1; 		
		line @60 'Page' _page " of &maxpage";
	endcomp;

run;
...

Is this helpful?

 

Thank you!

SAS Super FREQ
Posts: 8,814

Re: Automatic generation of table titles in long PDF reports

  Sort of...I don't understand why you show Page X of Y in the footnote and then roll your own for a LINE statement. You don't explain what %maxpage is doing and it's still not clear whether this is all going into 1 PDF/RTF output or multiple -- since you only show 1 PROC REPORT step. It sounds like you want/need a macro program that will generate the titles just before each report step based on dataset name. Otherwise, how will you distinguish which titles go with which report, unless you use the table number or something as one of your parameters.

 

  But for a quick proof of concept, in the program below, I make a dataset that holds some data specific title and number of obs information and then, I define a macro program to read that dataset and only get the row that meets my criteria and make TITLE statements. I could have put the title statements inside the macro program too, however, you showed your TITLES with the PROC REPORT, so I did that too. I modified something I already had that was using ODS PDF, but you will get the general idea of how &T1, &T1 and &useobs are treated in the 3 PROC REPORT steps.

 

cynthia

 

cynthia

 

data titles;
  length dsn $40 t1 t2 $80 ;
  infile datalines dlm=',' dsd;
  input dsn $ t1 $  t2 $ wantobs;
return;
datalines;
"sashelp.class","These Are The Students","At My School",5
"sashelp.cars","These Are The Cars","And Their Prices",6
"sashelp.heart","This Is The Jackson Heart Study","To Test With",10
;
run;
  
%macro maketitles(dsn=);
   %let wantdsn = %upcase(&dsn);
   data _null_;
      set work.titles;
      where upcase(dsn) = "&wantdsn";
	  call symputx('t1',t1,'G');
	  call symputx('t2',t2,'G');
	  call symputx('useobs',wantobs,'G');
	run;
%mend maketitles;
  
%maketitles(dsn=sashelp.class) 
ods pdf file='c:\temp\report_class.pdf';
proc report data=sashelp.class(obs=&useobs);
  title "&t1";
  title2 "&t2 and number of obs is &useobs";
run;
title;
ods pdf close;
  
%maketitles(dsn=sashelp.heart) 
ods pdf file='c:\temp\report_heart.pdf';
proc report data=sashelp.heart(obs=&useobs);
  column Status deathcause AgeCHDDiag Sex AgeatStart Height Weight Diastolic Systolic MRW Smoking AgeatDeath Cholesterol; 
  title "&t1";
  title2 "&t2 and number of obs is &useobs";
run;
title;
ods pdf close;
  
%maketitles(dsn=sashelp.cars) 
ods pdf file='c:\temp\report_cars.pdf';
proc report data=sashelp.cars(obs=&useobs);
  column make model type msrp mpg_city mpg_highway;
  title "&t1";
  title2 "&t2 and number of obs is &useobs";
run;
title;
ods pdf close;
Ask a Question
Discussion stats
  • 6 replies
  • 317 views
  • 0 likes
  • 3 in conversation