Rogue258
Rogue258

Reputation: 135

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.

Upvotes: 0

Views: 121

Answers (2)

Tom
Tom

Reputation: 51566

Before trying to generate code you need to have a good idea of the code you want to generate. Your current code is full of things that are just not valid SAS code, independent of your attempt to call your macros.

You cannot use a WHEN statement in the place you have it. You could use WHEN inside of a DO SELECT block.

You cannot use two equal signs next to each other. Your expression :

 Discount_EDD == 'Discount_EDD' 

Does not have any value between the two separate = operators.

If you meant to test if the value of the variable named Discount_EDD had the value 'Discount_EDD' then you would use

 Discount_EDD = 'Discount_EDD' 

If you wanted to test if the value of the macro variable was Discount_EDD then you might use this in SAS code since SAS does not care whether you use single or double quotes on the outside:

 "&list_string." = 'Discount_EDD' 

But that would fail if the test was in MACRO CODE since the " characters are different from the ' characters. So in macro logic you would need to use something like:

 "&list_string." = "Discount_EDD" 

And this will not work in either regular SAS code or in macro code

 '&list_string.' = 'Discount_EDD' 

because the macro processor will ignore the text inside of single quotes so the test will fail since & is different than D.

Upvotes: 1

Quentin
Quentin

Reputation: 6378

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.

Upvotes: 1

Related Questions