DATA Step, Macro, Functions and more

validating macro parameter using IN() statement?

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 18
Accepted Solution

validating macro parameter using IN() statement?

 

I have a macro which needs to validate keyword parameters against a list. The code below distills the issue (the actual macro is much more complex).

 

 

%MACRO CONVERTOR (CONVERSION_TYPE = );

  %IF &CONVERSION_TYPE IN (MILES_TO_METERS,MILES_TO_FEET) %THEN %DO;
    %LET ORIGINAL_UNIT = MILES;
	                                                       %END;

%MEND;

%CONVERTOR (CONVERSION_TYPE = MILES_TO_METERS);

Executing this yields the following error in the log:

 

ERROR: Required operator not found in expression: &CONVERSION IN       (MILES_TO_METERS,MILES_TO_FEET)

 

Could someone please point out the correct way to do this? It seems that SAS doesn't allow the IN operator within a macro code?

 


Accepted Solutions
Solution
3 weeks ago
Super User
Super User
Posts: 8,114

Re: validating macro parameter using IN() statement?

Trying to us IN as an operator in macro code is tricky, and probably not worth it.  If you do want to use it then make sure to tell the macro compiler that you want to use it and what character to use as the delimiter. It is generally a bad idea to use a comma as a delimiter in macro code as it can cause trouble when trying to pass values into macro functions (or macro calls) since comma is used as the delimiter between arguments (parameters).

%macro convertor(conversion_type) / minoperator mindelimiter='|';
%local original_unit ;
%if &conversion_type in miles_to_meters|miles_to_feet %then %do;
  %let original_unit = %scan(&conversion_type,1,_);
%end;
%else %put WARNING: Conversion_type not recognized. &=conversion_type;
%put &=conversion_type &=original_unit ;
%mend;

%convertor(conversion_type = miles_to_meters);
%convertor(conversion_type = pounds_to_dollars);

 

 

View solution in original post


All Replies
PROC Star
Posts: 1,815

Re: validating macro parameter using IN() statement?

Try using

 *macro IN operator;
  options minoperator mindelimiter=',';

specify the correct delimiter  

Super User
Posts: 23,734

Re: validating macro parameter using IN() statement?

[ Edited ]

Historically IN was not a macro operation, but it was added at some point in the last decade. For backward compatibility the old functionality remains and you have to specify the options. I think you may also need a space between the words? Or at least it helps to make it legible and easier to debug. 

 

I find it easiest to 

1) Set options permanently as suggested by @novinosrin

2) Set it specifically for each macro to avoid unexpected behaviour. 

 

I also like to add an %ELSE and %PUT to my tests to make it clear where my logic is failing.

 

%MACRO CONVERTOR (CONVERSION_TYPE = ) / minoperator mindelimiter=',';

  %IF &CONVERSION_TYPE IN (MILES_TO_METERS, MILES_TO_FEET) %THEN %DO;
    %PUT ORIGINAL_UNIT = MILES;
	                                                       %END;
   %ELSE %PUT Logic failed;

%MEND;

%CONVERTOR (CONVERSION_TYPE = MILES_TO_METERS);

 

Super User
Posts: 6,778

Re: validating macro parameter using IN() statement?

In addition to specifying the two options ...

 

Off the top of my head and untested ...

 

Do NOT use parentheses around the list of values.

 

Do NOT add a space on either side of the delimiter.

Solution
3 weeks ago
Super User
Super User
Posts: 8,114

Re: validating macro parameter using IN() statement?

Trying to us IN as an operator in macro code is tricky, and probably not worth it.  If you do want to use it then make sure to tell the macro compiler that you want to use it and what character to use as the delimiter. It is generally a bad idea to use a comma as a delimiter in macro code as it can cause trouble when trying to pass values into macro functions (or macro calls) since comma is used as the delimiter between arguments (parameters).

%macro convertor(conversion_type) / minoperator mindelimiter='|';
%local original_unit ;
%if &conversion_type in miles_to_meters|miles_to_feet %then %do;
  %let original_unit = %scan(&conversion_type,1,_);
%end;
%else %put WARNING: Conversion_type not recognized. &=conversion_type;
%put &=conversion_type &=original_unit ;
%mend;

%convertor(conversion_type = miles_to_meters);
%convertor(conversion_type = pounds_to_dollars);

 

 

Super Contributor
Posts: 398

Re: validating macro parameter using IN() statement?

See if https://github.com/scottbass/SAS/blob/master/Macro/parmv.sas meets your needs. 

 

Or, if not, perhaps you can use it as a starting point for your own generic macro parameter validation macro.

Occasional Contributor
Posts: 18

Re: validating macro parameter using IN() statement?

Thank you all for responding.

 

In light of the added complexity, I'll just use the OR operator ....but it's good to know how properly use the IN() operator if needed in the future! A requirement of this particular macro is maintainability by "non SAS experts" hence it would be inappropriate to rely on options or other such dependencies.

 

 

%MACRO CONVERTOR (CONVERSION_TYPE = );

  %IF &CONVERSION_TYPE = MILES_TO_METERS  OR  &CONVERSION_TYPE = MILES_TO_FEET  %THEN %DO;
    %LET ORIGINAL_UNIT = MILES;
	                                                       %END;

%MEND;

%CONVERTOR (CONVERSION_TYPE = MILES_TO_METERS);

 

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 149 views
  • 6 likes
  • 6 in conversation