因此,在深入讨论该问题之前,我将简要解释一下我的代码结构。
我有一个宏
%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)是原始代码流程,它工作正常。
我的问题:
我正在使用一种动态的方式为每个月生成文件名(因此每个月我都不会手动输入file_name_month和date。
文件名代码
%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的新手,请原谅我这是一个愚蠢的问题。谢谢。
答案 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, ¤t_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);
您应该可以将上述内容修改为您需要的内容。