1
votes

I have the following macro:

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

The purpose of this is to loop through the rows of a dataset and assign the values contained within to a series of macro variables i.e. regex_string_1, regex_string_2 etc.

The required data is being assigned to a macro variable of some sort as when I use %put &&regex_string_&Var; I am getting a series of macro variable strings in the correct order and generated from the my source dataset.

However, when I try and resolved the macro variables created with the above naming convention of regex_string_1, regex_string_2 etc I get a warning saying that these macro variable names have not been declared.

What I would like to know is:

1) Why is my code above not working as intended 2) How can I print the resolved name of a macro variable name made up from other macro variables as above to the SAS log?

Thanks

2

2 Answers

3
votes

Macro variables have a 'scope', either local or globally. Macro variables initialised for the first time within a macro, are local in scope by default. This means you can't resolve the value outside of the macro.

You can either a) define the macro variable outside of the macro initially, or b) specify it as %GLOBAL within the macro.

%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 */

So, to address your specific issue, simply add %GLOBAL &&regex_string_&Var ; before your PROC SQL step.

1
votes

Edit: Okay after reading Chris J's answer I realized what the problem actually was :).

Anyway I will leave this code here because it's simpler and much more effecient way to do the thing you want.

In your code you need to call proc sql n times where n is the number of observations. In fact you need only one datastep and no macro at all. See step 1 below:

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;