Reference 调用执行在SAS中不工作
为什么这段代码显示错误,尽管一切都是正确的。 我正在检查数据集编号中的值,以查找它们之间的匹配 带可变数字的总计数(仅供练习) 我使用procsql得到了count,在检查了条件之后,我 我正在删除count宏变量。之后 执行SAS发出错误消息的原因。请解释一下是什么 真的发生在这段代码中Reference 调用执行在SAS中不工作,reference,macros,sas,call,execute,Reference,Macros,Sas,Call,Execute,为什么这段代码显示错误,尽管一切都是正确的。 我正在检查数据集编号中的值,以查找它们之间的匹配 带可变数字的总计数(仅供练习) 我使用procsql得到了count,在检查了条件之后,我 我正在删除count宏变量。之后 执行SAS发出错误消息的原因。请解释一下是什么 真的发生在这段代码中 data numbers; input num; datalines; 3 1 3 ; run; %macro temp(num); proc sql noprint;
data numbers;
input num;
datalines;
3
1
3
;
run;
%macro temp(num);
proc sql noprint;
select count(*) into :count from numbers;
quit;
%if (&num eq &count) %then
%put Match Found;
%else
%put No Match Found;
%symdel count;
%mend;
data _NULL_;
set numbers;
call execute('%temp('||num||')');
run;
从调用中引用for execute:
注意:因为宏引用立即执行,SAS
语句在步骤边界之后才会执行,您不能使用
调用EXECUTE以调用包含宏引用的宏
由该宏中的CALL SYMPUT创建的变量
我认为您在这里尝试做的基本上是相同的事情,只是在宏中使用proc-sql
的select-into
,而不是call-symput
绕过此限制的一种方法是使用dosubl
功能。您可以使用它来创建一个函数式宏,然后可以通过call execute
生成的%put
语句运行该宏:
LOG-----when I execute the last data step--------->
6188 data _NULL_;
6189 set numbers;
6190 call execute('%temp('||num||')');
6191 run;
NOTE: Numeric values have been converted to character values at the places given by:
(Line):(Column).
6190:24
Match Found
WARNING: Apparent symbolic reference COUNT not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: &num eq &count
ERROR: The macro TEMP will stop executing.
WARNING: Apparent symbolic reference COUNT not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: &num eq &count
ERROR: The macro TEMP will stop executing.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: There were 3 observations read from the data set WORK.NUMBERS.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
NOTE: CALL EXECUTE generated line.
1 + proc sql;
1 + select count(*) into :count from numbers;
1 + quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.09 seconds
cpu time 0.00 seconds
2 + proc sql;
2 + select count(*) into :count from numbers;
2 + quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.15 seconds
cpu time 0.01 seconds
3 + proc sql;
3 + select count(*) into :count from numbers;
3 + quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.15 seconds
cpu time 0.01 seconds
或者,您可以将dosubl
调用放在数据步骤中,而不是放在宏定义中:
data numbers;
input num;
datalines;
3
1
3
;
run;
%symdel COUNT;
%macro temp(num);
%sysfunc(dosubl(proc sql noprint;
select count(*) into :count from numbers;
quit;))
%if &num eq &count %then
%put Match Found;
%else
%put No Match Found;
%mend;
data _NULL_;
set numbers;
count = symget('Count');
put "Before call execute " _n_= count=;
call execute('%put rc=%temp('||num||');');
count = symget('Count');
put "After call execute " _n_= count=;
run;
当CALL EXECUTE()语句运行时,代码被推送到堆栈上。由于没有使用任何宏引用,因此宏实际上正在运行,生成的代码被推送到堆栈上。因此%IF语句在SELECT语句运行之前运行。您可以使用%NRSTR()延迟此操作,以便将宏调用推送到堆栈上
%symdel COUNT;
%macro temp(num);
proc sql noprint;
select count(*) into :count from numbers;
quit;
%if &num eq &count %then
%put Match Found;
%else
%put No Match Found;
%mend;
data _NULL_;
set numbers;
count = symget('Count');
put "Before call execute " _n_= count=;
rc = dosubl('%temp('||num||')');
count = symget('Count');
put "After call execute " _n_= count=;
run;
或者只需避免调用EXECUTE并使用PUT语句将代码写入可以包含的文件
call execute(cats('%nrstr(%temp)(',num,')'));
建议您使用“OPTIONS MLOGIC;”查看要传递TEMP宏的参数,并从中进行调试。汤姆的回答也有帮助吗?如果是,请选择它作为答案。
filename code temp;
data _null_;
set numbers;
file code ;
put '%temp(' num ')' ;
run;
%include code / source2 ;