I have written a function to validate wether a country is in a specific list of the nordic countries (SE DK NO FI). So for example,
%put test = %ValidateCountry(se, no fi); #returns the logical 1.
The whole function looks like this (For the variables, b stands for boolean and m stands for macro. Example: countrym indicates that the variable is a macro variable).
%macro ValidateCountry(countrym /* Choose SE, DK, NO or FI. */,
countrylistm /* A used defined list contaning a combination of SE, DK, NO, FI. */
) /minoperator mindelimiter=' ';
/*--------------------------------------------------------------*/
/*Help Functionality*/
/*--------------------------------------------------------------*/
%if %upcase(&countrym.)= HELP or &countrym.=? %then %do;
%put WARNING-************************************************************************;
%put WARNING-* Description: Validate a country, the function is case-insensitive. *;
%put WARNING-* Syntax: ValidateCountry(countrym, countrylistm, caseb). *;
%put WARNING-* Parameters: *;
%put WARNING-* countrym: One of SE, DK, NO, FI. *;
%put WARNING-* countrylistm: a combination of SE, DK, NO, FI. *;
%put WARNING-* ---------------------------------------------------------------- *;
%put WARNING-* Example 1: ValidateCountry(SE, SE NO) returns 1. *;
%put WARNING-* Example 2: ValidateCountry(nO, sE NO Fi) returns 1. *;
%put WARNING-* Example 3: ValidateCountry(SE, SE USA) returns error. *;
%put WARNING-************************************************************************;
%return;
%end;
/*--------------------------------------------------------------*/
/*Validation*/
/*--------------------------------------------------------------*/
%local countrynotvalidbm countrylistnotvalidbm i nextm listm validbm;
%let countrynotvalidbm = 0; /* Initializing the variables used below */
%let countrylistnotvalidbm = 0;
%let validbm = 0;
%let listm=%qupcase(SE DK NO FI);
%if not (%qupcase(&countrym) in &listm) %then %do;
%let countrynotvalidbm=1;
%put ERROR: COUNTRY value "&countrym." must be ONE of the values: &listm .;
%end;
%do i=1 %to %sysfunc(countw(&countrylistm.));
%let nextm=%qscan(&countrylistm.,&i,%str( ));
%if not (%qupcase(&nextm) in &listm) %then %do;
%let countrylistnotvalidbm=1;
%put ERROR: COUNTRYLIST value "&nextm" is not among the values: &listm. ;
%end;
%end;
/*--------------------------------------------------------------*/
/*Main Body*/
/*--------------------------------------------------------------*/
%if (&countrynotvalidbm. = 1 or &countrylistnotvalidbm. = 1) %then %do ;
%put ERROR: The function was not run due to errors. ;
%end;
%else %do;
%if %upcase(&countrym.) in %upcase(&countrylistm.) %then %do;
%let validbm= 1;
%end;
%end;
&validbm. ; /*1 if the country is in the valid list */
%mend;
Now, running code below yields an error. I was hoping that the validation part of the function would catch it, but it does not. Error messages appearing are:
%put test = %ValidateCountry(,se no);
/* The following error appears */
ERROR: Operand missing for IN operator in argument to %EVAL function.
ERROR: The macro VALIDATECOUNTRY will stop executing. %put test = %ValidateCountry(se , ); /* The following error appears */ ERROR: The function COUNTW referenced by the %SYSFUNC or %QSYSFUNC macro function has too few arguments. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: %sysfunc(countw(&countrylistm.)) ERROR: The %TO value of the %DO I loop is invalid. ERROR: The macro VALIDATECOUNTRY will stop executing.
I don't know how to solve this "hole" in the error handling. All advice much appreciated.
... View more