代码之家  ›  专栏  ›  技术社区  ›  mrlcpa

在宏内使用数据集名称内的变量时出现SAS语法错误22和200

  •  0
  • mrlcpa  · 技术社区  · 7 年前

    我试图在SAS中使用宏中的循环对多个数据集进行排序,使用数据集名称中的数字列表,其中一些具有前导零(例如,在示例代码中 01,02 ),此代码还将指导我要构建的其他一些循环。

    从这里开始,我使用SAS指南,以宏DO循环代码循环通过非序列值列表作为起点: http://support.sas.com/kb/26/155.html .

    data dir1201;
       input compid directorid X;
       format ;
       datalines;
    01 12 11  
    02 15 5  
    ;
    run;
    
    data dir1202;
       input compid directorid X;
       format ;
       datalines;
    01 12 1  
    03 18 8  
    ;
    run;
    
    %macro loops1(values);                                                                                                         
         /* Count the number of values in the string */                                                                                                                                   
         %let count=%sysfunc(countw(&values)); 
         /* Loop through the total number of values */                                                                                         
         %do i = 1 %to &count;
          %let value=%qscan(&values,&i,%str(,)); 
          proc sort data=dir12&value out=dir12sorted&value nodupkey;
          by directorid compid;
          run;
          %end;
    %mend;
    options mprint mlogic;
    %loops1(%str(01,02))  
    

    我想 str 对于非序列列表需要,但当我想保留前导零时,这也很有用;

    我看到宏变量似乎在日志中包含了01或02,但随后我收到了错误22和200。下面是使用以下示例代码的日志错误片段:

    339  %macro loops1(values);
    340       /* Count the number of values in the string */
    341       %let count=%sysfunc(countw(&values));
    342       /* Loop through the total number of values */
    343       %do i = 1 %to &count;
    344        %let value=%qscan(&values,&i,%str(,));
    345        proc sort data=dir12&value out=dir12sorted&value nodupkey;
    346        by directorid compid;
    347        run;
    348        %end;
    349  %mend;
    350  options mprint mlogic;
    351  %loops1(%str(01,02))
    MLOGIC(LOOPS1):  Beginning execution.
    MLOGIC(LOOPS1):  Parameter VALUES has value 0102
    MLOGIC(LOOPS1):  %LET (variable name is COUNT)
    MLOGIC(LOOPS1):  %DO loop beginning; index variable I; start value is 1; stop value is 2; by
          value is 1.
    MLOGIC(LOOPS1):  %LET (variable name is VALUE)
    NOTE: Line generated by the macro variable "VALUE".
    1    dir1201
              --
              22
               --
               200
    ERROR: File WORK.DIR12.DATA does not exist.
    

    我不明白为什么 dir1201 显示,但错误引用了数据集 work.dir12 (忽略 01 )

    3 回复  |  直到 7 年前
        1
  •  2
  •   Tom    7 年前

    宏引用使解析器误以为宏引用表示新标记的开始。您可以添加 %unquote() 删除宏引用。

    proc sort data=%unquote(dir12&value) out=%unquote(dir12sorted&value) nodupkey;
    

    或者不要在开始时添加宏引用。

    %let value=%scan(&values,&i,%str(,));
    

    如果将宏设计为使用空格分隔的值,而不是逗号分隔的值,那么使用宏就会容易得多。然后,也不需要在调用中添加宏引用。

    %macro loops1(values);
    %local i value ;
    %do i = 1 %to %sysfunc(countw(&values,%str( )));
      %let value=%scan(&values,&i,%str( ));
    proc sort data=dir12&value out=dir12sorted&value nodupkey;
      by directorid compid;
    run;
    %end;
    %mend loops1;
    %loops1(values=01 02)
    
        2
  •  1
  •   mrlcpa    7 年前

    宏声明选项 /PARMBUFF 用于生成自动宏变量 SYSPBUFF 可用于扫描作为参数传递的任意数量的逗号分隔值。

    %macro loops1/parmbuff;
      %local index token;
      %do index = 1 %to %length(&syspbuff);
        %let token=%scan(&syspbuff,&index);
        %if %Length(&token) = 0 %then %goto leave1;
        proc sort data=dir12&token out=dir12sorted&token nodupkey;
        by directorid compid;
        run;
      %end;
      %leave1:
    %mend;
    options mprint nomlogic;
    %loops1(01,02)
    

    SYSPBUFF
    MACRO / PARMBUFF

        3
  •  0
  •   Reeza    7 年前

    由于你在重复日期,我认为从长远来看,这样做可能更有帮助:

    %macro date_loop(start, end);
        %let start=%sysfunc(inputn(&start, anydtdte9.));
        %let end=%sysfunc(inputn(&end, anydtdte9.));
        %let dif=%sysfunc(intck(month, &start, &end));
    
        %do i=0 %to &dif;
            %let date=%sysfunc(intnx(month, &start, &i, b), yymmdd4.);
            %put &date;
        %end;
    %mend date_loop;
    
    %date_loop(01Jan2012, 01Jan2015);
    

    这是对SAS文档(宏附录,示例11)中的版本稍作修改的版本。

    http://documentation.sas.com/?docsetId=mcrolref&docsetTarget=n01vuhy8h909xgn16p0x6rddpoj9.htm&docsetVersion=9.4&locale=en