2016-04-04 3 views
0

Надеюсь, это может объяснить это ясно. Я использую SAS 8.2 (это то, что использует моя компания) и пытается получить имя переменной & op_var_name, созданное в макросе create_var. Это изменяется при каждом запуске макроса run_loops. Например, он создаст list_detail1, list_detail2 и list_detail3 на основе набора данных ds_split_list. Мне нужно использовать эти переменные позже в коде, я не могу заставить его работать. Я попытался добавить% global & op_var_name в run_loops и макрос create_var. Журнал показывает переменную с данными в разделе run_loop, но затем журнал показывает пробел позже в коде при ссылке на переменную.SAS вложенный макрос, как использовать переменную вне макроса

%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); 

Спасибо!

EDIT: В итоге я использовал эту опцию из ответов Тома.

Или вы можете сделать переменную global, когда она создана в под макро.

%global &op_var_name; 
%let &op_var_name=&gen_name ; 

ответ

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, когда она создана в под макро.

%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; 
+0

Я обновил свой пост, но забыл сказать, что использую SAS 8.2. Это выдает опцию symputx. Опция% let не работает, если я не сделал что-то неправильно. Вопрос, который у меня есть, когда у вас есть% let перед макросом% create_var, это то, что я тоже установил? Мне нравится sql-параметр, но для внесения изменений в код, который я не опубликовал, потребуется больше. – Tony

+0

Даже в 8.2 вы должны иметь возможность объявить макро-вары с глобальной областью. Добавьте в начало вашего макроса: '% GLOBAL op_var_name;' – Jetzler

+0

Добавлен пример '% GLOBAL' для ответа. – Tom

0

Макросменная область. Объявите глобальным, если вы хотите использовать вне макроса. Вызов symputx имеет третий параметр, определяющий область.

Смежные вопросы