2017-02-22 73 views
0

我在宏中解析宏变量时遇到问题。我认为问题在于语言,以及SAS如何将语句发送到宏处理器与编译器。SAS宏函数与数据阶跃函数

这里是我的代码JIST:

....some import statements... 
%MACRO FCERR(date=); 

%LET REMHOST=MainFrame PORT; 
SIGNON REMHOST USER=&SYSUSERID. PASSWORD= _PROMPT_; 

    %SYSLPUT date=&yymm. ; 

RSUBMIT; 

      FILENAME FIN "MY.FILE.QUALIFIERS" DISP = shr; 

      ......some datasteps...... 

       LIBNAME METRO "My.File.Qualifiers" DISP=shr; 
/******************************************************************** 

         ******* ********* 
         **  **  ** 
         ******* ** * ** 
         **  ** * ** 
         ******* ********* 
              * 
/*******************************************************************/ 

%IF %SYSFUNC(EXIST(work.EQ_&date._FIN)) %THEN %DO; 

      PROC UPLOAD Data = work.EQ_&date._FIN 
         OUT = work.EQ_&date._FIN; 

..........a bunch of data steps.................. 

PROC SQL NOPRINT ; 
     select count(*) as EQB format=10.0 INTO :EQBEF from EQ_1701_FIN ; 
     select count(*) as EQA format=10.0 INTO :EQAFTER from trunc_fin_eq ; 
QUIT ; 

%PUT &EQBEF; 
%PUT &EQAFTER; 

%IF %SYSFUNC(STRIP(&EQBEF.)) ~= %SYSFUNC(STRIP(&EQAFTER.)) %THEN %DO; 

options emailhost= MYEMAILHOST.ORG ; 
filename mail email ' ' 
to= (&recip.) 
subject = "EQ Error QA/QC"; 

DATA _NULL_; 
file mail ; 
put "There were potential errors processing the Equifax Error file."; 
put "The input dataset contains %SYSFUNC(STRIP(&EQBEF.)) observations."; 
put "The output dataset contains %SYSFUNC(STRIP(&EQAFTER.)) observations."; 
put "Please check the SAS log for additional details."; 
RUN; 

%END; 

%END; 

%ENDRSUBMIT; 
%SIGNOFF; 

%MEND; 

%FCERR(date=&yymm.); 

我不断收到正在从处理停止我的宏出现错误。这是它:

>   SYMBOLGEN: Macro variable EQBEF resolves to  24707 
>   24707 
>   MLOGIC(FCERR): %PUT &EQAFTER 
>   WARNING: Apparent symbolic reference EQAFTER not resolved. 
>   &EQAFTER 
>   SYMBOLGEN: Macro variable EQBEF resolves to  24707 
>   WARNING: Apparent symbolic reference EQAFTER not resolved. 
>   WARNING: Apparent symbolic reference EQAFTER not resolved. 
>   ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric 
>     operand is required. The condition was: %SYSFUNC(STRIP(&EQBEF.)) ~= 
>     %SYSFUNC(STRIP(&EQAFTER.)) 
>   ERROR: The macro FCERR will stop executing. 

问题:是SAS试图处理我的第二个(即内部)%IF%,那么声明它编译和执行上述%IF %SYSFUNC(STRIP(&EQBEF.)) ~= %SYSFUNC(STRIP(&EQAFTER.)) %THEN %DO;数据步骤,我可以从日志SAS是抽看之前出它正在创建从我datasteps数据集之前,我相信&EQBEF被解决的原因是因为它使用PROC UPLOAD;

如果是这样产生的错误,我怎样才能防止SAS从IF%,那么直到执行第二%数据处理将被处理,因为proc sql;中的第二条select声明依赖于数据安全执行。

此外,我无法让我的日期变量在proc sql中解析;

E.G.

PROC SQL NOPRINT ; 
     select count(*) as EQB format=10.0 INTO :EQBEF from EQ_1701_FIN ; 
     select count(*) as EQA format=10.0 INTO :EQAFTER from trunc_fin_eq ; 
QUIT ; 

理想的是:

PROC SQL NOPRINT ; 
     select count(*) as EQB format=10.0 INTO :EQBEF from EQ_&DATE._FIN ; 
     select count(*) as EQA format=10.0 INTO :EQAFTER from trunc_fin_eq ; 
QUIT ; 

但&日期。不会在那个proc sql语句中解析,但是在我所有的libname语句中都可以很好地解决,等等。为什么&日期有一些意外情况。在PROC SQL中不能解析?.....我需要在参数列表中引用的宏中使用每个变量吗?

回答

1

您的宏正在本地SAS会话中运行,但由于RSUBMIT;ENDRSUBMIT;语句,正在生成宏变量的SQL代码正在远程SAS会话上运行,但宏语句正在引用本地宏变量。

例如尝试这个简单的程序,它创建一个本地和一个远程宏变量,并尝试显示值。

signon rr sascmd='!sascmd'; 
%let mvar=Local ; 
%syslput mvar=Remote ; 
%put LOCAL &=mvar; 
rsubmit rr; 
%put REMOTE &=mvar ; 
endrsubmit; 
signoff rr; 

如果你在open SAS中运行它,%PUT语句将显示MVAR分别等于LOCAL和REMOTE。

但是你换一个宏内部运行它

%macro xx; 
signon rr sascmd='!sascmd'; 
%let mvar=Local ; 
%syslput mvar=Remote ; 
%put LOCAL &=mvar; 
rsubmit rr; 
%put REMOTE &=mvar ; 
endrsubmit; 
signoff rr; 
%mend xx; 
options mprint; 
%xx; 

你会看到,无论%PUT语句在本地服务器上运行,并显示当地的宏观变量的值。

+0

阅读这几次之后,我明白了这个问题,以及如何解决它。我所做的是在Rsubmit中使用'PROC SQL SELECT COUNT(*)'语句,使用'%SYSRPUT'将远程服务器上的值赋给本地服务器上的值,然后处理我的'%IF%THEN'语句本地。我确实有一个问题,'%let mvar = Local'的目的是什么,然后像'%put LOCAL &=mvar;'那样引用它?我很困惑'LOCAL &=mvar;'一块。 '&=';是什么意思?我从未见过以这种方式构建的东西...... – DukeLuke

+1

'%put&= mvar'是'%put MVAR =&mvar'的新缩写。我添加了额外的文本LOCAL和REMOTE到%put,这样你就可以知道哪条语句在日志中生成了该行。 – Tom

0

检查日志第二选择

select count(*) as EQA format=10.0 INTO :EQAFTER from trunc_fin_eq ; 

如果数据集不存在,宏变量将不会被创建。

可以将其设置为0,将其初始化:

%let EQAFTER=0;