Sas 基于宏创建表的问题';s参数名

Sas 基于宏创建表的问题';s参数名,sas,Sas,因此,在深入讨论这个问题之前,我将简要解释我的代码结构 我有一个宏 %Sales (Outdata= , dt =, Outdata2= , Outdata3= ); ( I create a table &outdata by (Select * from XYZ); Proc SQL; Create table &Outdata._1 as ( ) %mend Sales 现在我调用宏 %Sales (Outdata = sales_final_

因此,在深入讨论这个问题之前,我将简要解释我的代码结构

  • 我有一个宏

    %Sales (Outdata= , dt =, Outdata2= , Outdata3= );
    (
      I create a table &outdata by (Select * from XYZ);
      Proc SQL;
      Create table &Outdata._1 as 
      (  
      )
    %mend Sales
    
  • 现在我调用宏

    %Sales (Outdata = sales_final_Oct17, dt='2017-10-01');
    
    Libname ABCDEFG
    
  • 我创建了一个数据集

     Data ABCDEFG.all_sales_test;
     Set  ABCDEFG. all_Sales
     sales_final_Oct17_1;
     incur_month = month(rept_dt);
     run;
    
    以上(1到3)是原始代码流,工作正常

    我的问题是:

    我使用动态方式为每个月生成文件名(这样每个月我就不会手动输入文件名、月份和日期)

  • 文件名代码

    %let Last_Month = intnx('month', current_date,-1, "beginning");
    Name = 'Sales_final';
    Last_Month_Name = name|| put(&last_month, monyy7.);
    Call SYMPUTX('Last_Month_Name_v', Last_Month_Name);
    run;
    
  • 调用宏

        %Sales(outdata=&Last_Month_Name, dt = 'Dynamic date');
    
    到目前为止,一切正常。当我创建一个类似于步骤3(上面)的数据集时,代码就中断了

        Libname ABCDEFG
    
        Data ABCDEFG.all_sales_test;
        Set  ABCDEFG.all_Sales
        Last_Month_Name_1;
        incur_month = month(rept_dt);
        run;
    > Error Message: File ABCDEFG.LAST_MONTH_NAME_1.DATA does not exist.
    
    我应该怎么做才能消除这个错误呢?似乎,如果我在宏中传递一个静态名称,然后使用与“_1”相同的名称,它工作得很好,但是当我传递动态引用时,数据集步骤失败,出现上述错误消息


    非常感谢您的帮助。我是SAS的新手,如果这是一个愚蠢的问题,请原谅。谢谢。

    使用宏是SAS中较难的部分之一,对新手来说可能会非常困惑。下面是一个简单的工作示例,演示了我将采取的方法

    首先,我们动态计算要将结果保存到的表的名称:

    %let current_date = %sysfunc(date());
    %let last_month = Sales_final_%sysfunc(intnx(month, &current_date, -1, beginning), monyy7.);
    %put &=last_month;
    
    上述步骤中的
    put
    语句的输出为:

    LAST_MONTH=Sales_final_OCT2017
    
    注意,在上面的代码中,我将两个参数传递给
    %sysfunc()
    。第一个参数是对
    intnx()
    函数的调用。第二个参数(
    monyy7.
    )是应用于函数调用返回的结果的格式

    还请注意,不需要将前缀(
    Sales\u final\uu
    )连接到
    %sysfunc()
    结果,因为在使用宏语言时,
    %sysfunc()的结果
    已替换到位。宏语言中根本没有连接运算符-所有操作都基于宏替换

    然后是将该值传递到宏的简单情况,如下所示:

    %macro sales(outdata=);
      proc sql;
        create table &outdata._1 as select * from sashelp.class;
      quit;
    %mend;
    
    %sales(outdata=&last_month);
    
    您应该能够根据需要修改上述内容。

    在(1)中,宏代码使用宏参数(或本地宏变量)
    OUTDATA
    的值来创建数据集。在(2)中,您在调用和(3)中为
    OUTDATA
    提供值在
    set
    语句中再次使用相同的值

    一种不必输入两次值的方法是将值存储到宏变量中,然后在步骤(2)和(3)中引用该宏变量的值

    因此,在第(4)段中您确实创建了一个宏变量,
    Last\u Month\u Name\u v
    ,但随后在宏调用中使用了另一个宏变量的值,
    &Last\u Month\u Name
    。但是您没有在
    set
    语句中使用宏变量,而是引用了一些以前从未提到的其他数据集,
    Last\u Month\u Name\u 1
    你一点也不担心

    以下是创建和使用宏变量过程中的简化关键步骤。我加入了
    ,以说明我遗漏了一条或多条语句的某些部分,因此我们可以专注于宏变量的流程及其值

    首先,将宏变量设置为您想要使用的某个名称。让我们使用
    anything
    作为本例的名称

    %let last_month_name= anything;
    
    然后使用宏调用中的值来创建数据集。请注意名称前的
    &
    ,这就是告诉宏处理器用值替换名称的原因。名称后的句点告诉宏处理器宏变量名称的结尾

    %sales(outdata=&last_month_name.  .... )
    
    然后,当您想告诉
    set
    语句要读取哪个数据集时,可以稍后再次使用该值

    set .... &last_month_name. ;
    
    现在,您发布的宏
    %sales
    实际上并没有创建名为
    anything
    的数据集。相反,它似乎创建了名为
    anything\u 1
    的数据集。我个人不知道为什么会出现这种情况,但如果保持这种方式,则需要将
    \u 1
    添加回
    中宏变量值的末尾>设置
    语句。只需按照与宏代码相同的方式执行即可

    set .... &last_month_name._1 ;
    

    Last\u Month\u Name
    宏变量的值是多少?运行
    %put&Last\u Month\u Name.
    将把值打印到日志中。我看到您只创建变量
    Last\u Month\u Name\u v
    。供将来参考,您的问题包含了大量不需要的信息。为了更快/更好地响应堆栈溢出建议提供一个其他人可以运行的简单示例,并包含演示或重新创建问题所需的最少信息量。非常感谢Robert!非常感谢!!