BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
kscdenney
Calcite | Level 5

I want to print a statement at the top of each BYVAL table (or the top of each page) labelling the BYVAL. However, when an ODS PDF page break occurs in the middle of a table, the label should include the word "(continued)".  

 

I don't care if this happens through a line statement, ODS text, conditional label, some span functionality, etc.  I don 't care if the proc report uses a BY statement or if I have to create a macro to run each BYVAL individually. 

 

I've only tried output ODS PDF, which needs to be the final result.  But I guess if ODS PDF is causing the problem, I could use another ODS and save the result to pdf manually.

 

I think I should be able to do this by evaluating _break_ type or observation number.  I feel like I might need a hold value from one compute statement to use in another compute statement, but I can't get it right. 

 

Thank you in advance for any advice!

 

ODS PDF.png

 

proc sort data=sashelp.cars out=cars_make;
  by make;
run;
 
ods escapechar='^';
options  nobyline;

Title1 color='black' "^S={font_face='Verdana' font_size=18pt}Title1" ;
Title2 color='black' "^S={font_face='Verdana' font_size=18pt}Title2" ;
Title3 color='black' "^S={font_face='Verdana' font_size=18pt}Title3" ;

ods pdf file ="SGE26.pdf" notoc startpage=no  ;
proc report data=cars_make (firstobs= 1 obs= 500) out=tryout;
   where origin = 'USA';
   by make;
   column make  DISP_make model type origin newobs;
   define make /group noprint;
   define DISP_make /computed;
   define model / order order=internal;
   define type / order order=internal;
   define origin / order order=internal;
   define newobs/display computed;

break after make/;

compute newobs;
	_obs_+1;
	newobs=(_obs_)-1;
endcomp;

compute before _page_ /left;
	length text $100;
	if hold_obs <2 then do;
		text="For Bucket xxx";
		num=100;
	end;
	else do;
		text="For Bucket XXX (continued)";
		num=150;
	end;
	line text $varying. num;
endcomp;


compute before make;
      cnt_make + 1;
      hold_make= make;
	  hold_obs=newobs;
endcomp;

compute DISP_make / character length= 20;
      DISP_make = hold_make;
	
   endcomp;
run;
ods pdf close;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User

If you want compact layout, try this one :

%let n=20;   * a page has 20 records ;



DATA AAA;
	SET SASHELP.CARS(obs=400);
RUN;
proc sort data=AAA;
by Make;
run;
data AAA;
 set AAA;
 by Make;
 if first.Make then n=0;
 n+1;
 if first.Make or mod(n,&n.)=1 then PAGE_NO+1;
 drop n;
run;





proc freq data=AAA noprint;
table Make*PAGE_NO/out=PAGE_NO;
run;
data PAGE_NO;
 length Make $ 80;
 set PAGE_NO;
 by Make;
 if not first.Make then Make=catx(' ',Make,'(continued)');

 total+count;
 if total>20 then do;group+1;total=count;end;
run;
data AAA2;
 merge AAA(drop=Make) PAGE_NO(keep=Make PAGE_NO group);
 by PAGE_NO;
run;
proc freq data=PAGE_NO noprint;
table group/out=group;
run;





%macro report(group=);
PROC REPORT DATA=AAA2 nowd contents='';
where group=&group.;
by PAGE_NO;
	COLUMNS  Make  Model Type Origin DriveTrain MSRP;
	DEFINE Make / order	 ;

	DEFINE Model / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Type / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Origin / 	DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE DriveTrain / DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE MSRP / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	compute before _page_/style={just=l};
     line Make $80.;
	endcomp;
RUN;
%mend;



ODS PDF FILE= "c:\temp\A.pdf" startpage=no;
option nobyline;
data _null_;
 set group end=last;;
 call execute(catt('%report(group=',group,')'));
 if not last then call execute('ods pdf startpage=now;');
run;
ODS PDF CLOSE;

View solution in original post

3 REPLIES 3
Ksharp
Super User

Yeah. It is a little complicated ,but still doable.

 

%let n=20;   * a page has 20 records ;



DATA AAA;
	SET SASHELP.CARS(obs=400);
RUN;
proc sort data=AAA;
by Make;
run;
data AAA;
 set AAA;
 by Make;
 if first.Make then n=0;
 n+1;
 if first.Make or mod(n,&n.)=1 then PAGE_NO+1;
run;



proc freq data=AAA noprint;
table Make*PAGE_NO/out=PAGE_NO;
run;
data PAGE_NO;
 length Make $ 80;
 set PAGE_NO;
 by Make;
 if not first.Make then Make=catx(' ',Make,'(continued)');
run;






%macro report(PAGE_NO=,Make=);
PROC REPORT DATA=AAA nowd contents='';
where PAGE_NO=&PAGE_NO.;
	COLUMNS ("(*ESC*)S={just=l}For Bucket &Make." Make Model Type Origin DriveTrain MSRP);
	DEFINE Make / 	DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Model / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Type / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Origin / 	DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE DriveTrain / DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE MSRP / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
RUN;
%mend;



ODS PDF FILE= "c:\temp\A.pdf" ;
data _null_;
 set PAGE_NO;
 call execute(catt('%report(PAGE_NO=',PAGE_NO,',Make=',Make,')'));
run;
ODS PDF CLOSE;

Ksharp_0-1741924254812.png

 

Ksharp
Super User

If you want compact layout, try this one :

%let n=20;   * a page has 20 records ;



DATA AAA;
	SET SASHELP.CARS(obs=400);
RUN;
proc sort data=AAA;
by Make;
run;
data AAA;
 set AAA;
 by Make;
 if first.Make then n=0;
 n+1;
 if first.Make or mod(n,&n.)=1 then PAGE_NO+1;
 drop n;
run;





proc freq data=AAA noprint;
table Make*PAGE_NO/out=PAGE_NO;
run;
data PAGE_NO;
 length Make $ 80;
 set PAGE_NO;
 by Make;
 if not first.Make then Make=catx(' ',Make,'(continued)');

 total+count;
 if total>20 then do;group+1;total=count;end;
run;
data AAA2;
 merge AAA(drop=Make) PAGE_NO(keep=Make PAGE_NO group);
 by PAGE_NO;
run;
proc freq data=PAGE_NO noprint;
table group/out=group;
run;





%macro report(group=);
PROC REPORT DATA=AAA2 nowd contents='';
where group=&group.;
by PAGE_NO;
	COLUMNS  Make  Model Type Origin DriveTrain MSRP;
	DEFINE Make / order	 ;

	DEFINE Model / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Type / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE Origin / 	DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE DriveTrain / DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	DEFINE MSRP / 		DISPLAY STYLE(COLUMN)={CELLWIDTH=1IN};
	compute before _page_/style={just=l};
     line Make $80.;
	endcomp;
RUN;
%mend;



ODS PDF FILE= "c:\temp\A.pdf" startpage=no;
option nobyline;
data _null_;
 set group end=last;;
 call execute(catt('%report(group=',group,')'));
 if not last then call execute('ods pdf startpage=now;');
run;
ODS PDF CLOSE;
kscdenney
Calcite | Level 5

Wow!  This is quite the "work-around," but it indeed WORKS!  Thank you so much! 

 

This second "compacted" method fit my needs better by not automatically page -breaking between the groups.  

 

I'm pretty new to Proc Report; I never would have thought to create a table to hold the record count, page numbering and the "continued" text.  I've added several new concepts to my SAS toolbox by working through this code with my real-life report. Thanks again! 

 

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