×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Macro variable resolution order

Macro variable resolution order

Macro variable resolution order

(OP)
Hi.

Can someone please explain why macro variable email is not resolving?

Here is some code the generates the WARNING.

CODE

*** Program 1 ***;

%macro report1;                  
  %let email = 1;                
  %inc dev(program2);            
%mend report1;                   
                                 
%macro report2;                  
  %let email = 2;                
  %inc dev(program2);            
%mend report2;                   
                                 
data test;                       
  run = 'YES';                   
run;                             
data _null_;                     
  set test;                      
  call execute('%report1');      
  call execute('%report2');      
run;                             

*** Program 2 - This code is stored elsewhere***;

%macro email020;                   
  %if &email = 1 %then %do;        
    %put THIS RESOLVED AT 1;       
  %end;                            
  %else %if &email = 2 %then %do;  
    %put THIS RESOVLED AT 2;       
  %end;                            
  %put _user_;                     
%mend email020;                    
%email020;  

Here is the resultant log

CODE


1    *** PROBLEM 1;                                                
2                                                                
3    %macro report1;                                             
4      %let email = 1;                                           
5      %inc dev(program2);                                       
6    %mend report1;                                              
7                                                                
8    %macro report2;                                             
9      %let email = 2;                                           
10     %inc dev(program2);                                       
11   %mend report2;                                              
12                                                               
13   data test;                                                  
14     run = 'YES';                                              
15   run;                                                        
                                                                 
NOTE: The data set WORK.TEST has 1 observations and 1 variables.
NOTE: The DATA statement used 0.02 CPU seconds and 10536K.       
                                                                 
16   data _null_;   
17     set test;                                                   
18     call execute('%report1');                                   
19     call execute('%report2');                                   
20   run;                                                          
                                                                   
MPRINT(REPORT1):   %inc dev(program2);                             
MPRINT(REPORT2):   %inc dev(program2);                             
NOTE: There were 1 observations read from the data set WORK.TEST.
NOTE: The DATA statement used 0.01 CPU seconds and 10556K.         
                                                                   
NOTE: CALL EXECUTE generated line.                                  
1   + %inc dev(program2);                                          
NOTE: %INCLUDE (level 1) file DEV(program2) is file                
      ACTUXK2.SAS.DEVLIB(PROGRAM2).  
                              
21  +*** PROGRAM2;                                                 
22  +%macro email020;
23  +  %if &email = 1 %then %do;                                           
24  +    %put THIS RESOLVED AT 1;                                          
25  +  %end;                                                               
26  +  %else %if &email = 2 %then %do;                                     
27  +    %put THIS RESOVLED AT 2;                                          
28  +  %end;                                                               
29  +  %put _user_;                                                        
30  +%mend email020;                                                       
31  +%email020;                                                            
WARNING: Apparent symbolic reference EMAIL not resolved.                   
ERROR: A character operand was found in the %EVAL function or %IF condition
       where a numeric operand is required. The condition was: &email = 1
    
ERROR: The macro EMAIL020 will stop executing.                                
NOTE: %INCLUDE (level 1) ending.                                             
2   + %inc dev(program2);                                                
NOTE: %INCLUDE (level 1) file DEV(program2) is file                        
      ACTUXK2.SAS.DEVLIB(PROGRAM2).   
                                     
32  +*** PROGRAM2;                                                         
33  +%macro email020;                                                      
34  +  %if &email = 1 %then %do;                                           
35  +    %put THIS RESOLVED AT 1;                                          
36  +  %end;                                                               
37  +  %else %if &email = 2 %then %do;                                     
38  +    %put THIS RESOVLED AT 2;                                          
39  +  %end;                                                               
40  +  %put _user_;                                                        
41  +%mend email020;                                                       
42  +%email020;                                                            
WARNING: Apparent symbolic reference EMAIL not resolved.                   
ERROR: A character operand was found in the %EVAL function or %IF condition
       where a numeric operand is required. The condition was: &email = 1
    
ERROR: The macro EMAIL020 will stop executing.                              
NOTE: %INCLUDE (level 1) ending.  
     

I have no doubt I am missing something obvious.

Kind Regards,



Asender...

RE: Macro variable resolution order

Hi Asender,
  The problem here is the SCOPE of the macro variable.  Macro variables by default are local in scope, they will exist within the current macro, but not outside it.
Insert this line:-

CODE

%GLOBAL EMAIL;
At the start of your program and it'll work just fine after that.
I'd recommend reading the doco on scope of Macro variables here:-
http://support.sas.com/onlinedoc/913/getDoc/en/mcrolref.hlp/a002047080.htm

It's useful to know how the scoping works now that you've hit this problem once.

Lastly, for anyone else trying this, you might need to change

CODE

  %inc dev(program2);    
to this

CODE

  %inc "C:\Temp\program2.sas";            
 to get it to work.
 

Chris
Business Analyst, Code Monkey, Data Wrangler.
SAS Guru.

RE: Macro variable resolution order

(OP)
Hiya Chris.

Thanks very much for replying.

I must confess that I have already considered and dismissed the global declaration solution.

True, the code now runs with no compilation error, but if you examine the new log you will see that the macro variable email has the same value ('2' - the last designated value) in both macro calls. This is no good.

I apologise, I should have made this clear at the start.

This is obviously a scoping issue, but as I understand it all macro variables located in a local table should be available to any macro nested within it. Do I have this correct?

I have come to the conclusion that the %inc is part of the issue. But I can't find anything definitive.

Kind Regards,


Asender...


 

RE: Macro variable resolution order

(OP)
Chris.

Sorry for posting again so soon.

I think I understand what is going on.

Even though the macro (email020) is being called from within another macro (Report1 or Report2), code within the %inc is being resolved in open code.

Try adding this %let to (program2):

CODE

*** PROBLEM2;                    
  %let test = TEST;              
%macro email020;                 
  %if &email = 1 %then %do;      
    %put THIS RESOLVED AT 1;     
  %end;                          
  %else %if &email = 2 %then %do;
    %put THIS RESOVLED AT 2;     
  %end;                          
  %put _user_;                   
%mend email020;                  
%email020;                       

On checking the log you will now see that macro variable TEST is declared as GLOBAL. Indicating that the macro EMAIL020 is not being called as a nested macro. Therefore, the macro variables EMAIL which are held at a local level within Report1 and Report2 are not available to EMAIL020.

Phew, what do you think?

Kind Regards,


Asender...

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login


Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close