Search code examples
sassas-macro

Calling and Running a Macro based on certain conditions SAS


I have the following SAS Code where I want to run certain macros based on certain conditions that a user inputs for the macro pre-defined macro variables.

%put &list_string;

%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 volume_edd; 
{proc sql statements to get volume data from teradata SQL}
%mend;

%macro volume_logility;
{proc sql statements to get volume data from Discount DB2 SQL}
%mend;

data _null_;
        when &list_string. == 'Discount_EDD' call execute('%discount_edd');
        when &list_string. == 'Discount_Logility' call execute('%get_bds');
        when &list_string. == 'Discount_Logility' call execute('%discount_logility');
    end;
run;

data _null_;
        when &list_string. == 'Volume_EDD' call execute('%volume_edd');
        when &list_string. == 'Volume_Logility' call execute('%get_bds');
        when &list_string. == 'Volume_Logility' call execute('%volume_logility');
    end;
run;

Basically whenever user selects anything from the 4 choices of Discount_EDD,Discount_Logility,Volume_EDD,Volume_Logility the corresponding macros should run for them (and in addition get_bds macro for Volume_EDD and Volume_Logility)

However, I keep get this error.

when &list_string. == 'Discount_EDD' call execute('%discount_edd');
                   ____
                   161
NOTE: Line generated by the macro variable "LIST_STRING".
290         Discount_EDD
            ____________
            395
            76
291       +        when &list_string. == 'Discount_Logility' call execute('%get_bds');
                                                                                          The SAS System

                   ____
                   161
NOTE: Line generated by the macro variable "LIST_STRING".
291         Discount_EDD
            ____________
            395
            76
292       +     when &list_string. == 'Discount_Logility' call execute('%discount_logility');
             ____
             161
NOTE: Line generated by the macro variable "LIST_STRING".
292         Discount_EDD
            ____________
            395
            76
293       +    end;
               ___
               161
ERROR 161-185: No matching DO/SELECT statement.

ERROR 395-185: Opening parenthesis for SELECT/WHEN expression is missing.

ERROR 76-322: Syntax error, statement will be ignored.

294       +run;

I know I need to add in the select statement in the DATA step, but I don't know how I can select the macro to run according to the conditions.

Also I am open to some other methods if they are suited better for this task. I have pretty much got all this by searching on the internet.


Solution

  • One way to approach this is to write an outer macro, %doit(), which has a parameter for list_string. The macro can use macro language %IF %THEN statements to control which of the helper macros it will execute. As an example:

    %macro get_bds();
      %put Code to get data from excel files stored on servers ;
    %mend;
    
    %macro discount_edd(); 
      %put proc sql statements to get Discount data from teradata SQL ;
    %mend;
    
    %macro discount_logility();
      %put proc sql statements to get Discount data from DB2 SQL} ;
    %mend;
    
    %macro doit(list_string=) ;
      %if &list_string=Discount_EDD %then %do ;
        %get_bds()
      %end ;
      %else %if &list_string=Discount_Logility %then %do ;
        %discount_edd()
        %discount_logility()
      %end ;
    %mend doit ;
    
    %doit(list_string=Discount_EDD)
    %doit(list_string=Discount_Logility)
    

    If you already have a global macro variable with the user's input value for list_string, you can reference that macro variable in the macro call, e.g.

    %let list_string=Discount_EDD ;
    %doit(list_string=&list_string)
    

    While it is possible to use DATA step and CALL EXECUTE to generate macro calls, that is a more complex technique, and is usually employed when you have a dataset that you want to use as a "driver" to generate macro calls.