SAS 宏函数与数据步函数
SAS Macro Functions vs Data Step Functions
我在解析宏中的宏变量时遇到问题。我认为问题在于语言,以及 SAS 如何将我的语句发送到宏处理器与编译器。
这是我的代码的要点:
....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 %THEN 语句%IF %SYSFUNC(STRIP(&EQBEF.)) ~= %SYSFUNC(STRIP(&EQAFTER.)) %THEN %DO;
我可以从日志中看到 SAS 正在抽出从我的数据步骤创建数据集之前出错,我相信 &EQBEF
解决的原因是因为它是使用 PROC UPLOAD;
创建的
如果是这样,我如何才能阻止 SAS 在处理数据步之前执行第二个 %IF %THEN,因为我在 proc sql;
中的第二个 select
语句取决于数据步的执行。
此外,我无法在 proc sql;
中解析我的日期变量
例如
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 ;
但是 &DATE。不会在该 proc sql 语句中解析,但在我的所有 libname 语句等中解析得很好。关于为什么 &date.不会在 PROC SQL 内解析?.....我是否需要在参数列表中引用宏中使用的每个变量?
您的宏在您的本地 SAS 会话中 运行ning,但是由于 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;
如果您 运行 在打开 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 语句 运行 并显示本地宏变量的值。
检查第二个日志select
select count(*) as EQA format=10.0 INTO :EQAFTER from trunc_fin_eq ;
如果该数据集不存在,则不会创建宏变量。
您可以将其设置为0来初始化它:
%let EQAFTER=0;
我在解析宏中的宏变量时遇到问题。我认为问题在于语言,以及 SAS 如何将我的语句发送到宏处理器与编译器。
这是我的代码的要点:
....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 %THEN 语句%IF %SYSFUNC(STRIP(&EQBEF.)) ~= %SYSFUNC(STRIP(&EQAFTER.)) %THEN %DO;
我可以从日志中看到 SAS 正在抽出从我的数据步骤创建数据集之前出错,我相信 &EQBEF
解决的原因是因为它是使用 PROC UPLOAD;
如果是这样,我如何才能阻止 SAS 在处理数据步之前执行第二个 %IF %THEN,因为我在 proc sql;
中的第二个 select
语句取决于数据步的执行。
此外,我无法在 proc sql;
中解析我的日期变量例如
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 ;
但是 &DATE。不会在该 proc sql 语句中解析,但在我的所有 libname 语句等中解析得很好。关于为什么 &date.不会在 PROC SQL 内解析?.....我是否需要在参数列表中引用宏中使用的每个变量?
您的宏在您的本地 SAS 会话中 运行ning,但是由于 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;
如果您 运行 在打开 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 语句 运行 并显示本地宏变量的值。
检查第二个日志select
select count(*) as EQA format=10.0 INTO :EQAFTER from trunc_fin_eq ;
如果该数据集不存在,则不会创建宏变量。
您可以将其设置为0来初始化它:
%let EQAFTER=0;