Post has been considerably edited (Sorry for this).
I run this pseudo program:
%macro myfun(country); %let country = %sysfunc(upcase(&country)); *Making the macro case insensitve; %if &country. = FI or US or GB or SW or DK %then %do; %put ERROR: Country in the list; %end; %else %do; %put Error: Just some random text; %end; %mend myfun; %myfun(FI);
It returns the error:
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &country. = FI or US or GB or SW or DK ERROR: The macro MYFUN will stop executing.
Any advice?
Use the IN operator, not the equality operator, to test if value is in a list. To use the IN operator make sure to set the MINOPERATOR and MINDELIMITER options on the %MACRO statement. Otherwise your macro will perform differently based on what users have set those options to in the calling program.
Do not use datastep functions via %SYSFUNC() when there is already a macro function for that operation.
Add macro quoting in case the values passed have strange characters that will impact the testing of the values.
%macro myfun(country) / minoperator mindelimiter=' ';
%let country = %qupcase(&country);
%if &country. in FI US GB SW DK %then %do;
%put NOTE: &=country is in the list;
%end;
%else %do;
%put ERROR: &=country is not in the list;
%end;
%mend myfun;
24 %myfun(FI) NOTE: COUNTRY=FI is in the list 25 %myfun(us) NOTE: COUNTRY=US is in the list 26 %myfun(usa) ERROR: COUNTRY=USA is not in the list
When I run your code, I get a different error.
254 %macro myfun(country); 255 %let country = %sysfunc(upcase(&random)); *Making the macro case insensitve; 256 257 %if &country. ^= FI US GB SW DK %then %do; 258 %put ERROR: Country not in the list 259 %end; ERROR: Macro keyword END appears as text. ERROR: A dummy macro will be compiled. 260 %mend myfun; 261 262 %myfun(E);
You might want to consider using %upcase instead of %sysfunc(upcase()). You might also want to consider defining variable &RANDOM before you use it. Hint hint hint.
Next, macro processor will test your &COUNTRY macro variable to see if it is (or is not) equal to the text string FI US GB SW DK and there is no such country, every country name or abbreviation in the world is not equal to the text string FI US GB SW DK so you really need to think this through carefully.
restarted my SAS and got something else, I edited my post considerably.
Why would SAS not recognize the %END; command???? Look very very carefully.
Also, a second problem after that is that you haven't grasped my point about comparing &COUNTRY to the text string shown.
Missing semicolon at the end of %put statement
so, fix this
%put ERROR: Country not in the list
to
%put ERROR: Country not in the list;
If the problem has been solved, mark the thread as solved and close it.
Then you should post a new question.
Otherwise, the exchange in the middle will be meaningless (in hindsight).
The problem is that the macro processor considers the stuff on the right hand side of the equal sign to be text. It doesn't know that you want to LOOP through each value shown there and do the test and then see if &COUNTRY matches one of the five abbreviations. Macros don't loop, unless you specifically tell it to do so, which you have not done.
You can also use native macro commands to determine if &country is IN the list
FI US GB SW DK
but there are some reasons why people don't like to do that and I won't get into this.
I like to use the %inm macro to do things like this. Here is how I would do it:
%macro inm(slist,s);
/* SAS Macro %inm to see if &s is contained in a string or list &slist */
/* Borrowed from https://groups.google.com/forum/#!topic/comp.soft-sys.sas/fWcSDgg11tE */
%if %sysfunc(indexw(&slist,&s)) gt 0 %then 1 ;
%else 0;
%mend;
%macro myfun(country);
%let country = %sysfunc(upcase(&country));
%if not %inm(FI US GB SW DK,&country) %then %do;
%put ERROR: Country not in the list;
%end;
%else %do;
%put Country &country found;
%end;
%mend myfun;
%myfun(FI)
If you don't want to do it that way, the proper syntax is
%if &country = FI or &country = US or &country = GB or &country = SW or &country = DK %then %do;
try this
options minoperator mindelimiter=',';
%macro myfun(country);
%let country = %sysfunc(upcase(&country)); *Making the macro case insensitve;
%if &country. in (FI, US, GB, SW, DK) %then %do;
%put ERROR: Country in the list;
%end;
%else %do;
%put Error: Just some random text;
%end;
%mend myfun;
%myfun(FI);
This condition
%if &country. = FI or US or GB or SW or DK
evaluates to this condition
%if (&country. = FI) or (US) or (GB) or (SW) or (DK)
Since none of
US GB SW DK
are valid boolean values (numeric, missing or 0 = false, any other = true), this must fail.
How about this: https://communities.sas.com/t5/SAS-Programming/Free-Webinar-How-Do-I-Build-a-Macro-Application/m-p/7...
There are plenty of tutorials on macros, and SAS maintains an extensive YouTube channel, I'm sure you can find macro information there.
The difference between in operation and equality operator is basic understanding of logical expressions. So general programming knowledge will help.
To find what operators SAS supports check the documentation.
or
Use the IN operator, not the equality operator, to test if value is in a list. To use the IN operator make sure to set the MINOPERATOR and MINDELIMITER options on the %MACRO statement. Otherwise your macro will perform differently based on what users have set those options to in the calling program.
Do not use datastep functions via %SYSFUNC() when there is already a macro function for that operation.
Add macro quoting in case the values passed have strange characters that will impact the testing of the values.
%macro myfun(country) / minoperator mindelimiter=' ';
%let country = %qupcase(&country);
%if &country. in FI US GB SW DK %then %do;
%put NOTE: &=country is in the list;
%end;
%else %do;
%put ERROR: &=country is not in the list;
%end;
%mend myfun;
24 %myfun(FI) NOTE: COUNTRY=FI is in the list 25 %myfun(us) NOTE: COUNTRY=US is in the list 26 %myfun(usa) ERROR: COUNTRY=USA is not in the list
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.