No need for macro variables.
Here is a more complete solution that includes the code generation step. If you want to include decoded values for variables with system supplied formats, like DATE or DOLLAR, then update the logic of the SQL join to pick the variables with those formats attached also.
proc contents data=MYLIB._ALL_ noprint
out=contents(keep=libname memname varnum name format)
;
run;
proc sql ;
create table custom as
select c.*
from contents c inner join dictionary.formats f
on f.source='C' and c.format=f.fmtname and f.fmttype='F'
order by c.libname,c.memname,c.varnum
;
quit;
filename code temp;
data _null_;
file code ;
set custom ;
by libname memname;
if first.memname then put
'data work.' memname +(-1) '_cd;'
/' set ' libname +(-1) '.' memname ';'
;
put 'length ' name +(-1) '_cd $200.;'
/ name +(-1) '_cd=vvalue(' name ');'
;
if last.memname then put 'run;' ;
run;
%include code / source2;
You can turn it into a macro if you want by replace MYLIB with a macro variable reference.
%macro decode(libref);
proc contents data=&libref.._all_ .....
%mend;
If you want to remove the format from the original variable you will need to do that in another step, since you need the format attached in the step that is using it to get the formatted value into the new character variable. Add this step before the %INCLUDE.
data _null_;
file code mod ;
set custom end=eof;
by libname memname ;
if _n_=1 then put 'proc datasets nolist lib=work;' ;
if first.memname then put 'modify ' memname +(-1) '_cd;' / 'format ' @;
put name @;
if last.memname then put ';'/'run;';
if eof then put 'quit;' ;
run;
... View more