【问题标题】:ERROR: Required operator not found in expression (SAS)错误:在表达式中找不到所需的运算符 (SAS)
【发布时间】:2021-07-05 04:21:02
【问题描述】:

我正在尝试从开始日期和结束日期开始循环,如下所示:

错误

在表达式中找不到必需的运算符:YEAR(INTNX('MONTH', MDY(2,1,2020), 3, 'SAME'))*100+MONTH(INTNX('MONTH', MDY(2,1) ,2020), 3, '相同'))

代码

%LET ENDING_YEAR         = 2021;   
%LET ENDING_MONTH        = 3;    
%LET STARTING_YEAR         = 2020;
%LET STARTING_MONTH        = 2;

DATA COUNT;
 START_DATE = MDY(&STARTING_MONTH.,1,&STARTING_YEAR.);
 END_DATE =  MDY(&ENDING_MONTH.,1,&ENDING_YEAR.);
 COUNT_MONTH = INTCK('MONTH',START_DATE,END_DATE)+1;
 COUNT_MONTH_4 = COUNT_MONTH - 4;
 COUNT_MONTH_3 = COUNT_MONTH - 3;
 call symputx('NUM_MONTH', COUNT_MONTH);
 call symputx('NUM_MONTH_4', COUNT_MONTH_4);
 call symputx('NUM_MONTH_3', COUNT_MONTH_3);
 RUN;


%MACRO FINAL_DATA;
%DO i = 0 %TO &NUM_MONTH_4.;
    %LET ADDITION = %EVAL(&i.+3);
    %LET TARGET_DB=INTNX('MONTH', MDY(&STARTING_MONTH.,1,&STARTING_YEAR.), &ADDITION., 'SAME');
    %LET TARGET_DB_MONTH = MONTH(&TARGET_DB.);
    %LET TARGET_DB_YEAR = YEAR(&TARGET_DB.);
    %LET DB = %EVAL(&TARGET_DB_YEAR.*100+&TARGET_DB_MONTH.);
    LIBNAME TETRIS "/actuary/Commercial/Monthend/&DB.";
    %LET TARGET_EFF =INTNX('MONTH', MDY(&STARTING_MONTH.,1,&STARTING_YEAR.), &i., 'SAME');
    %LET TARGET_EFF_MONTH = MONTH(&TARGET_EFF.);
    %LET TARGET_EFF_YEAR = YEAR(&TARGET_EFF.);
    %EXTRACTION(INFORCE, &TARGET_EFF_YEAR.,&TARGET_EFF_MONTH.);
%END;   

%DO j = &NUM_MONTH_3. %TO &NUM_MONTH.;
    %LET DB = %EVAL(&ENDING_YEAR.*100+&ENDING_MONTH.);
    LIBNAME TETRIS "/actuary/Commercial/Monthend/&DB.";
    %LET TARGET_EFF =INTNX('MONTH', MDY(&STARTING_MONTH.,1,&STARTING_YEAR.), &j., 'SAME');
    %LET TARGET_EFF_MONTH = MONTH(&TARGET_EFF.);
    %LET TARGET_EFF_YEAR = YEAR(&TARGET_EFF.);  
    %EXTRACTION(INFORCE, &TARGET_EFF_YEAR.,&TARGET_EFF_MONTH.);     
%END;

%MEND;
    
%FINAL_DATA;

我是 SAS 新手。任何建议将不胜感激。

谢谢。

【问题讨论】:

  • 显示的代码与错误消息不一致。是您提取宏的错误吗?请添加宏调试选项并发布更多日志。 `options mprint mlogic';

标签: sas


【解决方案1】:

如果要在宏逻辑中调用 YEAR() 或 INTNX() 等 SAS 函数,则每个函数调用都需要使用 %SYSFUNC() 宏函数来调用 SAS 函数。

所以在这个声明中:

%LET DB = %EVAL(&TARGET_DB_YEAR.*100+&TARGET_DB_MONTH.);

因为被引用的宏变量有这样的字符串:

TARGET_DB_YEAR resolves to YEAR(INTNX('MONTH', MDY(2,1,2020), 3, 'SAME'))
TARGET_DB_MONTH resolves to MONTH(INTNX('MONTH', MDY(2,1,2020), 3, 'SAME'))

而不是自 1960 年以来 SAS 用于存储日期值的实际天数,您要求 %eval() 函数执行它不理解的操作。它只能做简单的整数算术和布尔逻辑。

要循环一系列月份,只需使用带有 INTNX() 函数的起始月份的偏移量。如果要生成 YYYYMM 数字字符串,只需使用 YYMMN 格式。

所以你可以使用这样的东西:

%let start=%sysfunc(mdy(&starting_month,1,&starting_year));
%let end=%sysfunc(mdy(&ending_month,1,&ending_year));
%do offset = 0 %to %sysfunc(intck(month,&start,&end));
  %let date=%sysfunc(intnx(month,&start,&offset));
  %let db=%sysfunc(putn(&date,yymmn6.));
  ...
%end;

【讨论】:

    【解决方案2】:

    代码缺少在宏逻辑中使用函数所需的%SYSFUNC()

    SAS 应该如何知道是否应该是“INTNX”的文本值,或者您是否想将其用作函数?为了区分,除非您另有说明,否则所有内容都被解释为文本。使用 %SYSFUNC() 告诉 SAS 你想使用 SAS 函数。

    每个函数都需要包装在 %SYSFUNC() 中,因此对于嵌套函数,您需要多次调用。

    另外,在使用宏函数时,您不将参数包含在引号中,因此您需要删除 MONTH 和 SAME 参数周围的引号。

    %DO i = 0 %TO &NUM_MONTH_4.;
    
        %LET ADDITION = %EVAL(&i.+3);
    
        %LET TARGET_DB=%sysfunc(INTNX(MONTH, %sysfunc(MDY(&STARTING_MONTH.,1,&STARTING_YEAR.)), &ADDITION., S));
    
        %LET TARGET_DB_MONTH = %sysfunc(MONTH(&TARGET_DB.));
    
        %LET TARGET_DB_YEAR = %sysfunc(YEAR(&TARGET_DB.));
    
        %LET DB = %EVAL(&TARGET_DB_YEAR.*100+&TARGET_DB_MONTH.);
    
        LIBNAME TETRIS "/actuary/Commercial/Monthend/&DB.";
    
        %LET TARGET_EFF = %sysfunc(INTNX(MONTH, %sysfunc(MDY(&STARTING_MONTH.,1,&STARTING_YEAR.)), &i., S));
    
        %LET TARGET_EFF_MONTH = %sysfunc(MONTH(&TARGET_EFF.));
    
        %LET TARGET_EFF_YEAR = %sysfunc(YEAR(&TARGET_EFF.));
                        
        %PUT _ALL_;
    
    %END;   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多