调用和运行基于特定条件的宏 SAS

huangapple go评论63阅读模式
英文:

Calling and Running a Macro based on certain conditions SAS

问题

我有以下的SAS代码,我想根据用户输入的条件来运行特定的宏预定义宏变量。

%put &list_string;

%macro get_bds;
{从存储在服务器上的Excel文件获取数据的代码}
%mend;

%macro discount_edd; 
{从Teradata SQL获取折扣数据的proc sql语句}
%mend;

%macro discount_logility;
{从DB2 SQL获取折扣数据的proc sql语句}
%mend;

%macro volume_edd; 
{从Teradata SQL获取销量数据的proc sql语句}
%mend;

%macro volume_logility;
{从Discount DB2 SQL获取销量数据的proc 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;

基本上,每当用户从Discount_EDD、Discount_Logility、Volume_EDD、Volume_Logility这4个选择中选择任何一个时,应该运行相应的宏(以及Volume_EDD和Volume_Logility的get_bds宏)。

然而,我一直在收到以下错误。

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;

我知道我需要在DATA步骤中添加SELECT语句,但我不知道如何根据条件选择要运行的宏。

如果有更适合这个任务的其他方法,我也愿意尝试。我基本上是通过在互联网上搜索得到的这些内容。

英文:

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.

答案1

得分: 1

有一种处理方法是编写一个外部宏 %doit(),它具有一个名为 list_string 的参数。该宏可以使用宏语言的 %IF %THEN 语句来控制要执行哪些辅助宏。以下是一个示例:

%macro get_bds();
  %put 从存储在服务器上的 Excel 文件获取数据的代码;
%mend;

%macro discount_edd(); 
  %put 从 Teradata SQL 获取折扣数据的 proc sql 语句;
%mend;

%macro discount_logility();
  %put 从 DB2 SQL 获取折扣数据的 proc 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)

如果您已经有一个包含用户输入的 list_string 值的全局宏变量,您可以在宏调用中引用该宏变量,例如:

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

虽然可以使用 DATA 步骤和 CALL EXECUTE 生成宏调用,但这是一种更复杂的技术,通常在您有一个数据集要用作生成宏调用的 "驱动程序" 时使用。

英文:

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.

答案2

得分: 1

在尝试生成代码之前,您需要清楚地了解您要生成的代码。您当前的代码中存在许多无效的SAS代码,与您尝试调用宏无关。

您不能在您放置它的位置使用WHEN语句。您可以在DO SELECT块内部使用WHEN。

您不能在两个等号旁边使用两个等号。您的表达式:

Discount_EDD == 'Discount_EDD'

在两个分开的等号运算符之间没有任何值。

如果您想要测试变量名为Discount_EDD的变量的值是否为'Discount_EDD',那么您应该使用

Discount_EDD = 'Discount_EDD'

如果您想要测试宏变量的值是否为Discount_EDD,那么在SAS代码中,您可以使用以下代码,因为SAS不关心您在外部使用单引号还是双引号:

"&list_string." = 'Discount_EDD'

但是,如果测试在宏代码中进行,由于"字符与'字符不同,它将失败。因此,在宏逻辑中,您需要使用类似以下的内容:

"&list_string." = "Discount_EDD"

而且,这在常规SAS代码或宏代码中都不起作用

'&list_string.' = 'Discount_EDD'

因为宏处理器会忽略单引号内的文本,所以测试将失败,因为&D不同。

英文:

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.

huangapple
  • 本文由 发表于 2023年7月14日 01:50:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76682056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定