Jose
Jose

Reputation: 21

SAS: How to assign the output value of a function-like macro?

I am very new using SAS and Im having hard time trying to assign the output value of a function-like macro to a macro variable. After testing, I have check that the value is computed correctly, but once I tried to assign it the program crashes. here you can find the code

%MACRO TP_BULLET(ZCURVE,TAU,YF=1);

    /* KEEP ONLY THE ZERO CURVE UNTIL MATURITY*/
    DATA _TEMP;
        SET &ZCURVE;
        IF MATURITY > &TAU  THEN DELETE;
    RUN;

    PROC SQL NOPRINT;
        SELECT DISTINCT 1- DF
            INTO :NUME
        FROM _TEMP
        GROUP BY MATURITY
        HAVING MATURITY = MAX(MATURITY);
    QUIT;

    PROC SQL NOPRINT;
        SELECT SUM(DF)
            INTO :DENO
        FROM _TEMP;
    QUIT;

    PROC DELETE DATA=_TEMP;RUN;

    %LET TP = %SYSEVALF(&YF*&NUME / &DENO);
    &TP


%MEND TP_BULLET;


%MACRO TESTER2; 
    %LET K = %TP_BULLET(ZCURVE,TAU,YF=1);
    %PUT .......&K; 
%MEND TESTER2;

%TESTER2;

The error I am getting is the following

WARNING: Apparent symbolic reference DENO not resolved.
WARNING: Apparent symbolic reference NUME not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 
       1*&NUME / &DENO 

So I suppose that the DATA Step is failing to create the sas table _TEMP, but I have no idea how to solve it. Thanks in advance for any help or sugestion

Upvotes: 2

Views: 286

Answers (2)

Tim Sands
Tim Sands

Reputation: 1068

All philosophical issues aside, you could add a parameter to your macro that specifies the new macrovariable (mv) that you want to create. So instead of

%Let k = %TP_BULLET(ZCURVE,TAU,YF=1);

you could call

%TP_BULLET(ZCURVE,TAU,mvOutput=k,YF=1);;

Your macro would need to be modified slightly with

%MACRO TP_BULLET(ZCURVE,TAU,mvOutput,YF=1);
    %GLOBAL &mvOutput;
    ........ Same code as above .........
    %Let &mvOutput = &TP; *Instead of final line with '&TP';
%MEND;

It is not a very SAS-y way to accomplish it, but it can help keep things more modular and comprehensible if you're working with more programming backgrounds, rather than SAS.

Upvotes: 1

Allan Bowe
Allan Bowe

Reputation: 12691

This is NOT a 'function like' macro - you are mixing SAS Macro language and Base SAS. Remember that the SAS Macro language is a code generator - and you are generating code, which is currently something like:

%let K=data _temp; set ZCURVE; ....

note how the above is not what you wanted to assign to the macro variable K.

To help with this, try running your macro with options mprint - this will show you the code being generated by your macro.

If you want your macro to act like a function, then (at a minimum) you should find NO code being generated via the mprint option..

Upvotes: 2

Related Questions