/*
/ Program : mkformat.sas
/ Version : 1.5
/ Author : Roland Rashleigh-Berry
/ Date : 02-Jan-2012
/ Purpose : To create a format out of a "coded" and "decoded" variable in a
/ specified dataset.
/ SubMacros : %hasvars %varlen
/ Notes : Use this to generate a format from a coded and decoded variable so
/ that you can report it in coded order but have it displayed in its
/ decoded form by applying the generated format.
/ Usage : %mkformat(dsname(where=(x>1)),varcd,vardcd,fmtname,fmtcat);
/
/===============================================================================
/ PARAMETERS:
/-------name------- -------------------------description------------------------
/ ds (pos) Input dataset
/ code (pos) Coded variable
/ decode (pos) Decoded variable
/ fmtname (pos) Format name
/ lib (pos) Catalog library (defaults to work)
/ indent=0 Number of spaces to indent the label
/ underscore=no Whether to use underscore characters before and after the
/ label (will override indent= if set to yes)
/===============================================================================
/ AMENDMENT HISTORY:
/ init --date-- mod-id ----------------------description------------------------
/ rrb 19Mar07 Macro called message added plus header tidy
/ rrb 30Jul07 Header tidy
/ rrb 19Jan11 Allow modifiers in input dataset specification (v1.2)
/ rrb 30Nov11 indent= parameter added (v1.3)
/ rrb 21Dec11 underscore= processing added (v1.4)
/ rrb 02Jan12 Notes disabled (v1.5)
/===============================================================================
/ This is public domain software. No guarantee as to suitability or accuracy is
/ given or implied. User uses this code entirely at their own risk.
/=============================================================================*/
%put MACRO CALLED: mkformat v1.5;
%macro mkformat(ds,code,decode,fmtname,lib,indent=,underscore=no);
%local errflag err len savopts;
%let err=ERR%str(OR);
%let errflag=0;
%let savopts=%sysfunc(getoption(notes));
options nonotes;
%if not %sysfunc(exist(%scan(&ds,1,%str(%()))) %then %do;
%put &err: (mkformat) Dataset &ds does not exist;
%let errflag=1;
%end;
%if not %length(&fmtname) %then %do;
%put &err: (mkformat) You must supply a format name;
%let errflag=1;
%end;
%if &errflag %then %goto exit;
%if not %length(&indent) %then %let indent=0;
%if not %length(&underscore) %then %let underscore=no;
%let underscore=%upcase(%substr(&underscore,1,1));
data _mkfmt;
set &ds;
run;
%if not %hasvars(_mkfmt,&code &decode) %then %do;
%put &err: (mkformat) Dataset &ds does not contain variable(s) &_nomatch_;
%let errflag=1;
%end;
%if &errflag %then %goto exit;
proc sort nodupkey data=_mkfmt(keep=&code &decode)
out=_mkfmt(rename=(&code=start &decode=label));
by &code &decode;
run;
%let len=%varlen(_mkfmt,label,x);
%if &underscore EQ Y or &indent GT 0
%then %let len=%eval(&len+%sysfunc(max(2,&indent)));
data _mkfmt;
length label $ &len;
retain fmtname "&fmtname";
set _mkfmt;
%if &underscore EQ Y %then %do;
label="_"||trim(label)||"_";
%end;
%else %if &indent GT 0 %then %do;
label=repeat(" ",%eval(&indent-1))||label;
%end;
run;
proc format cntlin=_mkfmt
%if %length(&lib) %then %do;
library=&lib
%end;
;
run;
proc datasets nolist;
delete _mkfmt;
run;
quit;
%goto skip;
%exit: %put &err: (mkformat) Leaving macro due to problem(s) listed;
%skip:
options &savopts;
%mend mkformat;