I have a query where I need to run multiple macros based on a condition. The condition is that if the value of a variable is X then macro 1 should run, if the value of the variable is Y then macro 2 should run and so one. I am trying to pass the value of the variable as a list. But only the 'discount_edd' macro is running. I don't see any particular error in the code. I haven't declared the variable 'buriza' anywhere else in the code except the place where you directly see it. Here is the code for the same. I am passing 'Discount_EDD' and 'Discount_Logility' as the inputs to the '&list_string' macro variable and want the macro 'dummy' to run both the discount_edd and discount_logility macros from the macro named 'doit'.
%put &list_string;
%put &buriza;
%macro get_bds;
{code to get data from excel files stored on servers}
%mend;
%macro discount_edd;
{proc sql statements to get Discount data from teradata SQL}
%mend;
%macro discount_logility;
{proc sql statements to get Discount data from DB2 SQL}
%mend;
%macro doit(list=);
%if "&buriza."="Discount_EDD" %then %do;
%discount_edd
%end;
%else %if "&buriza."="Discount_Logility" %then %do;
%get_bds
%discount_logility
%end ;
%mend doit;
%macro dummy(bur= );
%do i = 1 %to %sysfunc(countw(&list_string.));
%let buriza = %scan(&list_string., &i.);
/*%let list_string=Discount_EDD;*/
%doit(list=&buriza)
%end;
%mend dummy;
options mprint;
%dummy(bur= &list_string)
Here is the part of the log of the output
LIST_STRING=Discount_EDD
LIST_STRING0=2
LIST_STRING1=Discount_EDD
LIST_STRING2=Discount_Logility
LIST_STRING_COUNT=2
MLOGIC(QLEFT): %LET (variable name is I)
MLOGIC(VERIFY): Beginning execution.
MLOGIC(VERIFY): This macro was compiled from the autocall file /opt/../verify.sas
MLOGIC(VERIFY): Parameter TEXT has value
MLOGIC(VERIFY): Parameter TARGET has value
MLOGIC(VERIFY): %LOCAL I
MLOGIC(VERIFY): %IF condition %length(&text)=0 OR %length(&target)=0 is FALSE
MLOGIC(VERIFY): %DO loop beginning; index variable I; start value is 1; stop value is 1; by value is 1.
MLOGIC(VERIFY): %IF condition NOT %index(&target,%qsubstr(&text,&i,1)) is FALSE
MLOGIC(VERIFY): %DO loop index variable I is now 2; loop will not iterate again.
MLOGIC(VERIFY): %IF condition &i>%length(&text) is TRUE
MLOGIC(VERIFY): Ending execution.
MLOGIC(QLEFT): %IF condition &i is FALSE
MLOGIC(QLEFT): Ending execution.
MLOGIC(DATATYP): %LET (variable name is LEN)
MLOGIC(DATATYP): %IF condition &len > 0 is FALSE
MLOGIC(DATATYP): Ending execution.
MLOGIC(STPEND): %IF condition (%qcmpres(&_RESULT) eq PACKAGE_TO_EMAIL) and (%datatyp(&_EMAIL_ADDRESS0) ne NUMERIC) and (&_EMAIL_ADDRESS0 ne ) is FALSE
MLOGIC(STPEND): %LET (variable name is MIMEMAP1)
MLOGIC(STPEND): %LET (variable name is MIMEMAP)
MLOGIC(QCMPRES): Beginning execution.
MLOGIC(QCMPRES): This macro was compiled from the autocall file /opt/../qcmpres.sas
MLOGIC(QCMPRES): Parameter TEXT has value
MLOGIC(QCMPRES): %LOCAL I
MLOGIC(QCMPRES): %LET (variable name is I)
MLOGIC(QCMPRES): %DO %WHILE(&i^=0) loop beginning; condition is FALSE. Loop will not be executed.
MLOGIC(QLEFT): Beginning execution.
MLOGIC(QLEFT): This macro was compiled from the autocall file /opt/../qleft.sas
MLOGIC(QTRIM): Beginning execution.
MLOGIC(QTRIM): This macro was compiled from the autocall file /opt/../qtrim.sas
MLOGIC(QTRIM): Parameter VALUE has value
MLOGIC(QTRIM): %LOCAL I
MLOGIC(QTRIM): %DO loop beginning; index variable I; start value is 0; stop value is 1; by value is -1. Loop will not be executed.
MLOGIC(QTRIM): %IF condition &i>0 is FALSE
MLOGIC(QTRIM): Ending execution.
MLOGIC(QLEFT): Parameter TEXT has value
MLOGIC(QLEFT): %LOCAL I
MLOGIC(QLEFT): %IF condition %length(&text)=0 is TRUE
After the revised code only the 'discount_edd' macro runs. I need the 'discount_logility' macro to run too.
This macro definition does not make sense.
%macro doit(list=);
%if "&buriza."="Discount_EDD" %then %do;
%discount_edd
%end;
%else %if "&buriza."="Discount_Logility" %then %do;
%get_bds
%discount_logility
%end ;
%mend doit;
You are defining the macro to take a parameter (which will be a LOCAL macro variable) named LIST. But the macro is only referencing some undefined macro variable named buriza instead of using the value you are passing into it.
If you want %DOIT to operate on just one value then use the same name for both macro variables:
%macro doit(buriza);
%if "&buriza."="Discount_EDD" %then %do;
%discount_edd
%end;
%else %if "&buriza."="Discount_Logility" %then %do;
%get_bds
%discount_logility
%end ;
%mend doit;
If you want %DOIT to loop over an actual list of values then you would define it his way instead:
%macro doit(list);
%local buriza i ;
%do i=1 to %sysfunc(countw(&list),|));
%let buriza=%scan(&list,&i,|);
%if "&buriza."="Discount_EDD" %then %do;
%discount_edd
%end;
%else %if "&buriza."="Discount_Logility" %then %do;
%get_bds
%discount_logility
%end ;
%end ;
%mend doit;
Then you could call it with an actual list of values. I have used | as the delimiter between the values since your valid values are already using spaces in them.
%doit(Discount_EDD|Discount_Logility);