Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Macro variable resolution order

Status
Not open for further replies.

Asender

Programmer
Jun 4, 2003
31
GB
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;                                                        
                                                                 
[COLOR=blue]NOTE: The data set WORK.TEST has 1 observations and 1 variables. [/color]
[COLOR=blue]NOTE: The DATA statement used 0.02 CPU seconds and 10536K. [/color]      
                                                                 
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);                             
[COLOR=blue]NOTE: There were 1 observations read from the data set WORK.TEST. [/color] 
[COLOR=blue]NOTE: The DATA statement used 0.01 CPU seconds and 10556K. [/color]        
                                                                   
[COLOR=blue]NOTE: CALL EXECUTE generated line. [/color]                                 
1   + %inc dev(program2);                                          
[COLOR=blue]NOTE: %INCLUDE (level 1) file DEV(program2) is file                
      ACTUXK2.SAS.DEVLIB(PROGRAM2).  [/color]                              
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;                                                            
[COLOR=green]WARNING: Apparent symbolic reference EMAIL not resolved.[/color]                   
[COLOR=red]ERROR: A character operand was found in the %EVAL function or %IF condition
       where a numeric operand is required. The condition was: &email = 1 [/color]    
[COLOR=red]ERROR: The macro EMAIL020 will stop executing.[/color]                                
[COLOR=blue]NOTE: %INCLUDE (level 1) ending. [/color]                                            
2   + %inc dev(program2);                                                
[COLOR=blue]NOTE: %INCLUDE (level 1) file DEV(program2) is file                        
      ACTUXK2.SAS.DEVLIB(PROGRAM2).   [/color]                                     
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;                                                            
[COLOR=green]WARNING: Apparent symbolic reference EMAIL not resolved.[/color]                   
[COLOR=red]ERROR: A character operand was found in the %EVAL function or %IF condition
       where a numeric operand is required. The condition was: &email = 1 [/color]    
[COLOR=red]ERROR: The macro EMAIL020 will stop executing.[/color]                              
[COLOR=blue]NOTE: %INCLUDE (level 1) ending.[/color]

I have no doubt I am missing something obvious.

Kind Regards,



Asender...
 
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:-

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.
 
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...


 
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;                    
  [b][COLOR=red]%let test = TEST;[/color][/b]              
%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...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top