Chuck,
I enjoyed your post and your well-crafted macro code. I, too, strive to minimize maintenance disruption by honoring legacy interfaces while providing additional function without muddling the code.
Having an interest in macros myself, I shanghaied your code into my SAS laboratory to see how it works, especially that impressive quadruple ampersand piece! In my experience, I have never needed more than triple ampersands to produce the required indirection. More than triple ampersands seem to me to obscure the logic. So I wanted to see why you included a quad!
As I studied your code in the following test bed, it appeared to me that I might be able to simplify the 2 quads to doubles and yield the same result. When I attempted it, it seemed to work as the original. What are your thoughts?
OPTIONS MPRINT MPRINTNEST MLOGIC;
DATA work.users;
INPUT user_id : $8.
password : $25.
;
DATALINES;
z123456 bisko_bosco34
wakkaw yadda_yadda2314
abcdefg blini_wonker
;
RUN;
%macro getPWD(user,dummy);
%put RP Note: inside macro getpwd(user,dummy) ;
%put - parameter user = &user ;
%put - parameter dummy = &dummy ;
%local dsid rc user_id varN _&dummy;
%let dsid=%sysfunc(open(work.users(where=(user_id="&user")),i));
%if (&dsid > 0) %then %do;
%let varN = %sysfunc(varnum(&dsid,password));
%let rc=%sysfunc(fetchobs(&dsid,1));
%if (&rc = 0) %then %do;
%let _&dummy = %sysfunc(getvarc(&dsid,&varN));
%if %length(&dummy) > 0 %then %let &dummy = &&_&dummy ;
%else &&_&dummy ;
%end;
%else %put RP ERROR: failed to retrieve an observation from misc.users for user_id=&user ;
%let rc=%sysfunc(close(&dsid));
%end;
%else %put RP ERROR: failed to open misc.users ;
%put RP Note: finished getpwd ;
%mend;
%macro test;
%local password;
%let user_id = wakkaw;
%getPWD(&user_id,password)
%put _LOCAL_;
%mend;
%test
%PUT password=%getPWD(wakkaw);
... View more