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
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)]
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:
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!
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!
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;
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: