问题基于宏的参数名称创建表

时间:2017-11-07 20:54:39

标签: sas

因此,在深入讨论该问题之前,我将简要解释一下我的代码结构。

  1. 我有一个宏

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

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

     Data ABCDEFG.all_sales_test;
     Set  ABCDEFG. all_Sales
     sales_final_Oct17_1;
     incur_month = month(rept_dt);
     run;
    

    以上(1到3)是原始代码流程,它工作正常。

    我的问题:

    我正在使用一种动态的方式为每个月生成文件名(因此每个月我都不会手动输入file_name_month和date。

  4. 文件名代码

    %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;
    
  5. 调用宏

        %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的新手,请原谅我这是一个愚蠢的问题。谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

所以在(4)中你确实创建了一个宏变量Last_Month_Name_v,但是你在宏调用中使用了另一个宏变量&Last_Month_Name的值。但是,您没有在set语句中使用宏变量,而是引用了之前从未提及过的其他数据集Last_Month_Name_1

以下是您希望如何创建和使用宏变量的简化关键步骤。我已经放入...来显示我遗漏了一些或多个语句的部分,以便我们可以专注于宏变量及其值的流程。

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

%let last_month_name= anything;

然后使用宏调用中的值创建数据集。请注意名称前面的&,即告诉宏处理器用名称替换名称。名称后面的句点告诉宏处理器这是宏变量名称的结尾。

%sales(outdata=&last_month_name.  .... )

然后,当您想要告诉set语句要读取哪个数据集时,您可以稍后再次使用该值。

set .... &last_month_name. ;

现在,您发布的宏%sales实际上并未创建名为anything的数据集。相反,它似乎创建了一个名为anything_1的数据集。我个人不知道为什么会这样,但如果你保持这种方式,那么你需要将_1添加回set语句中宏变量值的末尾。只需按照宏代码中的相同方式进行操作即可。

set .... &last_month_name._1 ;

答案 1 :(得分:0)

使用宏是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_final_)连接到%sysfunc()结果,因为在使用宏语言时,%sysfunc()的结果将被替换。宏语言中根本没有连接运算符 - 一切都基于宏替换。

然后将这个值传递给宏的一个简单例子如下所示:

%macro sales(outdata=);
  proc sql;
    create table &outdata._1 as select * from sashelp.class;
  quit;
%mend;

%sales(outdata=&last_month);

您应该可以将上述内容修改为您需要的内容。