Reference 调用执行在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;

为什么这段代码显示错误,尽管一切都是正确的。 我正在检查数据集编号中的值,以查找它们之间的匹配 带可变数字的总计数(仅供练习) 我使用procsql得到了count,在检查了条件之后,我 我正在删除count宏变量。之后 执行SAS发出错误消息的原因。请解释一下是什么 真的发生在这段代码中

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 ;