Dear community,
I am facing yet another peculiar issue with proc document. I have generated a bunch of ods document outputs containing proc tabulate results and would now like to rearrange them for final report. This is the code I am trying to use:
options papersize="a4" number date;
ods escapechar='~';
proc template;
define style styles.monospace_pageof;
parent=styles.monospace;
style pageno from pageno /
font=fonts("strongfont")
posttext=" of ~{lastpage} ";
style body from document /
leftmargin=20mm
rightmargin=20mm
topmargin=15mm
bottommargin=20mm;
end;
run;
%macro replay_table(file, group, object, title, subtitle, makegroup);
obstitle1 \foolib.&file.&object "%bquote(&title)" /just=left;
obstitle2 \foolib.&file.&object "%bquote(&subtitle)" /just=left;
%if &makegroup EQ 1 %then
%do;
make &group;
setlabel \&group#1 "%sysfunc(tranwrd(%bquote(&title), %str(~{unicode 0025}), %nrstr(%%)))";
%end;
%if %length(&group) GT 0 %then
%do;
dir \&group#1;
setlabel \foolib.&file.&object "%bquote(&subtitle)";
copy \foolib.&file.&object to ^;
dir ^^;
%end;
%else
%do;
setlabel \foolib.&file.&object "%sysfunc(tranwrd(%bquote(&title), %str(~{unicode 0025}), %nrstr(%%)))";
copy \foolib.&file.&object to ^;
%end;
%mend replay_table;
%macro generate_report;
data _null_;
toc = cats("'", pathname("foolib"), "\table_of_contents.csv'");
rtfout = cats("'", pathname("foolib"), "\final_report.rtf'");
call execute(catx(" ", "filename toc", toc, ";"));
call execute(cats(" ", "ods rtf style=monospace_pageof contents toc_data file=", rtfout, ";"));
run;
data _null_;
infile toc firstobs=2 dsd dlm=";" truncover end=last;
length file $20 group $10 object $30 title $250 subtitle $100;
input file group object title subtitle;
call symputx(cats("file", _n_), file);
call symputx(cats("group", _n_), group);
call symputx(cats("object", _n_), object);
call symputx(cats("title", _n_), title);
call symputx(cats("subtitle", _n_), subtitle);
if not missing(group) and group NE lag(group) then
call symputx(cats("makegroup", _n_), "1");
else call symputx(cats("makegroup", _n_), "0");
if last then
call symputx("last", _n_);
run;
proc document name=foolib.all_tables(write);
%do i = 1 %to &last;
%replay_table(&&file&i, &&group&i, &&object&i, %str(&&title&i), %str(&&subtitle&i), &&makegroup&i);
%end;
replay /levels=all;
quit;
ods rtf close;
%mend generate_report;
%generate_report
For reasons I was not able to figure out yet, adding the bodytitle option causes the footnotes to shift by one: table 1 has footnote of table 2, table 2 of table 3 and so forth. As each table needs to have a different footnote (which is generated at the time proc tabulate is run), it is not good at all.
Alternative code which calls proc document multiple times instead of merging sas7bitm files does work with bodytitle, but it unfortunately means I cannot create table of contents with two levels:
options papersize="a4" number date;
ods escapechar='~';
proc template;
define style styles.monospace_pageof;
parent=styles.monospace;
style pageno from pageno /
font=fonts("strongfont")
posttext=" of ~{lastpage} ";
style body from document /
leftmargin=20mm
rightmargin=20mm
topmargin=15mm
bottommargin=20mm;
end;
run;
%macro replay_table(file, object, title, title2);
proc document name=foolib.&file;
obstitle1 &object "%bquote(&title)" /just=left;
obstitle2 &object "%bquote(&title2)" /just=left;
replay &object;
quit;
%mend replay_table;
%macro report;
data _null_;
toc = cats("'", pathname("foolib"), "\table_of_contents.csv'");
rtfout = cats("'", pathname("foolib"), "\final_report.rtf'");
call execute(catx(" ", "filename toc", toc, ";"));
call execute(cats(" ", "ods rtf style=monospace_pageof bodytitle file=", rtfout, ";"));
run;
data _null_;
infile toc firstobs=2 dsd dlm=";" truncover;
length file $20 object $28 title $250 title2 $100;
input file group object title title2;
call execute(cats('%replay_table(', file, ',', object, ', %str(', title,') , %str(', title2,'))'));
run;
ods rtf close;
%mend report;
%report
Is there a way in which I can have table of contents and correct headers/footers as part of the document? Thank you!
Hi:
BODYTITLE takes up space in the document. If your bodytitle is one line, it adds that line to the BODY of the document. Your quickest resolution may be to work on this with Tech Support.
Cynthia
You might want to investigate use of the POSTTEXT option for tables in Proc tabulate instead of footnotes. The behavior is different and for Proc Tabulate with multiple table requests per procedure call the post text appears after the table unlike footnotes.
proc tabulate data=sashelp.class; class sex age; var height weight; table sex, Weight=''*mean='Avg Weight' /style=[posttext='Sex and weight' ] ; table age, height=''*mean='Avg Height' /style=[posttext='Age and Height' ] ; run;
Since the Posttext goes to the body all the time there is no shift for changing behavior due to the BODYTITLE option.
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.