lubenja
lubenja

Reputation: 57

SAS store macro reference in macro variable

I want to store a list of macro references in another macro variable and then change the content of one of the referenced variables.

As example:

%LET String=FirstString; 
%LET KeepMacroNotString=&String; 
%PUT &String = &KeepMacroNotString ?;  


%LET String=String changed; 
%PUT &String = &KeepMacroNotString?; 

In the end I would like that %PUT &KeepMacroNotString resolves to "String changed". However it sticks to the first assignment.

Any ideas? Thx, Lubenja

Upvotes: 1

Views: 107

Answers (3)

Quentin
Quentin

Reputation: 6378

I wouldn't use this approach, but if you don't mind warning messages in the log (I do), you could in theory just change the order of your statements:

WARNING: Apparent symbolic reference STRING not resolved.
 57         
 58             %LET KeepMacroNotString=&String;
 59         
 60             %LET String=FirstString;
 61             %PUT &String = &KeepMacroNotString ?;
 FirstString = FirstString ?
 62         
 63             %LET String=String changed;
 64             %PUT &String = &KeepMacroNotString?;
 String changed = String changed?

This is basically an ugly way of accomplishing the same sort of indirection that Tom did more gracefully. Key point being that that the macro variable KeepMacroNotString is given a value of &String, not the resolved value.

In a macro setting, this can also be accomplished by assigning default value as a macro variable reference, e.g.:

 59         %macro indirect(String=
 60                 ,KeepMacroNotString=&string
 61                 );
 62           %put _local_;
 63           %put &string = &keepmacronotstring;
 64         %mend indirect;
 65         %indirect(string=Hi)
 INDIRECT KEEPMACRONOTSTRING &string
 INDIRECT STRING Hi
 Hi = Hi

Upvotes: 0

Tom
Tom

Reputation: 51566

Much easier to do with a data step.

data _null_;
  call symputx('KeepMacroNotString','&String');
run;

Upvotes: 2

lubenja
lubenja

Reputation: 57

I found the solution: A combination of the %NRSTR function and the %UNQUOTE function do the trick:

%LET String=FirstString; 
%LET KeepMacroNotString=%NRSTR(&String); 
%PUT &String = &KeepMacroNotString ?;  

%LET String=String changed; 
%PUT &String = %UNQUOTE(&KeepMacroNotString)?; 

Explanation: First you have to mask the "&" to prevent the macro from being resolved (%NRSTR()). But when you want to use the marco, then you have to unquote it again (%UNQUOTE()).

Upvotes: 1

Related Questions