SAS中PROC FCMP函数返回空值问题求助及代码修正
SAS问题:PROC FCMP调用宏计算分组总和返回空值的修正
问题说明
在SAS中尝试通过PROC FCMP创建函数,结合TAB_PARAM和SOURCE数据集,调用宏计算对应CAT_A、CAT_B分组的VALUE总和,但函数始终返回空值,需要修正代码以生成正确的TAB_PARAM_BIS表。
原始代码
DATA TAB_PARAM; infile cards delimiter=','; input CAT_A $ CAT_B $ ; cards; AA1,XXX BB1,YYY CC1,ZZZ ; run; DATA SOURCE; infile cards delimiter=','; input CAT_A $ CAT_B $ VALUE; cards; AA1,XXX,200 AA1,XXX,500 AA1,ZZZ,800 BB1,YYY,100 BB1,YYY,300 BB1,ZZZ,700 CC1,XXX,900 CC1,ZZZ,600 CC1,ZZZ,400 ; run; %macro extraction(ca,cb); proc sql noprint; select distinct sum(value)as value into: val from source where CAT_A in ("&ca.") and CAT_B in ("&cb.") ; quit; %put val=&val.; %mend; %extraction(AA1,XXX); PROC FCMP OUTLIB=work.funcs.sql; FUNCTION calc(ca $,cb $) ; rc = RUN_MACRO('extraction',ca,cb,val); RETURN(val); ENDSUB; run; OPTIONS cmplib = work.funcs; data _null_; ca='BB1'; cb='YYY'; val=calc(ca,cb) ; run; OPTIONS cmplib = work.funcs; DATA TAB_PARAM_BIS; SET TAB_PARAM; val=calc("CAT_A" , "CAT_B"); RUN;
期望结果
CAT_A CAT_B val ------------------- AA1 XXX 700 BB1 YYY 400 CC1 ZZZ 1000
实际结果
CAT_A CAT_B val ------------------- AA1 XXX . BB1 YYY . CC1 ZZZ .
修正方案及完整代码
DATA TAB_PARAM; infile cards delimiter=','; input CAT_A $ CAT_B $ ; cards; AA1,XXX BB1,YYY CC1,ZZZ ; run; DATA SOURCE; infile cards delimiter=','; input CAT_A $ CAT_B $ VALUE; cards; AA1,XXX,200 AA1,XXX,500 AA1,ZZZ,800 BB1,YYY,100 BB1,YYY,300 BB1,ZZZ,700 CC1,XXX,900 CC1,ZZZ,600 CC1,ZZZ,400 ; run; %macro extraction(ca, cb, out_val); proc sql noprint; select sum(value) into: &out_val. trimmed from source where CAT_A = "&ca." and CAT_B = "&cb."; quit; %put &out_val. = &&&out_val..; %mend; PROC FCMP OUTLIB=work.funcs.sql; FUNCTION calc(ca $, cb $) NUMERIC; DECLARE num val; rc = RUN_MACRO('extraction', ca, cb, val); RETURN(val); ENDSUB; run; OPTIONS cmplib = work.funcs; data _null_; ca='BB1'; cb='YYY'; val=calc(ca,cb) ; put val=; run; DATA TAB_PARAM_BIS; SET TAB_PARAM; val=calc(CAT_A, CAT_B); RUN;
修正要点解释
宏参数优化
- 新增
out_val参数指定存储结果的宏变量名,避免依赖全局宏变量,确保FCMP调用时结果能正确传递 - 移除多余的
distinct(sum()本身是聚合函数,无需去重),添加trimmed去除结果空格 - 将
in条件改为直接等于=,适配单个分组值的匹配场景,提升效率
- 新增
FCMP函数调整
- 显式声明函数返回类型为
NUMERIC,确保类型匹配 - 用
DECLARE num val;初始化函数内部变量,避免未赋值导致的空值 - 明确
RUN_MACRO的输出参数为val,让宏将计算结果直接赋值给该变量
- 显式声明函数返回类型为
DATA步调用修正
- 在
TAB_PARAM_BIS的DATA步中,直接传递变量CAT_A和CAT_B给calc函数,而非带引号的字符串,确保传递的是实际分组值
- 在
内容的提问来源于stack exchange,提问作者newcomer2025
相关产品推荐
相关产品推荐

