我只有宏%IF%ELSE的问题。 我必须设置开关" Y"或" N" (更多将来)这个变量运行不同的代码部分。 例如:
data REKORD_RACH;
input id_wsadu dept $;
datalines;
1 Sales
2 Acctng
3 eeeaa
4 ffff
;
%LET Czy_Max = 'Y'; /*<=============================== SWITCH*/
OPTION MPRINT;
option compress=yes validvarname=any;
%macro Set_id_wsadu(Czy_Max);
%if &Czy_Max. = 'N' %then
%do;
%let id_wsadu = 3;/*Tu wpisujemy ręcznie id wsadu które nas interesuje*/
%end;
%else %if &Czy_Max. = 'Y' %then
%do;
Proc SQL NOPRINT;
Select MAX(id_wsadu) Into :id_wsadu
From Work.REKORD_RACH;
quit;
%end;
%mend;
%Set_id_wsadu;
%put &id_wsadu;
PROC SQL;
CREATE TABLE REKORD_RACH_GET AS
SELECT *
FROM REKORD_RACH
WHERE ID_WSADU = &id_wsadu
;QUIT;
但是Sas指南向我展示了这些日志:
54 %mend;
55 %Set_id_wsadu;
56
57 %put &id_wsadu;
WARNING: Apparent symbolic reference ID_WSADU not resolved.
&id_wsadu
我应该怎么做才能让它发挥作用?
答案 0 :(得分:2)
首先,您需要将%global id_wsadu;
添加到宏中。这将使宏值在宏外部解析。然后,您需要通过传递参数,例如%Set_id_wsadu('Y')
来正确调用您的宏。这里:
%macro Set_id_wsadu(Czy_Max);
%global id_wsadu;
%if &Czy_Max. = 'N' %then
%do;
%let id_wsadu = 3;/*Tu wpisujemy ręcznie id wsadu które nas interesuje*/
%end;
%else %if &Czy_Max. = 'Y' %then
%do;
Proc SQL NOPRINT;
Select MAX(id_wsadu) Into :id_wsadu
From Work.REKORD_RACH;
quit;
%end;
%mend;
%Set_id_wsadu('Y');
%put &id_wsadu;
PROC SQL;
CREATE TABLE REKORD_RACH_GET AS
SELECT *
FROM REKORD_RACH
WHERE ID_WSADU = &id_wsadu.;
QUIT;
答案 1 :(得分:2)
您遇到宏变量范围问题以及宏变量值的混淆。
首先,您定义了一个全局宏变量(因为您在任何特定宏范围之外运行了%let
)。
%LET Czy_Max = 'Y';
然后,您定义了一个使用相同宏变量名称作为参数的宏。
%macro Set_id_wsadu(Czy_Max);
这将创建一个名为Czy_Max
的本地宏变量,该变量将隐藏具有相同名称的全局宏变量的值。您可以通过在调用时将全局宏变量的值传递到宏中来使此设置工作。像这样:
%Set_id_wsadu(&Czy_Max);
虽然为全局和本地宏变量使用不同的名称可能不那么令人困惑。
其次,您要为宏内部的宏变量设置一个值,而没有明确定义SAS是否应该将该宏变量视为本地或全局。
%let id_wsadu = 3;
如果该变量运行时宏变量id_wsadu
已存在,则其值将更新。否则,它将导致创建一个本地宏变量,该宏将在宏完成运行时停止存在。您可以通过确保在调用宏之前定义宏变量来解决此问题。
%let id_wsadu = ;
%Set_id_wsadu(&Czy_Max);
或者您可以在宏中添加%global
语句,以在为其分配值之前在全局符号表中定义宏变量。但是,如果从另一个已经将该宏变量创建为本地的宏调用此宏,则会导致问题。您不能使用与现有本地宏变量同名的新全局宏变量。为了防止该错误,您可以在将宏变量设置为全局之前测试该宏变量是否已存在。像这样:
%if not %symexist(id_wsadu) %then %global id_wsadu;
最后,为什么要在宏变量的值中添加引号?看起来你一直这样做,所以代码应该工作,但这可能意味着你不明白引号实际上是宏变量值的一部分。这与需要引号的SAS代码不同,因此编译器知道字符串文字,数字文字和变量名称或SAS关键字之间的区别。因此,在SAS代码中,文字周围的引号不是值的一部分。
因此,在数据步骤中,您可以使用不同的外部引号运行这样的代码,文字将匹配。
if 'A' = "A" then
但是在宏代码中,引号是值的一部分,所以如果你尝试了这段代码:
%if 'A' = "A" %then
这两个值不同,因为'
不等于"
。