1
votes

I have this data, and I want to update a certain table using a macro

DATA WORK.t1;
    LENGTH
        POLICY_RK          8
        POLICY_VERSION     8
        TREATMENT_IND      8 ;
    FORMAT
        POLICY_RK        BEST12.
        POLICY_VERSION   BEST12.
        TREATMENT_IND    BEST12. ;
    INFORMAT
        POLICY_RK        BEST12.
        POLICY_VERSION   BEST12.
        TREATMENT_IND    BEST12. ;
    INFILE DATALINES4
        DLM='7F'x
        MISSOVER
        DSD ;
    INPUT
        POLICY_RK        : BEST32.
        POLICY_VERSION   : BEST32.
        TREATMENT_IND    : BEST32. ;
DATALINES4;
105000002
114000005
123000007
132000001
141000007
1508
;;;;

I'm trying to run the below code:

     %macro storno (pol_rk , pol_ver );
       PROC SQL;
            UPDATE t1
            SET POLICY_VERSION=POLICY_VERSION*3.1113
            where POLICY_RK=&pol_rk and policy_Version = &pol_ver;
       QUIT;
 %mend ;





 data _null_;
       set t1 ;

       IF input(TREATMENT_IND,best12.) eq 1  THEN do;
            call symputx("a",policy_rk);
            call symputx("b",pol_ver);
            end;
            %storno(&a, &b);



       %put a=&a;
        %put b=&b;
 run;

but get a warning message:

WARNING: Apparent symbolic reference A not resolved. WARNING: Apparent symbolic reference B not resolved. NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column). 19:21
NOTE: There were 6 observations read from the data set WORK.T1. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds

NOTE: No rows were updated in WORK.T1.

What exactly am I doing wrong here....?

2
data _null_; ...; call execute('%storno(&a, &b);'); run; -- voila!samkart

2 Answers

5
votes

CALL SYMPUTX assigns values to macro variables, but those macro variables aren't available for use until after the end of the DATA step in which they're assigned.

That's because macro language compiles before the results of the data step. So SAS sees your call to %storno(&a, &b) before it processes the DATA step to assign the macro variables &a and &b.

See the "Problem Trying to Reference..." subsection of this link for more: https://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000210266.htm

That's why you're seeing warnings about the symbolic references not being resolved - they don't exist yet when you're trying to use them.

3
votes

Another good solution to running this - often better, IMO, because there are a few weird consequences of CALL EXECUTE that can affect how macros called from it work vs. called in plain code - is SELECT INTO.

proc sql;
select cats('%storno(',policy_rk,',',pol_ver,')') into :calllist separated by ' '
from t1
where input(TREATMENT_IND,best12.) eq 1
;
quit;

&calllist;

That pulls a list of calls into a macro variable (&calllist) and then runs them in open text just as if you'd run them separately.

You also ought to unwrap the PROC SQL if possible; it's adding a bit of extra overhead to open/close PROC SQL so many times.

Remove the PROC SQL and QUIT from the macro, then call it like this:

proc sql;
&calllist;
quit;