希望可以清楚地解释这一点。我使用SAS 8.2(它是我公司使用的)并尝试获取在create_var宏中创建的名为& op_var_name的变量名称。每次运行run_loops宏时,这都会更改。例如,它将根据ds_split_list数据集创建list_detail1,list_detail2和list_detail3。我需要在代码中稍后使用这些变量,我似乎无法使其工作。我尝试在run_loops和create_var宏中添加%global& op_var_name。日志在run_loop部分显示带有数据的变量,但是当引用变量时,日志在代码中显示为空白。
%macro create_var(ds_in=, item_to_list=, op_var_name=);
data &op_var_name;
set &ds_in end=eof;
length gen_list $30000.;
retain gen_list;
if not eof then do;
gen_list=trim(left(gen_list))||"'"||trim(left(&item_to_list))||"'"|| ",";
end;
if eof then do;
gen_list=trim(left(gen_list))||"'"||trim(left(&item_to_list))||"'";
call symput("gen_name",trim(left(gen_list)));
output;
end;
run;
%put &op_var_name=&gen_name ;
%mend create_var;
data _null_;
set ds_split_list;
call symput ('nobs', _n_);
call symput ('ds_feed'||left(_n_),memname);
call symput ('item_to_list', 'lotlabel');
call symput ('op_var_name'||left(_n_), 'list_detail'||left(_n_));
run;
%macro run_loops;
/* &nobs and all the "&&var&i" variables defined above */
%do i = 1 %to &nobs;
%create_var(ds_in=&&ds_feed&i, item_to_list=&&item_to_list, op_var_name=&&op_var_name&i);
%end;
%mend run_loops;
%run_loops;
/* Later in the code is where I reference the variable created above. */
%get_oper(list=&list_detail1);
谢谢!
编辑:我最终使用了汤姆的回应中的这个选项。
或者,当在子宏中创建变量时,可以使变量成为全局变量。
%global &op_var_name;
%let &op_var_name=&gen_name ;
答案 0 :(得分:2)
您似乎有拼写错误和逻辑错误。错误是您的内部宏具有%PUT
语句而不是%LET
语句。因此,唯一的宏变量是名为GEN_NAME
的宏变量,而不是以分析变量命名的变量。所以把它改成这一行。
%let &op_var_name=&gen_name ;
您遇到的逻辑问题是您对新宏变量的初始引用位于内部宏内部,因此默认情况下它变为局部并在宏结束时消失。您可以在调用宏之前先定义宏变量。
%let &&op_var_name&i=;
%create_var(ds_in=&&ds_feed&i, item_to_list=&&item_to_list, op_var_name=&&op_var_name&i);
或者,您可以在子宏中创建变量全局变量。
%global &op_var_name;
%let &op_var_name=&gen_name ;
您甚至可以使用CALL SYMPUTX()
执行此操作并消除额外的GEN_NAME宏变量。
call symputx("&op_var_name",gen_list,'global');
除了宏变量之外,您真的需要所有这些单独的数据集吗?为什么不直接从输入数据集创建宏变量而不创建另一个数据集?
proc sql noprint ;
select "'"||trim(left(&item_to_list))||"'"
into :&op_var_name separated by ','
from &ds_in
;
quit;
答案 1 :(得分:0)
宏变量范围。如果要在宏之外使用,则声明为全局。调用symputx有第三个参数来指定范围。