2015-08-16 2 views
0

У меня вопрос о разрешении макропеременных в SAS. У меня есть следующий код, который является упрощенной версией гораздо большего блока. По практической причине я не могу изменить структуру кода.Разрешить переменную макроса в SAS

%let a = x1 x2 x3; 
%let b = y1 y2 y3; 
%let c = a b; 


%macro test (input); 
    %local i; 
    %let string_c = %str(&input); 
    %do i=1 %to 2; 
     %put &%qscan(&string_c, &i); /* ? */ 
    %end; 
%mend test; 

%test(&c); 

В шаге? выше, я хотел бы решить и б, как макропеременные и имею системную распечатку

x1 x2 x3 

и затем

y1 y2 y3 

Однако приведенный выше код не reslove а и Ь, как макропеременные и система распечатывает

&a 
&b 

Мне интересно, есть ли какие-либо решения этой проблемы.

Большое спасибо!

ответ

1

Попробуйте это:

%let a = x1 x2 x3; 
%let b = y1 y2 y3; 
%let c = a b; 

%macro test (input); 
    %local i; 
    %let string_c =%str(&input); 
    %do i=1 %to 2; 
     %put %unquote(&&%qscan(&string_c, &i)); 
    %end; 
%mend test; 

%test(&c); 
+1

Интересный ответ. Можете ли вы добавить какое-то объяснение, почему это работает, особенно почему% unquote() полезен здесь, даже если вы удаляете котировку с помощью% str() и% qscan(). Например, это помогает в этом простом случае: % macro x; x% исправления; % let x = 1; % put% unquote (&&%x); – Quentin

+0

Спасибо, Shenglin. Он работает! Следующий вопрос, подобный Quentin's, почему он работает :) – frostman

+0

Без% unquote, SAS интерпретирует a/b как текст плюс &, а не макро переменную & a/& b, с% unquote, принудительно склеить & и a/b вместе и восстановить нормальную токенизацию значения. –

0

Триггер & предназначен для разрешения имени, но вы использовали другой макрос триггер% вместо имени. Так оно и не делает. Легче назначить имя макрокоманде, а затем оценить ее.

%macro test(list); 
    %local i varname value; 
    %do i=1 %to %sysfunc(countw(&list,%str())); 
    %let varname=%scan(&list,&i,%str()); 
    %let value=&&&varname ; 
    %put The value of "&varname" is "&value" ; 
    %end; 
%mend test; 
%let a=One ; 
%let b=Two ; 
%test(a b); 

Какие результаты в:

The value of "a" is "One" 
The value of "b" is "Two" 
+0

Спасибо, Том. Моя проблема в том, что я должен сохранить структуру кода для практических, хотя и не разумных причин :). Поэтому я должен разрешить макропеременные a и b в цикле. – frostman

+0

Итак, как это отличается от примера, который я опубликовал? Он решает макропеременные A и B. Это просто SOOOOOOOO гораздо более управляемым, если вы сначала проанализируете имя из списка в новую макрокоманду, а затем используйте синтаксис &&& mvar для разрешения значения переменной, названной в MVAR. – Tom

+0

Спасибо, Том. Да, я согласен, что это более управляемо, если мы фактически определяем «a» и «b» в макроре, а не в самом начале. Тем не менее, мои руки полностью связаны с кодом, над которым я работаю, поскольку я должен определить a и b в самом начале из-за существующей политики ... Да здравствует бюрократия :) – frostman