Macros that need to return a single value, as opposed to generating code are often written as functions so they can be used, for example, as follows:
- %let total = %getMax(data= . . ., var = . . . );
- retain denom %getMax(data= . . ., var = . . . );
- store the value into a macro variable that the calling program must know about;
- save the value into a data set that the calling program must use to get the value;
- use the %sysfunc macro along with the data access functions.
%macro getSurrogateKey
(data = /* name of the dataset being updated */
,key = /* name of surrogate key variable */
);
%local newkey;
%if &&&key = . or &&&key = %then
%do; /* generate a new surrogate key value */
%let rc = %sysfunc(dosubl(
'proc sql noprint;
select cats(sum(max(&key),1))
into:newkey from &data;quit;'
));
%put NOTE: &key value of &newkey generated.;
&newkey
%end; /* generate a new surrogate key value */
%else &&&key;
%mend getSurrogateKey;
The macro is called unconditionally by the update process and if the macro variable, from the Data Entry page (a SAS Server Page), for the key is missing, a new row is being added and this requires a new key value. The DOSUBL function is used, via %SYSFUNC) to run the PROC SQL code to get the next auto-number key value. Since DOSUBL is used, the macro execution does not return the SQL code to the current SAS session's input stack. Executing the macro returns:
- the new key value, &newkey, for a new row.
- the current key value, &&&key, for an existing row.
Thanks Don,
ReplyDeleteThis is wild stuff. Mike Rhoads had an great SGF paper last year on "Macro Function Sandwich" which used FCMP and Run_Macro to write function-style macros which execute data/proc steps.
http://support.sas.com/resources/papers/proceedings12/004-2012.pdf
Seems like DOSUBL lets you do similar, with less work (?). (I don't have 9.3M1 yet, so can't play)
When I explored run_macro, I was disappointed to see that it wasn't thoroughly documented. The "inner" data step/proc step executes in it's own environment (sub-session?), and what gets inherited from/passed back to the main environment seemed to vary quite a bit.
But this is certainly exciting stuff. Makes me wish I was going to SGF this year.
--Q.
Quentin, I know you won't be at SGF. But I spoke to Rich L who is the developer for DOSUB/DOSUBL (as well as PROC STREAM) and he is presenting a paper on this at SGF:
ReplyDeleteSubmitting SAS® Code on the Side
Date: Tue, Apr 30, 2013
Time: 1:30 PM-1:50 PM
Location: Room 2016
So you might want to check this out later. He also said that WRT Mike Rhoads paper about this, he has been in touch with Mike and the above paper includes one of examples modified to use DOSUBL.
Excellent, that's exciting news. I'll look forward to reading the paper. Really useful stuff, which can greatly expand the utility of the macro language.
ReplyDeleteThanks again,
-Q.