BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
CP2
Pyrite | Level 9 CP2
Pyrite | Level 9

Does anyone know why my macro variable is not resolving?

 

I want to search a variable, named DrugHave. If macro variable DrugUse1 is equal to DrugHave then I want to create a variable called DrgUse1 and flag it with a 1. I want to do this for all 5 macro variables named in the %LET statements at the beginning of my program. Some variables in the %LET statements will be blank. Also, is it necessary to encase the DO LOOP within a macro at all or can I just use the DO LOOP within a datastep yet still call out my globa macro variables? All the online help suggestions use macros for this. I've tried both ways but the macro is not resolving. 

 

 

%LET DrugUse1 = 'ABC' ;
%LET DrugUse2 = 'XYZ' ;
%LET DrugUse3 = '' ;
%LET DrugUse4 = '' ;

%LET DrugUse5 = '' ;


array use[5] DrgUse1-DrgUse5 ;
%MACRO DRUG() ;
%do i = 1 %to 5 ;
%if drugHave = &&&drugUse&i %then use[i]=1 ;
%end;
%MEND ;
%DRUG ;

 

Error Msg

 

WARNING: Apparent symbolic reference DRUGUSE5 not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: drughave = &&&drugUse&i
ERROR: The macro DRUG will stop executing.

 

 

WITHOUT MACRO :

 

array use[5] DrgUse1-DrgUse5 ;
do i = 1 to 5 ;
if drughave = &&&drugUse&i then use[i]=1 ;
end;
run;

ERROR MESSAGE 

 

1717 array use[5] DrgUse1-DrgUse5 ;
1718 /*%MACRO DRUG() ;*/
1719 do i = 1 to 5 ;
1720 if drughave = &&&drugUse&i then use[i]=1 ;
WARNING: Apparent symbolic reference I not resolved.
NOTE: Line generated by the macro variable "I".
1 &drugUse&
-
22
WARNING: Apparent symbolic reference DRUGUSE not resolved.
WARNING: Apparent symbolic reference I not resolved.
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string,
a numeric constant, a datetime constant, a missing value, bitstring, INPUT, PUT.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

You're mixing together macro language and DATA step code in ways that are just not allowed.  It's so prevalent here that there is no quick fix.  I would suggest that you put aside macro language entirely, and learn more about SAS language.  For example, you might create a second array:

 

array druglist {5} $ _temporary_ (&druguse1 &druguse2 &druguse3 &druguse4 &druguse5);

 

That would be the extent of any use of macro language in the program, to assign initial values to elements of a temporary array.  Then figure out how to use that array within a DATA step to get the result that you want.

View solution in original post

4 REPLIES 4
RW9
Diamond | Level 26 RW9
Diamond | Level 26

You would need to use %global.  That being said I will strongly advise you not to mess around with this total mess of code.  You will find your life is much easier doing this in base SAS with arrays, there is nothing in what you have posted to suggest any need of macro at all.  And even if there was then after the datastep just call symput().  

novinosrin
Tourmaline | Level 20

If I understand you correctly, this is perhaps what you need:

 

%LET DrugUse1 = 'ABC' ;
%LET DrugUse2 = 'XYZ' ;
%LET DrugUse3 = '' ;
%LET DrugUse4 = '' ;
%LET DrugUse5 = '' ;


data want;
set have;/*your source input dataset*/
array use[5] DrgUse1-DrgUse5 ;
%MACRO DRUG ;
%do i = 1 %to 5 ;
if drugHave = "&&drugUse&i" then drugUse&i=1 ;
%end;
%MEND ;
run;
%DRUG

Try and let me know when you can-

Regards,

Naveen Srinivasan

Astounding
PROC Star

You're mixing together macro language and DATA step code in ways that are just not allowed.  It's so prevalent here that there is no quick fix.  I would suggest that you put aside macro language entirely, and learn more about SAS language.  For example, you might create a second array:

 

array druglist {5} $ _temporary_ (&druguse1 &druguse2 &druguse3 &druguse4 &druguse5);

 

That would be the extent of any use of macro language in the program, to assign initial values to elements of a temporary array.  Then figure out how to use that array within a DATA step to get the result that you want.

CP2
Pyrite | Level 9 CP2
Pyrite | Level 9

Yes. I wasn't thinking of putting the macro variables in an array as well but this is exactly what I needed. Thank you.

 


array druglist {5} $ _temporary_ (&druguse1 &druguse2 &druguse3 &druguse4 &druguse5) ;
array use[5] DrgUse1-DrgUse5 ;
do i = 1 to 5 ;
if drugHave = druglist[i] then use[i]=1 ;
else use[i]='' ;
end;

 

 

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 1647 views
  • 1 like
  • 4 in conversation