BookmarkSubscribeRSS Feed
pit
Fluorite | Level 6 pit
Fluorite | Level 6

I use Proc Report to create a listing for the destination tagsets.rtf. I have numeric columns with formats. There is a repetative ID column with subcategories. I want to only print each category once at first appearance and repeat them after a page break, so the reader always knows the ID and respective subgroups. For this I use the "spanrows" option in my Proc Report statement.

 

To enhance readability I added an empty line for each new ID-variable and after each new subcategory (only for the first subcategory) by using a compute block with a line statement: 

 

compute after <ID-variable> / style={font_size=4pt};
	line@1 "";
endcomp;

Displaying the results in "ods listing" works fine, but the output with "tagsets.rtf" does not work as I want, because after such a line break of the subcategory the ID-variable will no longer show up on following pages. 

 

 

I know this is an issue addressed by SAS providing a workaraound. I tried to use this workaround, but somehow it doesn't work. 

 

For reproducing my issue I created the following dataset:

proc format;
	value originf	1="Asia" 2="Europe" 3="USA";
	value makef		1="Acura" 2="Audi" 3="BMW" 4="Buick" 5="Cadillac" 6="Chevrolet" 7="Chrysler" 8="Dodge" 9="Ford" 10="GMC" 
					11="Honda" 12="Hummer" 13="Hyundai" 14="Infiniti" 15="Isuzu" 16="Jaguar" 17="Jeep" 18="Kia"  19="Land Rover" 20="Lexus"
					21="Lincoln" 22="MINI" 23="Mazda" 24="Mercedes-Benz" 25="Mercury" 26="Mitsubishi" 27="Nissan" 28="Oldsmobile" 29="Pontiac" 30="Porsche"
					31="Saab" 32="Saturn" 33="Scion" 34="Subaru" 35="Suzuki" 36="Toyota" 37="Volkswagen" 38="Volvo";
	value typef		1="Hybrid" 2="SUV" 3="Sedan" 4="Sports" 5="Truck" 6="Wagon";
run;

data tst;
	retain or mk typ model weight;
	set sashelp.cars;
	select(origin);
		when("Asia") or=1;
		when("Europe") or=2;
		when("USA") or=3;
		otherwise or=.;
	end;
	select(make);
		when("Acura") mk=1; when("Audi") mk=2; when("BMW") mk=3; when("Buick") mk=4; when("Cadillac") mk=5;
		when("Chevrolet") mk=6; when("Chrysler") mk=7; when("Dodge") mk=8; when("Ford") mk=9; when("GMC") mk=10;
		when("Honda") mk=11; when("Hummer") mk=12; when("Hyundai") mk=13; when("Infiniti") mk=14; when("Isuzu") mk=15;
		when("Jaguar") mk=16; when("Jeep") mk=17; when("Kia") mk=18; when("Land Rover") mk=19; when("Lexus") mk=20;
		when("Lincoln") mk=21; when("MINI") mk=22; when("Mazda") mk=23; when("Mercedes-Benz") mk=24; when("Mercury") mk=25;
		when("Mitsubishi") mk=26; when("Nissan") mk=27; when("Oldsmobile") mk=28; when("Pontiac") mk=29; when("Porsche") mk=30;
		when("Saab") mk=31; when("Saturn") mk=32; when("Scion") mk=33; when("Subaru") mk=34; when("Suzuki") mk=35;
		when("Toyota") mk=36; when("Volkswagen") mk=37; when("Volvo") mk=38;
		otherwise mk=.;
	end;
	select(type);
		when("Hybrid") typ=1; when("SUV") typ=2; when("Sedan") typ=3; 
		when("Sports") typ=4; when("Truck") typ=5; when("Wagon") typ=6;
		otherwise typ=.;
	end;
	format	or originf.
			mk makef.
			typ typef.;
	keep or mk typ model weight;
run;
proc sort data=tst;
	by or mk typ;
run;

Then the desired output is created by:

 

%let filename=&path.\Listings\Proc-Report_spanrows_rtf-tagsets_issue_&sysdate9..doc;

ods listing close;
options nofontembedding orientation=landscape nodate nonumber center ls=150 ps=70;
ods tagsets.rtf style=styles.listings_journal file="&filename." uniform;
ods noproctitle;
ods escapechar = "^";
ods tagsets.rtf startpage=yes;

proc report 	data=tst center split='*' nowd headline headskip spacing=2 spanrows
				style(report) = [cellspacing=0 cellpadding=6] out=tst
				/*style(lines) = {font_size=10pt}*/;
	columns (or hold_or mk typ model weight);
	define or			/ order left width=10 "Origin";
	define hold_or		/ 		computed noprint;
	define mk			/ order	left width=10 "Make";
	define typ			/ order left width=10 "Type";
	define model		/ order left width=10 "Model";
	define weight		/		left width=14 "Weight (in kg)" f=comma7.0;
	compute before or;
		hold=or;		* Assign new variable "hold", that keeps the value of "or";
	endcomp;
	compute hold_or;
		hold_or=hold;	* Pass value of "or" (earlier saved as "hold") to computed variable "hold_or";
		if or=. then or=hold;
	endcomp;
	* Empty line after "make";
	compute after mk / style={font_size=4pt};
		line@1 "";
	endcomp;
	* Empty line after "origin";
	compute after or / style={font_size=8pt};
		line@1 '';
	endcomp;
run;

ods tagsets.rtf close;
ods listing;

The resulting Output is attached.

 

2 REPLIES 2
Cynthia_sas
Diamond | Level 26

Hi:

  Making a first pass reading your program I note a lot of inconsistency that I would clean up first:

first_pass.png

That's all I've found so far that I would change. I haven't actually had a chance to run anything yet. Thanks for posting your program that makes the data although it is annoying that you are using a custom style -- I'm not sure how it is different from regular JOURNAL style.

 

Cynthia

pit
Fluorite | Level 6 pit
Fluorite | Level 6

Dear Cynthia, 

 

thank you for your quick reply and helpful comments on my code! I corrected the inconsistencies: 

 

%let filename=&path.\Listings\Proc-Report_spanrows_rtf-tagsets_issue_v2_&sysdate9..rtf;

ods listing close;
options nofontembedding orientation=landscape nodate nonumber center;
ods tagsets.rtf style=styles.journal file="&filename." uniform;
ods noproctitle;
ods escapechar = "^";
ods tagsets.rtf startpage=yes;

proc report 	data=tst center split='*' nowd spanrows
				style(report) = [cellspacing=0 cellpadding=6]
				/*out=tst_out style(lines) = {font_size=10pt}*/;
	columns (or hold_or mk typ model weight);
	define or			/ order left style(column)=[cellwidth=1.5cm] "Origin";
	define hold_or		/ 		computed noprint;
	define mk			/ order	left style(column)=[cellwidth=1.5cm] "Make";
	define typ			/ order left style(column)=[cellwidth=1.5cm] "Type";
	define model		/ order left style(column)=[cellwidth=1.5cm] "Model";
	define weight		/		left style(column)=[cellwidth=2.0cm] "Weight (in kg)" f=comma7.0;
	compute before or;
		hold=or;		* Assign new variable "hold", that keeps the value of "or";
	endcomp;
	compute hold_or;
		hold_or=hold;	* Pass value of "or" (earlier saved as "hold") to computed variable "hold_or";
		if or=. then or=hold;
	endcomp;
	* Empty line after "make";
	compute after mk / style={font_size=4pt};
		line@1 "";
	endcomp;
	* Empty line after "origin";
	compute after or / style={font_size=8pt};
		line@1 '';
	endcomp;
run;

ods tagsets.rtf close;
ods listing;

 

Regarding the custom journal-style: I made some changes on the page definitions (e.g. size of page, fontsize). For the sake of this example I can go with the default journal style.