CALL EXECUTE vs CALL SYMPUT/INTO

Aus BI-Snippets - Business Intelligence Code und Module
Wechseln zu: Navigation, Suche

Bei der Verwendung der Statements CALL SYMPUT bzw. INTO innerhalb eines via CALL EXECUTE aufgerufenen Makros kommt es zu Runtime vs. Compile time Problemen, aufgrund dessen die durch CALL SYMPUT bzw. INTO erzeugten Makrovariablen innerhalb des Makros nicht nach Beendigung des nächsten STEPS referenziert werden können. Das Problem und die Lösung sind in SAS Note 23134 beschrieben:

If a CALL EXECUTE routine argument is invoked via a macro invocation or resolves to one, the macro code executes immediately. However, any SAS® statements (such as CALL SYMPUTX and INTO) that are produced by a CALL EXECUTE routine do not execute until after a step boundary has been passed.

Because of this, the %NRSTR function has to be used in the CALL EXECUTE syntax. This enables you to reference the variables created by CALL SYMPUTX or INTO in the code generated by CALL EXECUTE. This workaround delays execution of the macro within the DATA step that contains the CALL EXECUTE.

The use of %NRSTR in the following example masks the call to the %TEST macro when the argument to the CALL EXECUTE routine is evaluated. This causes the %TEST macro invocation to be pushed onto the input stack. Prior to using %NRSTR, all the non-macro statements generated were pushed to the input stack. %NRSTR delays the execution of the %TEST macro until after the RUN statement for the DATA step containing the CALL EXECUTE statement.

Here is an example:
<syntaxhighlight lang="SAS" line="1" >

 /*sample data set*/
 data a;
   value='Hello';
 run;
 /*sample macro*/
  %macro test(val);

   data _null_;
     call symput('num',200);
   run;
    %if &num eq 200 %then %do;
     proc print data=&val;
     run;
    %end;
  %mend;
 /*this will fail*/
 data _null_;
   temp='a';
   call execute('%test('||temp||')');
 run;
 /*work-around*/
 data _null_;
   temp='a';
   call execute('%nrstr(%test('||temp||'))');
 run;

</syntaxhighlight>

Starting with SAS® 9.3 M2, the new DOSUBL function can be used instead of CALL EXECUTE. Here is an example:


<syntaxhighlight lang="SAS" line="1" >

 data _null_;
   temp='a';
   rc=dosubl('%test('||temp||')');
 run;

</syntaxhighlight> Weiterführende Informationen zur sehr mächten SAS BASE Funktion DOSUBL sind in Paper 032-2013 zu finden. (Weiterführende Infos zum Thema auch in SAS NOTE 53059)