BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
js5
Pyrite | Level 9 js5
Pyrite | Level 9

Dear community,

 

I have created the following picture format so that the numbers in cross tables are decimal-point aligned when monospace style is used:

proc format;
	picture pctn
		low - <10	= "0009.9%)" (prefix="(  ")
		10  - <100	= "0099.9%)" (prefix="( ")
		100 - high	= "0999.9%)" (prefix="(");

Interestingly enough, this only works when outputting the reports from proc tabulate directly into ods rtf. When I am trying to store the documents in ods document and concatenate them later using proc document, the pctn format is getting mangled and the prefix disappears. I am using the following macro to join the documents:

%macro replay_table(file, object, title);

	proc document name=foolib.&file;
		obstitle &object "%bquote(&title)" /just=left;
		replay &object;
	quit;

%mend replay_table;

%macro generate_onedoc;

	data _null_;
		toc = cats("'", pathname("foolib"), "\table_of_contents.csv'");
		rtfout = cats("'", pathname("foolib"), "\single_file_output.rtf'");
		call execute(catx(" ", "filename toc", toc, ";"));
		call execute(cats(" ", "ods rtf style=monospace bodytitle file=", rtfout, ";"));
	run;

	data _null_;
		infile toc firstobs=2 dsd dlm=";" truncover;
		length file $6 object $28 title $250;
		input file object title;
		call execute(cats('%replay_table(', file, ',', object, ', %str(', title,'))'));
	run;

	ods rtf close;
%mend generate_onedoc;

%generate_onedoc

Any ideas what might be happening here? Looking at the logs it appears that proc document is implicitly running proc format, but I am not sure if this is the reason for the strange behaviour.

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

I got it to work using a permanent format.  PROC DOCUMENT does not store permanent formats and does not recreate them so they can't be corrupted. 

 

proc datasets kill;
   quit;

libname library "%sysfunc(pathname(work,L))";

proc format lib=library.fmt;
	picture pctn (round)
		low - <10	= "0009.9%)" (prefix="(  ")
		10  - <100	= "0099.9%)" (prefix="( ")
		100 - high	= "0999.9%)" (prefix="(");
quit;
options fmtsearch=(library.fmt);
ods pdf file=".\xproctab_direct.pdf" style=monospace;

ods document name=indirect(write);
proc tabulate data=sashelp.cars;
	var Cylinders;
	class Make Type;
   table Make all, Type * Cylinders * (sum * [style=[just=R borderrightstyle=hidden cellwidth=50] format=best3.] colpctsum * [style=[just=L borderleftstyle=hidden cellwidth=90] format=pctn.]);
   quit;

ods document close;
ods pdf close;
ods pdf file=".\xproctab_indirect.pdf" style=monospace;
proc document name=indirect;
	replay \Tabulate#1\Report#1\Table#1;
   quit;
ods pdf close;

Capture.PNG

View solution in original post

6 REPLIES 6
js5
Pyrite | Level 9 js5
Pyrite | Level 9

I have now updated my format to use round option:

proc format;
	picture pctn (round)
		low - <10	= "0009.9%)" (prefix="(  ")
		10  - <100	= "0099.9%)" (prefix="( ")
		100 - high	= "0999.9%)" (prefix="(");S

Similarly to the prefix it is getting ignored when output is produced using proc document. Is proc document having issues with brackets?

data_null__
Jade | Level 19

Is the format PCTN available when you replay.  Do you get a NOTE: about the format being output.

 

Capture.PNG

js5
Pyrite | Level 9 js5
Pyrite | Level 9

Hi @data_null__ ,

 

yes, the format is being output. The following two lines:

NOTE: Format PCTN is already on the library WORK.FORMATS.
NOTE: Format PCTN has been output.

are repeated for every replay_table macro invocation. What is being strange here is that both brackets and the percent sign are being used as defined in the pctn format, it is only the rounding and prefix which are being lost.

js5
Pyrite | Level 9 js5
Pyrite | Level 9

I was able to generate a reproducer for the missing spaces using the sashelp.cars dataset:

proc format;
	picture pctn (round)
		low - <10	= "0009.9%)" (prefix="(  ")
		10  - <100	= "0099.9%)" (prefix="( ")
		100 - high	= "0999.9%)" (prefix="(");
quit;

ods pdf file="c:\Users\&sysuserid\Downloads\proctab_direct.pdf" style=monospace;
ods document name=indirect(write);

proc tabulate data=sashelp.cars;
	var Cylinders;
	class Make Type;

	table Make all, Type * Cylinders * (sum * [style=[just=R borderrightstyle=hidden cellwidth=50] format=best3.] colpctsum * [style=[just=L borderleftstyle=hidden cellwidth=90] format=pctn.]);
quit;

ods document close;
ods pdf close;
ods pdf file="c:\Users\&sysuserid\Downloads\proctab_indirect.pdf" style=monospace;

proc document name=indirect;
	replay \Tabulate#1\Report#1\Table#1;
quit;

ods pdf close;

The rounding vs truncation issue does not appear to be happening here though.

data_null__
Jade | Level 19

I got it to work using a permanent format.  PROC DOCUMENT does not store permanent formats and does not recreate them so they can't be corrupted. 

 

proc datasets kill;
   quit;

libname library "%sysfunc(pathname(work,L))";

proc format lib=library.fmt;
	picture pctn (round)
		low - <10	= "0009.9%)" (prefix="(  ")
		10  - <100	= "0099.9%)" (prefix="( ")
		100 - high	= "0999.9%)" (prefix="(");
quit;
options fmtsearch=(library.fmt);
ods pdf file=".\xproctab_direct.pdf" style=monospace;

ods document name=indirect(write);
proc tabulate data=sashelp.cars;
	var Cylinders;
	class Make Type;
   table Make all, Type * Cylinders * (sum * [style=[just=R borderrightstyle=hidden cellwidth=50] format=best3.] colpctsum * [style=[just=L borderleftstyle=hidden cellwidth=90] format=pctn.]);
   quit;

ods document close;
ods pdf close;
ods pdf file=".\xproctab_indirect.pdf" style=monospace;
proc document name=indirect;
	replay \Tabulate#1\Report#1\Table#1;
   quit;
ods pdf close;

Capture.PNG

js5
Pyrite | Level 9 js5
Pyrite | Level 9

Thank you, it worked! I was still having some issues with one of the ods documents using update mode - it was breaking all documents after itself), but switching the offender to write mode has allowed to replay all documents without issues.

It is still strange that using a permanent format is required though.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1154 views
  • 1 like
  • 2 in conversation