Macro Variables Scopes

Reply
Contributor
Posts: 27

Macro Variables Scopes

Friends, I have a bit confusion between macro variables scope. I am aware that they are either local or global but have confusion with their declaration in code. Examples are provided below :

1) %LET A ;

%MACRO XYZ;

.......

%MEND;

2) %MACRO XYZ;

    %LET A;

%MEND;

WHAT ARE THE SCOPES OF MACRO VARIABLE A IN BOTH 1 AND 2 CASES. IF YOU SAY THAT INTHE 1ST CASE A IS GLOBAL AND IN 2ND A IS LOCAL THEN WHAT IS THE USED OF DECLARING IT AS %LOCAL AND %GLOBAL IN THE CODE ?

NEEDS YOUR HELP GUYS !!!

Trusted Advisor
Posts: 1,131

Re: Macro Variables Scopes

Hi,

It all depends on where the macro variable is created and where is it storing its value. if the macro variable is created in the open code, then its scope is global, as the macro variable value is stored in global symbol table.

if the macro variable is created within the macro, then its scope is local, the values are stored in the local symbol table and these values are available only till the macro is processed.

However you can still control the storage of the macro variable values, using the %global and %local statements.

You can create the macro variable within a macro and still you can store its values in the global symbol table. Please check the example below

%macro test;

%global var;

%let var=1;

%mend;

In the above code we have created a macro variable var with value 1, if %global is skipped, the macro variable will be stored in local symbol table and its scope is local.

However if you use %global followed by the macro variable name, we are asking sas to store the macro variable var in global symbol table and its scope is global.

Hope this information has helped you.

Thanks,

Jagadish

Thanks,
Jag
Super Contributor
Posts: 276

Re: Macro Variables Scopes

Hi Rohit.

Hope you got clarified with Jagadish Reply and i would like to add some more info regarding Marco variable Scope.

Hi ,

As you mentioned in post "if %global is skipped, the macro variable will be stored in local symbol table and its scope is local" is not always correct..

In some case Even if you skip the %global while creating macro variable with in the macro ,still that macro variable becomes global..

Feeling Strange??

Take a look on bellow code.

%Let A=100;

%macro Test;

%Let A=200;

%mend;

%Test;

%Put &A;

What value we expect in log??

100 right??(Because we skipped %Global in Test Macro),But the value stored in A is 200.

So what i want to conclude is

"While creating Local Macro variable ,make sure that same macro variable name not exist in global macro variable list.then only the macro variable becomes Local".

In Some case If you want to create global and local macro variable with the Same name,that time %local comes into the picture.

Like ..

%Let A=100;

%macro Test;

%Local A;

%Let A=200;

%mend;

%Test;

Thanks &Regards.

Sanjeev.K

Trusted Advisor
Posts: 1,131

Re: Macro Variables Scopes

Hi Sanjeev,

I agree with you, if you are using the same macro variable name outside and inside the macro, The open macro variable will be stored in the global symbol table. The closed macro variable will also create a local macro variable, and its values will be constant, it will not change as it will be available only till the macro session last. Where as since we are using the same variable name, that is already present in the global symbol table its value will be replaced.

So here the macro variable names play a crucial role in determining the values.

Thanks for the information.

Regards,

Jagadish

Thanks,
Jag
Contributor
Posts: 27

Re: Macro Variables Scopes

Yes, you are right. Local replaces global. so in order to stop local value over riding global value, use %local within in the macro. But what if global macro variable is not declared and with in the macro macro variable is defined with %let.

%macro test;

%let a;

%mend;

will this code give error as it does not have any global macro variable by name (a) to replace value with or it will declare a as local macro variable ????

Super Contributor
Posts: 276

Re: Macro Variables Scopes

Hi Rohit..

If you create A macro variable with in the macro,it always become a Local Variable(except one Situation which i mentioned in recent Post) even if you don't mention %Local.

thanks

Sanjeev.K

Trusted Advisor
Posts: 1,131

Re: Macro Variables Scopes

Hi Rohit,

As i said in my email earlier,

The local macro variable will be available only till the macro session last. so its values will always remain constant, it will not change, it will be the values what you have mentioned within the macro.


Thanks,

Jagadish

Thanks,
Jag
Super Contributor
Posts: 644

Re: Macro Variables Scopes

Additional information

  • A macro variable created in open code (ie not in a macro) will always be global.
    • Using %Local in open code will result in an error
  • A macro variable created within a macro will by default be local, but there are exceptions
    • Parameters in the macro declaration are always local, an attempt to global them will result in error
      • Example: %Macro foobar (a, z) ;  - &a and &z will be local within the macro even if defined as global in open code
    • In Sanjeev.K's example SAS sees that the macro variable already exists so treats it as global within the macro.  Declaring a local macro variable with the same name within the macro can be done but there is no interaction between the local and global variables
    • If the macro variable is created using call symput in a data step or select into in Proc SQL, the value will be global even if the datastep/SQL runs within a macro (this needs to be validated - I don't have access to SAS right now).  The reason being that the datastep/sql runs after the macro is resolved, effectively in open code.
  • Good reasons for declaring macro variables in open to be global:
    • It can be a structured way of listing all the macro variables in use at the head of a program
    • Sometimes a piece of code is designed to run either stand alone or following another program which might pre-set the macro value.  If your code needs to reference the macro variable whether it already exists or not, declare it as a global variable at the start of the program.  If it is already defined, %global has no effect.  Otherwise, a macro variable is defined to exist with null value (%length zero), and you can detect this case and deal with it .
  • Good reason for declaring macro variables explicitly local in a macro
    • If a macro is to be reused you have no control over how another programmer may define global macro variables in other parts of the program.  To avoid confusion of the kind illustrated by Sanjeev.K it is necessary to be explicit in defining variables to be local.
  • If a macro is to be reused it is good practice to avoid defining global macro variables within a macro as these may interact with definitions elsewhere in open code.  Instead create the macro as a macro function

          %macro foobar (a, b) ;

               %local x ;

               %Let x = ...... ;

               %* Note no semicolon on next line, not an error! ;

               &x

          %mend ;


           %put %foobar (1, 2) ;

Richard

Super Contributor
Posts: 276

Re: Macro Variables Scopes

Hi   @RichardinOz

As you Said..

"If the macro variable is created using call symput in a data step or select into in Proc SQL, the value will be global even if the datastep/SQL runs within a macro (this needs to be validated - I don't have access to SAS right now).  The reason being that the datastep/sql runs after the macro is resolved, effectively in open code."


No.


The Macro Variable always become Local,if they created With in the Code irrespective of the way they created.



Regards..


Sanjeev.K


Super Contributor
Posts: 282

Re: Macro Variables Scopes

Hi Sanjeev,

If I've understood correctly, I'd be inclined to agree with Richard as I get the following output:

a=Initial value

a=Data step value

a=Alice

from the following code:

%let a=Initial value;

%put a=&a;

%macro test1;

  data _null_;

    call symput('a','Data step value');

  run;

%mend test1;

%test1;

%put a=&a;

%macro test2;

  proc sql noprint;

    select name into: a

  from sashelp.class

  where height=56.5 /* only Alice */

  ;

  quit;

%mend test2;

%test2;

%put a=&a;

regards,

Amir.

Super Contributor
Posts: 276

Re: Macro Variables Scopes

Hi ..

Hope you gone through my earlier comments in this post.

Rechard saying that if we create macro variable with in the macro  using call symput and into,that will become always global.

but that is always not correct.

Try This Code..

  %let a=Initial value;

%put a=&a;

%macro test1;

  data _null_;

    call symput('b','Data step value');

  run;

%mend test1;

%test1;

%put b=&b;

%macro test2;

  proc sql noprint;

    select name into: c

  from sashelp.class

  where height=56.5 /* only Alice */

  ;

  quit;

%mend test2;

%test2;

%put c=&c;


In above code  we created B and C macro variables with in the Macro using  Call Symput and Into,but still the Scope of B and C macro variable is Local.




Thanks.


Sanjeev.K

Super Contributor
Posts: 282

Re: Macro Variables Scopes

Hi Sanjeev,

As suggested, I ran the code in PC SAS 9.1.3 and had the following results:

a=Initial value

b=Data step value

WARNING: Apparent symbolic reference C not resolved.

c=&c

So maybe we were both half right?

Regards,

Amir.

Message was edited by: Amir Malik - Format output

Super Contributor
Posts: 276

Re: Macro Variables Scopes

Yes Amir.

I too tested the  code now and getting Same.

So we can conclude that  If we create Macro variable inside macro using Call Symput that always become Global.but not in the Case of INTO.:-)

Might the reason being that the datastep  runs after the macro is resolved.

Regards.

Sanjeev.K

Super Contributor
Posts: 644

Re: Macro Variables Scopes

Would you mind trying it again with the colon in front of the macro variable name?  I can't think of any reason why Proc SQL should run during macro pre-processing, which is implied if the macro variable created is local

%macro test2;

  proc sql noprint;

    select name into :c

  from sashelp.class

  where height=56.5 /* only Alice */

  ;

  quit;

%mend test2;

%test2;

%put c=&c;


Richard

Respected Advisor
Posts: 3,777

Re: Macro Variables Scopes

It appears that INTO creates LOCAL variables unless the variable(s) already exist in an outer or global symbol table.

Ask a Question
Discussion stats
  • 27 replies
  • 852 views
  • 3 likes
  • 9 in conversation