Macros 迭代宏变量并将值分配给它们

Macros 迭代宏变量并将值分配给它们,macros,sas,Macros,Sas,我有以下宏: %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 &&regex_s

我有以下宏:

%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 &&regex_string_&Var;

%end;
%mend;

%regex_builder;
其目的是循环数据集的行,并将其中包含的值分配给一系列宏变量,即
regex\u string\u 1
regex\u string\u 2

当我使用
%put&®ex\u string\uvar我正在以正确的顺序获取一系列宏变量字符串,这些字符串是从我的源数据集生成的

但是,当我尝试解析使用上述命名约定创建的宏变量时,
regex_string_1
regex_string_2
等,我收到一条警告,指出这些宏变量名称尚未声明

我想知道的是:

1) 为什么我上面的代码没有按预期工作 2) 如何将由上述其他宏变量组成的宏变量名称的解析名称打印到SAS日志中


谢谢

编辑:好的,读了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 &regex_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 &&regex_string_&i;
    %end;
%mend;
%printall;

编辑:好的,在读了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 &regex_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 &&regex_string_&i;
    %end;
%mend;
%printall;

宏变量具有“作用域”,可以是局部变量,也可以是全局变量。默认情况下,在宏中首次初始化的宏变量在作用域中是局部变量。这意味着您无法解析宏之外的值

%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 */ 您可以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 */ %宏MYMACRO; %设X=1; %修补; %MYMACRO; %放置&X;/*未解析,因为X是%MYMACRO的本地*/ /*方法A*/ %设X=; %宏MYMACRO; %让X=你好; %修补; %MYMACRO; %放置&X;/*我决定打招呼*/ /*方法B*/ %宏MYMACRO; %全球X; %让X=你好; %修补; %MYMACRO; %放置&X;/*我决定打招呼*/ 因此,要解决您的具体问题,只需添加
%GLOBAL&®ex\u string\uvar在执行
PROC SQL
步骤之前。

宏变量有一个“范围”,可以是局部的,也可以是全局的。默认情况下,在宏中首次初始化的宏变量在作用域中是局部变量。这意味着您无法解析宏之外的值

%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 */ 您可以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 */ %宏MYMACRO; %设X=1; %修补; %MYMACRO; %放置&X;/*未解析,因为X是%MYMACRO的本地*/ /*方法A*/ %设X=; %宏MYMACRO; %让X=你好; %修补; %MYMACRO; %放置&X;/*我决定打招呼*/ /*方法B*/ %宏MYMACRO; %全球X; %让X=你好; %修补; %MYMACRO; %放置&X;/*我决定打招呼*/ 因此,要解决您的具体问题,只需添加
%GLOBAL&®ex\u string\uvar在您的
过程SQL
步骤之前。

该死,我就知道!我想我今天早上喝的咖啡不够。谢谢你的帮助。该死,我就知道!我想我今天早上喝的咖啡不够。谢谢你的帮助。