BookmarkSubscribeRSS Feed
js5
Pyrite | Level 9 js5
Pyrite | Level 9

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!

2 REPLIES 2
Cynthia_sas
SAS Super FREQ

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

ballardw
Super User

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.

Ready to join fellow brilliant minds for the SAS Hackathon?

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!
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
  • 2 replies
  • 656 views
  • 0 likes
  • 3 in conversation