/* search words in a macro variable list which contains "'" or any special caracters*/
%let source=1028_BUZ%STR(%'); /* i have the apostroph in my list of words and potentially other punctuation or special caracters*/
%let string= 1028_' 1_AAA 1_AAB 1BUZ 14_EUZ;
%macro finddlm(source,string,dlm);
%global result;
%let source=%upcase(%NRSTR(&source));
%let string=%upcase(%NRSTR(&string));
%if &dlm= %then %let dlm=%str( );
%if %sysfunc(indexw(%superq(source),&string,%superq(dlm)))>0 %then %do;
%let result=1;
%end;
%else %do;
%let result=0;
%end;
%mend finddlm;
%finddlm(&source,&string,);
First of all, you've mixed up source and string in the indexw() function, and you've created a search string that isn't found in the source.
This will give you a result of 1:
%let string=1028_%STR(%');
%let source= 1028_%str(%') 1_AAA 1_AAB 1BUZ 14_EUZ;
%macro finddlm(source,string,dlm);
%global result;
%let source=%upcase(%NRSTR(&source));
%let string=%upcase(%NRSTR(&string));
%if &dlm= %then %let dlm=%str( );
%if %sysfunc(indexw(%superq(source),&string,%superq(dlm)))>0 %then %do;
%let result=1;
%end;
%else %do;
%let result=0;
%end;
%mend finddlm;
%finddlm(&source,&string,);
%put result=&result;
as will this:
%let string=1028_%STR(%');
%let source= 1028_%str(%') 1_AAA 1_AAB 1BUZ 14_EUZ;
data _null_;
result = indexw("&source","&string"," ");
call symputx('another_result',result,'g');
run;
%put result=&another_result;
As you have likely seen, using macro language to solve this introduces complications. There is the possibility of unmatched quotes and unmatched parentheses in either string. It would be a whole lot easier to let a DATA step do the searching:
data _null_;
source = symget(source);
string = symget(string);
if ......
then call symput('result', '1');
else call symput('result', '0');
run;
First of all, you've mixed up source and string in the indexw() function, and you've created a search string that isn't found in the source.
This will give you a result of 1:
%let string=1028_%STR(%');
%let source= 1028_%str(%') 1_AAA 1_AAB 1BUZ 14_EUZ;
%macro finddlm(source,string,dlm);
%global result;
%let source=%upcase(%NRSTR(&source));
%let string=%upcase(%NRSTR(&string));
%if &dlm= %then %let dlm=%str( );
%if %sysfunc(indexw(%superq(source),&string,%superq(dlm)))>0 %then %do;
%let result=1;
%end;
%else %do;
%let result=0;
%end;
%mend finddlm;
%finddlm(&source,&string,);
%put result=&result;
as will this:
%let string=1028_%STR(%');
%let source= 1028_%str(%') 1_AAA 1_AAB 1BUZ 14_EUZ;
data _null_;
result = indexw("&source","&string"," ");
call symputx('another_result',result,'g');
run;
%put result=&another_result;
/* sorry for my mistakes it works more easy with a data step but still understand why my macro program doesn't work , it seems the it is indefinitely runing .....*/
/* i have en error when i submit my code with my example where source and string contains quotation marks or special caracters
i have created the source and string macro variable with proc sql statment using into: separated by ' ' ( space )
*/
%macro control_find_word(source,string,dlm);
%let k=1;
%let ID_dim=%scan(&string. , &k ," ");
%do %while (&ID_dim ne );
data _null_;
result = indexw("&source","&string"," ");
call symputx('result',result,'g');
run;
%if &result=0 %then %do;
%let control_dim=1;
%put ERROR: WORD DOES NOT EXIST;
%goto fin;
%end;
%let k=%eval(&k+1);
%let ID_dim=%scan(&string. , &k ," ");
%end;
%FIN : ;
%mend;
%control_find_word(&source,&string,);
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.