我有这些数据, 我想使用宏
更新某个表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中没有更新任何行。
我到底做错了什么......?
答案 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;