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

Coding a Macro to tell whether one string is in a string list or not[Code and Log are below].

In one way, it works. But in the other way, it is a BIG NOT. When the String to pass as var with additional space after, the return 

value changes from 1 to 0?!! 

 

Anyone helps...

 

%let vrf_sellist=vrf_ordval_dif_acs_p vrf_ordval_dif_mix_1 vrf_ordval_dif_mix_2 vrf_ordval_dif_p vrf_ordvol_dif_p vrf_ordvol_dif_p_d vrf_val_dif_p;

%macro isin(vlist, var);
%local i isin;
%let n_vars=%sysfunc(countw(&vlist.));
%let isin=0;
%do i=1 %to &n_vars;
%if &var.=%scan(&vlist.,&i) %then %do;
%let isin=1;
%end;
%end;

&isin
%mend;

%isin(&vrf_sellist., vrf_ordval_dif_acs_p); /*=1*/
%isin(&vrf_sellist., vrf_ordnet_dif_acs_p ); /*=0*/

 

7532 %let vrf_sellist=vrf_ordval_dif_acs_p vrf_ordval_dif_mix_1 vrf_ordval_dif_mix_2
7532! vrf_ordval_dif_p vrf_ordvol_dif_p vrf_ordvol_dif_p_d vrf_val_dif_p;
7533
7534 %macro isin(vlist, var);
7535 %local i isin;
7536 %let n_vars=%sysfunc(countw(&vlist.));
7537 %let isin=0;
7538 %do i=1 %to &n_vars;
7539 %if &var.=%scan(&vlist.,&i) %then %do;
7540 %let isin=1;
7541 %end;
7542 %end;
7543
7544 &isin
7545 %mend;
7546
7547
7548
7549 %isin(&vrf_sellist., vrf_ordval_dif_acs_p); /*=1*/
MLOGIC(ISIN): Beginning execution.
MLOGIC(ISIN): Parameter VLIST has value vrf_ordval_dif_acs_p vrf_ordval_dif_mix_1
vrf_ordval_dif_mix_2 vrf_ordval_dif_p vrf_ordvol_dif_p vrf_ordvol_dif_p_d
vrf_val_dif_p
MLOGIC(ISIN): Parameter VAR has value vrf_ordval_dif_acs_p
MLOGIC(ISIN): %LOCAL I ISIN
MLOGIC(ISIN): %LET (variable name is N_VARS)
MLOGIC(ISIN): %LET (variable name is ISIN)
MLOGIC(ISIN): %DO loop beginning; index variable I; start value is 1; stop value is 7; by value is
1.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is TRUE
MLOGIC(ISIN): %LET (variable name is ISIN)
MLOGIC(ISIN): %DO loop index variable I is now 2; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 3; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 4; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 5; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 6; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 7; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 8; loop will not iterate again.
NOTE: Line generated by the macro variable "ISIN".
1 1
-
180
MPRINT(ISIN): 1
MLOGIC(ISIN): Ending execution.

ERROR 180-322: Statement is not valid or it is used out of proper order.

7550 %isin(&vrf_sellist., vrf_ordnet_dif_acs_p ); /*=0*/
MLOGIC(ISIN): Beginning execution.
MLOGIC(ISIN): Parameter VLIST has value vrf_ordval_dif_acs_p vrf_ordval_dif_mix_1
vrf_ordval_dif_mix_2 vrf_ordval_dif_p vrf_ordvol_dif_p vrf_ordvol_dif_p_d
vrf_val_dif_p
MLOGIC(ISIN): Parameter VAR has value vrf_ordnet_dif_acs_p
MLOGIC(ISIN): %LOCAL I ISIN
MLOGIC(ISIN): %LET (variable name is N_VARS)
MLOGIC(ISIN): %LET (variable name is ISIN)
MLOGIC(ISIN): %DO loop beginning; index variable I; start value is 1; stop value is 7; by value is
1.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 2; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 3; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 4; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 5; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 6; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 7; loop will iterate again.
MLOGIC(ISIN): %IF condition &var.=%scan(&vlist.,&i) is FALSE
MLOGIC(ISIN): %DO loop index variable I is now 8; loop will not iterate again.
NOTE: Line generated by the macro variable "ISIN".
1 0
-
180
MPRINT(ISIN): 0
MLOGIC(ISIN): Ending execution.

ERROR 180-322: Statement is not valid or it is used out of proper order.

 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

Thank you

 

So, if you remove these two lines because they are unnecessary

 

%isin(&vrf_sellist., vrf_ordval_dif_acs_p);  /*=1*/
%isin(&vrf_sellist., vrf_ordnet_dif_acs_p ); /*=0*/

and also replace %and with and

everything should work

--
Paige Miller

View solution in original post

9 REPLIES 9
PaigeMiller
Diamond | Level 26

First, thank you for showing us the entire LOG for this code. That's helpful. However, it would be 1,000 times better if you include the LOG in the window that appears when you click on the </> icon. This preserves the formatting of the LOG and makes it much easier to read. Please please please please please please please please please preserve the formatting of the LOG as described every time from now on.

 

2021-11-26 08_27_29-Reply to Message - SAS Support Communities — Mozilla Firefox.png

It's not clear what your macro is supposed to be doing, or why you have this line in the code

 

&isin

but that is the error. This line creates SAS code, which SAS then tries to execute. But in SAS code, the number 0 by itself (or the number 1 by itself) is an error. I am thinking you did not intend it to be SAS code, so what is the intent here?

 

I am guessing that you want this macro variable &ISIN to be available to use after the macro runs. Is that correct? If so, remove that one line, remove ISIN from the %LOCAL command, and add this before you actually call the macro:

 

%global isin;

 

--
Paige Miller
hellohere
Pyrite | Level 9

Use it as a logic ... isin is the return value

 

 

%let vrf_sellist=vrf_ordval_dif_acs_p vrf_ordval_dif_mix_1 vrf_ordval_dif_mix_2 vrf_ordval_dif_p vrf_ordvol_dif_p vrf_ordvol_dif_p_d vrf_val_dif_p; %macro isin(vlist, var); %local i isin; %let n_vars=%sysfunc(countw(&vlist.)); %let isin=0; %do i=1 %to &n_vars; %if &var.=%scan(&vlist.,&i) %then %do; %let isin=1; %end; %end; &isin %mend; %isin(&vrf_sellist., vrf_ordval_dif_acs_p); /*=1*/ %isin(&vrf_sellist., vrf_ordnet_dif_acs_p ); /*=0*/ %macro test(); %if %isin(&vrf_sellist., var)=1 %and %isin(&vrf_sellist., vrf_ordval_dif_acs_p)=1 %then %do; %put "both match"; %end; %else %do; %put "has non-match"; %end; %mend; %test();

hellohere
Pyrite | Level 9
%macro test(); %if %isin(&vrf_sellist., var)=1 %and %isin(&vrf_sellist., vrf_ordval_dif_acs_p)=1 %then %do; %put "both match"; %end; %else %do; %put "has non-match"; %end; %mend; %test();
PaigeMiller
Diamond | Level 26

Please post code in the code box. Click on the "little running man" icon and paste your code into the box that appears.

--
Paige Miller
hellohere
Pyrite | Level 9
%let vrf_sellist=vrf_ordval_dif_acs_p	vrf_ordval_dif_mix_1	vrf_ordval_dif_mix_2	vrf_ordval_dif_p	vrf_ordvol_dif_p	vrf_ordvol_dif_p_d	vrf_val_dif_p;

%macro isin(vlist, var);
	%local i isin;
	%let n_vars=%sysfunc(countw(&vlist.));
	%let isin=0;
	%do i=1 %to &n_vars;	
		%if %scan(&var.,1)=%scan(&vlist.,&i) %then %do;
			%let isin=1; 
		%end;

	%end;

	&isin
%mend;

%isin(&vrf_sellist., vrf_ordval_dif_acs_p);  /*=1*/
%isin(&vrf_sellist., vrf_ordnet_dif_acs_p ); /*=0*/


%macro test();
	%if %isin(&vrf_sellist., var)=1 %and %isin(&vrf_sellist., vrf_ordval_dif_acs_p)=1 %then %do;
		%put "both match";
	%end;
	%else %do;
		%put "has non-match";
	%end;
%mend;

%test();
PaigeMiller
Diamond | Level 26

Thank you

 

So, if you remove these two lines because they are unnecessary

 

%isin(&vrf_sellist., vrf_ordval_dif_acs_p);  /*=1*/
%isin(&vrf_sellist., vrf_ordnet_dif_acs_p ); /*=0*/

and also replace %and with and

everything should work

--
Paige Miller
PaigeMiller
Diamond | Level 26

You may also want to use the %inm macro, which is the equivalent of the non-macro IN function

 

%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;
--
Paige Miller
Astounding
PROC Star

The macro itself looks OK, but the way you are calling it is not what it is intended for.  Let's assume you remove the semicolon at the end of the macro call, so you have:

%isin(&vrf_sellist., vrf_ordval_dif_acs_p)

This macro call is intended to return a 1 or a 0.  So you have to use it in a place where your program would expect to process a 1 or a 0.  For example:

%if %isin(&vrf_sellist., vrf_ordval_dif_acs_p) %then %do;
hellohere
Pyrite | Level 9

Know what you say. The quest is when with extra space, the return value changes from 1 to 0.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 9 replies
  • 1934 views
  • 0 likes
  • 3 in conversation