在内部运行宏_NULL_

时间:2013-12-23 10:56:46

标签: sas

我有这些数据, 我想使用宏

更新某个表
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
;;;;

我正在尝试运行以下代码:

     %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;

但收到警告信息:

警告:未解析显式符号引用A. 警告:未解析表观符号引用B. 注意:数字值已在以下位置转换为字符值:(行):(列)。       19:21
注意:从数据集WORK.T1中读取了6个观察值。 注意:使用的DATA语句(总处理时间):       实时0.00秒       cpu时间0.00秒

注意:WORK.T1中没有更新任何行。

我到底做错了什么......?

2 个答案:

答案 0 :(得分:5)

CALL SYMPUTX为宏变量赋值,但是这些宏变量在分配它们的DATA步骤结束之后才可用。

那是因为宏语言在数据步骤结果之前编译。因此SAS在处理DATA步骤之前会看到您对%storno(&a, &b)的调用,以分配宏变量&a&b

有关详情,请参阅此链接的“试图引用的问题...”小节:https://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000210266.htm

这就是为什么你看到关于符号引用未被解决的警告 - 当你试图使用它们时它们还不存在。

答案 1 :(得分:3)

运行它的另一个好方法 - 通常更好,IMO,因为CALL EXECUTE有一些奇怪的后果会影响从它调用的宏的工作方式与普通代码中调用的方式 - 是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;

将一个调用列表拉入一个宏变量(& calllist),然后以打开的文本运行它们,就好像你单独运行它们一样。

如果可能,您还应该打开PROC SQL;它为开启/关闭PROC SQL添加了一些额外的开销。

从宏中删除PROC SQL和QUIT,然后像这样调用它:

proc sql;
&calllist;
quit;