SAS 在 do 循环和 if 语句中调用符号不起作用



我需要根据宏的输入定义一个名为test_var的变量。以下是我试图在 SAS 中实现的目标的简化版本:

%macro testing(blah);
%if &blah. = 1 %then %do;
data _null_;
call symput('test_var',"a1");
run;
%end;
%mend;
%testing(1);
%put &test_var.;

但是我收到错误:警告:明显的符号引用TEST_VAR未解决。

这是一个宏变量范围的简单问题。您正在宏 TESTING 中定义宏变量,并尝试在宏停止运行后引用它。

如果您尝试设置的宏变量尚不存在,则将在本地范围内定义它。因此,要么在调用宏之前定义宏变量,要么让宏创建一个全局宏变量而不是局部宏变量。

您可以使用 %SYMEXIST(( 宏函数来检查是否需要将宏定义为全局宏,然后使用 %GLOBAL 语句在全局范围内定义它。

%if not %symexist(test_var) %then %global test_var;

此外,如果您切换到使用较新的 CALL SYMPUTX(( 函数而不是旧样式的 CALL SYMPUT(( 函数,您可以使用可选的第三个参数来告诉它强制全局符号表中的宏变量,而不是遵循正常的范围规则。

call symputX('test_var',"a1",'g');

PS:你也没有告诉宏变量BLAH来自哪里。它不是参数,也没有在任何 %LOCAL 或 %GLOBAL 语句中定义。我个人认为在宏代码中使用这种类型的"魔术"宏变量是一种糟糕的编码风格,可能会导致维护问题。 至少添加有关其来源的评论。 或者使用 %SYMEXIST(( 函数在引用它之前确保它存在。

您可以通过以下两种方式之一解决此问题:

  1. 在运行宏之前定义&test_var,例如%let test_var=;.
  2. 将其声明为宏中的全局宏变量,例如%global test_var;

最新更新