Hi All, Thanks for your replies, esp. Cynthia. Much appreciated. I'm using a computed, noprint dummy variable to contain my compute block. If there's a better approach, let me know. My final version (sorry for the length, relevant bits in yellow): %macro print_topx_report; %let data=spdework.topx_source_data; %let nodata=%varexist(&data,message); <<< if there was no source data, I create a msg dataset upstream and print it instead. it will contain the variable "message" ; proc report data=&data nowd spanrows split="*"; columns %if (&nodata) %then %do; message %end; %else %do; label ("Period 1" period1_col1 period1_col2 period1_col3 ) ("Period 2" period2_col1 period2_col2 period2_col3 ) ("% Change" change_col1 change_col2 change_col3 ) dummy <<< dummy variable used to contain "code" ; %end; ; %if (&nodata) %then %do; define message / display center style(column)=[cellwidth=195mm] "0A"x; <<< prints a blank header (no varname or label) %end; %else %do; define label / display style(column)=[cellwidth=101mm]; define period1_col1 / analysis format=comma16. style(column)=[cellwidth=11mm]; define period1_col2 / analysis format=dollar16. style(column)=[cellwidth=20mm]; define period1_col3 / analysis format=dollar16. style(column)=[cellwidth=24mm]; define period2_col1 / analysis format=comma16. style(column)=[cellwidth=11mm]; define period2_col2 / analysis format=dollar16. style(column)=[cellwidth=20mm foreground=green]; define period2_col3 / analysis format=dollar16. style(column)=[cellwidth=24mm]; define change_col1 / computed format=blankpct. style(column)=[cellwidth=13mm background=highlight.] "Label1"; define change_col2 / computed format=blankpct. style(column)=[cellwidth=20mm background=highlight.] "Label2"; define change_col3 / computed format=blankpct. style(column)=[cellwidth=24mm background=highlight.] "Label3"; define dummy / computed noprint; <<< the dummy variable is not printed compute change_col1; <<< compute percent change between period 1 and period 2 if (period2_col1.sum ne 0) then change_col1 = (period2_col1.sum - period1_col1.sum) / period2_col1.sum; else change_col1 = 0; endcomp; compute change_col2; if (period2_col2.sum ne 0) then change_col2 = (period2_col2.sum - period1_col2.sum) / period2_col2.sum; else change_col2 = 0; endcomp; compute change_col3; if (period2_col3.sum ne 0) then change_col3 = (period2_col3.sum - period1_col3.sum) / period2_col3.sum; else change_col3 = 0; endcomp; compute dummy; if prxmatch("/Total|Percent/io",label) then do; call define(_row_,"style","style=DataEmphasis"); <<< I create the Totals and Percent rows in an upstream data step. I want it to look like a PROC REPORT summary line. end; if prxmatch("/Percent/io",label) then do; call define("period1_col1.sum","format","blankpct."); <<< see below for blankpct format. call define("period1_col2.sum","format","blankpct."); call define("period1_col3.sum","format","blankpct."); call define("period2_col1.sum","format","blankpct."); call define("period2_col2.sum","format","blankpct."); call define("period2_col3.sum","format","blankpct."); end; endcomp; %end; quit; %mend; proc format; * format to print blanks for special missing numeric values ; value blankpct .Z = " " other = [percent8.1] ; quit;
... View more