我有以下宏:
%macro regex_builder;
%do i = 1 %to 11;
data _null_;
a = &i.;
call symputx('Var', a, 10.);
run;
proc sql noprint;
select Regex into :regex_string_&Var
from Regex
where monotonic() = &i.;
quit;
%put &®ex_string_&Var;
%end;
%mend;
%regex_builder;
这样做的目的是循环遍历数据集的行,并将其中包含的值分配给一系列宏变量,即regex_string_1
,regex_string_2
等。
所需数据被分配给某种宏变量,就像我使用%put &®ex_string_&Var;
时一样,我以正确的顺序获取一系列宏变量字符串,并从我的源数据集生成。
但是,当我尝试解决使用上述regex_string_1
,regex_string_2
等命名约定创建的宏变量时,我收到一条警告,说明这些宏变量名称尚未声明。
我想知道的是:
1)为什么我的上面的代码没有按预期工作 2)如何将由上述其他宏变量组成的宏变量名称的已解析名称打印到SAS日志中?
由于
答案 0 :(得分:3)
宏变量具有范围',本地或全局。宏中第一次初始化的宏变量默认为本地范围。这意味着您无法解析宏之外的值。
你可以a)最初在宏之外定义宏变量,或者b)在宏中指定它为%GLOBAL
。
%MACRO MYMACRO ; %LET X = 1 ; %MEND ; %MYMACRO ; %PUT &X ; /* not resolved as X is local to %MYMACRO */ /* Method A */ %LET X = ; %MACRO MYMACRO ; %LET X = Hello ; %MEND ; %MYMACRO ; %PUT &X ; /* Resolves to Hello */ /* Method B */ %MACRO MYMACRO ; %GLOBAL X ; %LET X = Hello ; %MEND ; %MYMACRO ; %PUT &X ; /* Resolves to Hello */
因此,要解决您的具体问题,只需添加即可
在%GLOBAL &®ex_string_&Var ;
步之前PROC SQL
。
答案 1 :(得分:1)
编辑:好的,在阅读了Chris J的回答后,我意识到问题究竟是什么:)。
无论如何,我会将此代码保留在此处,因为它更简单,更有效地完成您想要的操作。
在你的代码中你需要调用proc sql n次,其中n是观察数。实际上,您只需要一个datastep而不需要宏。见下面的步骤1:
data y;
input regex $;
datalines;
Hello
world
this
is
an
example
;
run;
/* 1) in the datasteps rows are looped automatically, no macro needed here */
data _null_;
set y;
call symputx(cats("regex_string_",_N_),regex);
run;
/* example */
%put ®ex_string_4;
proc sql noprint;
select count(*) into :n from y;
quit;
/* 2) This is how you refer to a macro variable by another macro variable */
%macro printall;
%do i = 1 %to &n;
%put &®ex_string_&i;
%end;
%mend;
%printall;