Macro variables issue when using call execute
我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。
macro %TWO 需要全局变量
您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /* test data */ data dataset; name="a"; condition="1"; output; name="b"; condition=""; output; name="c"; condition="1"; output; run; data a_agg; v="a_agg"; run; data b_agg; v="b_agg"; run; data c_agg; v="c_agg"; run; data meta_table; condition="1"; name_ot="ot1"; output; condition="2"; name_ot="ot2"; output; condition=""; name_ot="ot_"; output; run; %macro one(condition); %global names_agg; %let names_agg = ; proc sql noprint; select cats(name,"_agg") into :names_agg separated by"" from dataset where condition ="&condition."; quit; %mend; %*-- just checking --*; %one(condition=1) %put names_agg=&names_agg; %one(condition=2) %put names_agg=&names_agg; %one(condition= ) %put names_agg=&names_agg; %*-- on log names_agg=a_agg c_agg names_agg= names_agg=b_agg --*; %macro two(name_ot); %if &names_agg= %then %do; data &name_ot.; run; %end; %else %do; data &name_ot.; set &names_agg.; run; %end; %mend; data _null_; length code $200; set meta_table; code = catt('%one(', condition,")"); code = catt(code, '%two(', name_ot,")"); code = catt('%nrstr(', code,")"); call execute(code); run; /* check */ title ot1; proc print data=ot1; run; title; /* on lst ot1 Obs v 1 a_agg 2 c_agg */ title ot2; proc print data=ot2; run; title; /* on log NOTE: No variables in data set WORK.OT2. */ title ot_; proc print data=ot_; run; title; /* on lst ot_ Obs v 1 b_agg */ |
您可能需要在数据步骤中将双引号更改为单引号,如下所示:
1 2 3 4 5 6 | data _null_; length code $32767; set meta_table; code = '%ONE(' || cats(condition) || '); %TWO(' || cats(Name_OT) ||");"; call execute(code); run; |
现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。
除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:
1 2 3 4 5 6 7 8 9 10 11 | %macro TheOnlyOne(condition,name_OT); proc sql noprint; select cats(name,"_agg") into :names_agg separated by"" from dataset where condition="&condition"; quit; data &name_OT; set &names_agg; run; %mend; |
无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗
- 在调用执行方法之外按顺序运行宏?
-
在执行之前设置
options mprint mlogic symbolgen; 以查看日志中的调试信息? -
在您的宏中使用一些
%put 语句,并在您的call execute 数据步中使用put 语句,以便查看在各个点生成了什么?
建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式
也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。
顺便说一句,我喜欢使用