两个SAS程序报错求助:%EVAL字符操作数问题与宏引用未解析
问题1:宏%IF中IN运算符报错
错误原因
SAS宏处理器的%IF语句默认用%EVAL处理条件,而%EVAL不支持IN运算符,会把IN识别成字符常量,触发"需要数值操作数但找到字符操作数"的错误。
修正代码
用%SYSFUNC调用SAS内置的IN()函数实现成员判断,这是宏环境下支持IN逻辑的正确方式:
%macro Execution; %if (%sysfunc(in(%sysfunc(weekday(%sysfunc(today()))), 2, 3, 4, 5, 6, 7)) and %sysfunc(in(%sysfunc(day(%sysfunc(today()))), 1, 2, 3)) ) %then %do; %put "The program is running"; %end; %else %do; %put "No execution necessary."; %end; %mend Execution; %Execution;
说明
%sysfunc(in(值, 列表))会返回1(值存在于列表)或0(不存在),完全符合宏逻辑的数值判断要求,替代原生IN运算符即可解决类型错误。
问题2:宏变量未解析及日期参数错误
错误原因
- 原SQL的
CASE语句会返回两行结果(对应两个目标表),但INTO :modified_CONTRAT, :modified_TCHOBQ默认仅提取第一行的两个值,导致第二个宏变量无法正确获取目标表的日期; - 当
CASE不匹配条件时返回缺失值.,若对应宏变量未被赋值,会出现"符号引用未解析"警告,后续%sysfunc(day())因参数为缺失值或未解析的宏引用报错。
修正代码
用聚合函数MAX()结合CASE,把两个表的日期值合并到同一行,确保INTO能正确赋值两个宏变量:
proc sql; select max(case when libname = 'LS' and memname = 'CONTRAT' then datepart(modate) else . end) as contrat_dt, max(case when libname = 'KO' and memname = 'TCHOBQ' then datepart(modate) else . end) as tchobq_dt into :modified_CONTRAT, :modified_TCHOBQ from dictionary.tables where libname in ('LS', 'KO') and memname in ('CONTRAT', 'TCHOBQ'); quit; %put %sysfunc(day(&modified_CONTRAT.)) ; %put %sysfunc(day(&modified_TCHOBQ.)) ;
说明
MAX(CASE...)会筛选出对应表的有效日期值(自动忽略缺失值),确保每个宏变量都能拿到目标表的日期数值;- 若目标表不存在,宏变量会被赋值为缺失值
.,此时可提前添加判断避免报错:%if &modified_CONTRAT. ne . %then %put %sysfunc(day(&modified_CONTRAT.)) ; %else %put "Table LS.CONTRAT not found or no modate.";
内容的提问来源于stack exchange,提问作者nadal
相关产品推荐
相关产品推荐

