SAS宏错误:找到的位置参数多于定义的

时间:2018-01-10 12:48:04

标签: macros sas

鉴于以下SAS数据集和宏,有人可以提供一个解释,说明为什么前3个调用宏没有错误执行,但第4个调用产生如下所列的错误消息。如果我没有在宏定义中使用“代码”的默认值(将“code = A11”更改为“code”),那么所有4个调用都会执行而不会出错。为什么是这样?我已经尝试退出SAS会话并重新启动但没有帮助。

SAS新手。谢谢。非常感激。 :)

    ------------------- begin code block -----------------------------------


    /* data set definition */

    data dat5;
        infile datalines truncover;
        input Year Prod_Cd $ Sales;
        datalines;
        2001 A11 100
        2001 B12 200
        2002 C13 300
        ;
    run;

    /* macro definition */
    %macro sel(code=A11); 
        proc sql;
            select * from dat5
            where Prod_Cd = "&code";
        quit;
    %mend;

    /* calls to the macro */

    %sel();             /* 1st call */
    %sel(code=A11);     /* 2nd call */
    %sel(code=A12);     /* 3rd call */
    %sel(A11);          /* 4th call */


    --------------------end code block--------------------------------------

    /* SAS log message for the 4th call to the macro */


    128  %macro sel(code=A11);
    129      proc sql;
    130          select * from dat5
    131          where Prod_Cd = "&code";
    132      quit;
    133  %mend;
    134
    135  %sel(A11);
    MLOGIC(SEL):  Beginning execution.
    ERROR: More positional parameters found than defined.
    MLOGIC(SEL):  Parameter CODE has value A11
    MLOGIC(SEL):  Ending execution.

    ------------------------------------------------------------------------          

3 个答案:

答案 0 :(得分:3)

定义宏时,可以指定是否可以按位置调用参数(即不在宏调用中命名参数)。所谓的位置参数在%MACRO语句中定义,名称后面没有=。您可以定义位置参数和命名参数,但必须首先显示位置参数。请注意,您可以在宏调用中按名称指定任何参数的值,但只能通过位置调用定义为位置的参数。

因此,如果您想在宏调用中指定CODE参数的值而不包含名称,那么您需要像这样定义宏:

%macro sel(code);

然后,您示例中的所有调用都会有效,但第一个调用会将CODE设置为空字符串而不是A11。如果要为定义为位置的参数设置默认值,则需要将逻辑添加到宏本身。比如这个:

%macro sel(code);
%if not %length(&code) %then %let code=A11;
proc sql;
  select * from dat5
    where Prod_Cd = "&code"
  ;
quit;
%mend;

答案 1 :(得分:0)

这是预期的行为:

%sel();             /* 1st call - no parameters specified - SAS uses default values from macro definition */
%sel(code=A11);     /* 2nd call - keyword parameter used correctly */
%sel(code=A12);     /* 3rd call - keyword parameter used correctly */
%sel(A11);          /* 4th call - No parameter name or =, so SAS interprets this as a positional parameter, but none are defined within the macro, hence the error*/

答案 2 :(得分:0)

SAS® 9.4 Macro Language: Reference, Fifth Edition, %MACRO Statement

定义宏时,参数列表被指定为逗号分隔的位置项列表(名称),后跟关键字项( name = default-value )。

调用宏时,指定为逗号分隔值列表的参数将映射到参数。

  • 位置参数必须以与宏定义中相同的顺序出现。
  • 关键字参数可以在位置参数之后以任何顺序出现。
    • 也可以将位置参数指定为name = value。这是确保宏重代码可读性的良好惯例。
  • 任何跳过的位置参数都将作为空字符串传递。
  • 为任何未指定的关键字参数指定默认值。
  • 如果参数列表尝试多次指定参数时出错(如果您错误地混合位置和关键字或重复关键字,则会出现错误)

使用A11值作为位置参数会导致错误,因为宏%sel的参数列表没有任何位置参数。