This macro consists of three separate macros. The two small ones are called %enquote and %sepbycommas. They accept space-separated lists of variable names and print out, in the first case, that list with double-quotes around each name, separated by commas, and, in the second case, just the variable names separated by commas. If you provide
permno date ret
to the first macro, it will return
``permno'',''date'',''ret''
And the second will return
permno,date,ret
The macro that does the actual work, %hashmerge, just prints out the data step that does the hash merge.
%macro sepbycomma(varlist); %let delim=%str( ); %let outputvar=%qscan(&varlist,1,&delim); %let i=2; %do %while(%length(%qscan(&varlist,&i,&delim)) GT 0); %let varhere=%qscan(&varlist,&i,&delim); %let outputvar=&outputvar,&varhere; %let i=%eval(&i + 1); %end; &outputvar %mend; %macro enquote(varlist); %let delim=%str( ); %let outputvar=''%qscan(&varlist,1,&delim)''; %let i=2; %do %while(%length(%qscan(&varlist,&i,&delim)) GT 0); %let varhere=%qscan(&varlist,&i,&delim); %let outputvar=&outputvar,''&varhere''; %let i=%eval(&i + 1); %end; &outputvar %mend; %macro hashmerge(largeds, smallds, byvars, extravars, outds); data &outds; call missing(%sepbycomma(&extravars)); if _n_=1 then do; declare hash h(dataset:''&smallds''); h.defineKey(%enquote(&byvars)); h.defineData(%enquote(&extravars)); h.defineDone(); end; set &largeds; if h.find()=0; run; %mend;