BookmarkSubscribeRSS Feed
deleted_user
Not applicable
I have a stored procedure that, using Proc Report, lists information about students at several colleges. My question is this: using the following type of code, how can I get the various college names into a report heading when the data changes from one college to another:

TITLE;
TITLE1 "ALAMO COMMUNITY COLLEGES";
TITLE2 h=4 " Employee Report ";
TITLE3 h=4 " For &campuscodes ";
FOOTNOTE;
FOOTNOTE1 h=2 "Report Name: HFA954";
FOOTNOTE2 h=2 "Generated by ACCD Information Technologies on %SYSFUNC(DATE(), WEEKDATX23.) at %SYSFUNC(TIME(),TIMEAMPM8.)";

PROC REPORT data = SortedHFA954Step01 spacing = 1 style(Header)={font_size=1.0 font_weight=medium} split='*' missing;
column campus employee_name birth_date curr_hire_date department;

define campus / group noprint;
define employee_name / "Employee*Name" style=[just=l font_weight=demi_bold font_size=1.0];
define birth_date / "Date of*Birth" style=[just=l font_weight=demi_bold font_size=1.0];
define curr_hire_date / "Employment*Date" style=[just=l font_weight=demi_bold font_size=1.0];
define department / "Department" style=[just=l font_weight=demi_bold font_size=1.0] format=$30.;

compute before campus;
endcomp;

break after campus / page;

run;

Any advice / assistance is most welcome. Thanks in advance!
4 REPLIES 4
Cynthia_sas
SAS Super FREQ
Hi:
Run the following code in a code node and review the results. There are approximately 3 different techniques that you could use:
1) use BY group processing and allow the default BYLINE to show; or
2) use BY group processing and suppress the default BYLINE in order to use special BY group variables in the SAS title; or
3) use PROC REPORT COMPUTE BEFORE techniques, either
COMPUTE BEFORE_PAGE_ or COMPUTE BEFORE GRPVAR capability to put the "group" information within the boundary of the table.

You'll have to decide which technique works best for you depending on the client application from which the SP will be run; the result type that your users will most likely use; and whether the output will be printed or not (for example, if you create HTML results from the SP and then your users want to print the HTML results, the COMPUTE BEFORE text from method 3 will only appear on the 1st page of any group (if the group goes over more than 1 page). You'll need to test out each of these techniques from all the client applications that could invoke the SP.

If you are planning to surface the reports in Web Report Studio, you should be aware of the fact that LINE statement information in PROC REPORT SPs is not currently surfaced in Web Report Studio because the SASReport XML does not currently handle LINE information (which would rule out example 3 if you were going to use WRS.)

cynthia
[pre]
** the code;

proc sort data=sashelp.shoes out=shoes;
by product region;
run;

** 1) Using regular BYLINE info;
options byline;
ods rtf file='c:\temp\product_byline.rtf';
ods pdf file='c:\temp\product_byline.pdf';
ods html file='c:\temp\product_byline.html' style=sasweb;
proc report data=shoes nowd;
title '1) Using Default BYLINE';
by product;
column product region sales;
define product /group noprint;
define region /group;
define sales/ sum;
run;
ods _all_ close;

** 2) using special BY variable info;
** turn off "default" BYLINE first;
options nobyline;
ods rtf file='c:\temp\product_nobyline.rtf';
ods pdf file='c:\temp\product_nobyline.pdf';
ods html file='c:\temp\product_nobyline.html' style=sasweb;
proc report data=shoes nowd;
title '2) Using Special BY info in Title: #byval(product)';
title2 'This title will appear on EVERY PAGE for RTF and PDF';
by product;
column product region sales;
define product /group noprint;
define region /group;
define sales/ sum;
run;
ods _all_ close;
options byline;

** 3) Using COMPUTE block before Page;
ods rtf file='c:\temp\product_compute.rtf' ;
ods pdf file='c:\temp\product_compute.pdf' ;
ods html file='c:\temp\product_compute.html' style=sasweb;
proc report data=sashelp.shoes nowd
style(lines)=Header{just=c font_weight=bold};
title '3) SHORT pages and compute before using group variable';
column product region sales;
define product /group noprint;
define region /group;
define sales/ sum;
break after product /page;
compute before _page_;
lgprod = length(product);
line 'Product is: ' product $varying. lgprod;
endcomp;
run;

proc report data=sashelp.shoes nowd
style(lines)=Header{just=c font_weight=bold};
title '3) LONG compute before using group variable';
title2 'For LONG reports, when printing from HTML';
title3 'compute before text will only appear on the FIRST page for HTML';
column product region subsidiary sales;
define product /group noprint;
define region /group;
define subsidiary / order;
define sales/ sum;
break after product /page;
compute before _page_;
lgprod = length(product);
line 'Product is: ' product $varying. lgprod;
endcomp;
run;
ods _all_ close;

** 3a) Using COMPUTE block before PRODUCT;
ods rtf file='c:\temp\product_compute2.rtf' ;
ods pdf file='c:\temp\product_compute2.pdf' ;
ods html file='c:\temp\product_compute2.html' style=sasweb;
proc report data=sashelp.shoes nowd
style(lines)=Header{just=c font_weight=bold};
title '3a) SHORT pages and compute before using group variable';
column product region sales;
define product /group noprint;
define region /group;
define sales/ sum;
break after product /page;
compute before product;
lgprod = length(product);
line 'Product is: ' product $varying. lgprod;
endcomp;
run;

proc report data=sashelp.shoes nowd
style(lines)=Header{just=c font_weight=bold};
title '3a) LONG compute before using group variable';
title2 'For LONG reports, when printing from HTML';
title3 'compute before text will only appear on the FIRST page for HTML';
column product region subsidiary sales;
define product /group noprint;
define region /group;
define subsidiary / order;
define sales/ sum;
break after product /page;
compute before product;
lgprod = length(product);
line 'Product is: ' product $varying. lgprod;
endcomp;
run;
ods _all_ close;
[/pre]
deleted_user
Not applicable
Hi, Cynthia, and thank you for replying! I utried using your option 2, and the report almost works.... I get output data with college designations in the heading, but I also get apparent BYLINE data..... what I see is like this:

....................................For XYZ College
................................Campus=XYZ college

I checked my code and I am using the Options = NOBYLINE; here is my Proc Print Code, based on your option 2..... What am I doing incorrectly?

PROC REPORT data = SortedHFA954Step01 nowd spacing = 1 style(Header)={font_size=1.0 font_weight=medium} split='*' missing ;
options nobyline;
TITLE;
TITLE1 "ALAMO COMMUNITY COLLEGES";
TITLE2 h=4 " Employee Report ";
TITLE3 h=4 " For #byval(campus) ";
by campus ;
column campus employee_name birth_date curr_hire_date department;

define campus / group noprint;
define employee_name / "Employee*Name" style=[just=l font_weight=demi_bold font_size=1.0];
define birth_date / "Date of*Birth" style=[just=l font_weight=demi_bold font_size=1.0];
define curr_hire_date / "Employment*Date" style=[just=l font_weight=demi_bold font_size=1.0];
define department / "Department" style=[just=l font_weight=demi_bold font_size=1.0] format=$30.;

FOOTNOTE;
FOOTNOTE1 h=2 "Report Name: HFA954";
FOOTNOTE2 h=2 "Generated by ACCD Information Technologies on %SYSFUNC(DATE(), WEEKDATX23.) at %SYSFUNC(TIME(),TIMEAMPM8.)";

options byline;
run;

Thanks so much for your help and especially for your patience!!!!
Cynthia_sas
SAS Super FREQ
Hi:
Notice the difference between where I have my options statement to turn the option on and off and where you put the statement in your code. It does make a difference. Your 2nd option statement essentially cancelled out the 1st option statement because they were both within the boundary of the step. A good rule of thumb is to place the option statement to turn OFF regular by line processing BEFORE Proc Report starts to execute; and to place the option statement to turn ON the regular processing AFTER Proc Report finishes executing (after the step boundary).

Since you are executing this as a stored process, however, you would want to run the option right after %stpbegin (then the setting will override any by line option set inside %stpbegin):[pre]
*ProcessBody;
%stpbegin;
options nobyline;
proc report ...;
...more code;
run;
%stpend;
[/pre]

If you do not have any other steps that require by line default processing, then you can leave off the option byline statement at the end of the code. (you have yours before the RUN). In fact, it is this last option byline that caused your trouble.

Think of the options statement, like the title statement, as being "pulled out" of your code and executed first. The 1st option statement was cancelled out by the 2nd option statement. Just like if you did this:
[pre]
proc report data=sashelp.shoes nowd;
title 'one fish, two fish';
column product sales;
title 'red fish, blue fish';
run;
[/pre]

The -effective- title would be 'red fish, blue fish' -- because the second title statement would override the first title statement. In order to avoid this accidental collision, I generally follow the scheme where all my option statements stay outside of step boundaries and my title and footnote statements are the only global-type statements that I will put inside procedure code.

cynthia
deleted_user
Not applicable
Got it and actually understand it! I put the options nobyline at the top of my code, prior to the %stpbegin; line, and the program worked successfully.

A big thank you, and hopefully, my questions will start diminisheing soon! 🙂

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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