1

我是一个业余的sas用户,所以请原谅我缺乏词汇!

%macro wtv(n);
var&n = 1;
%mend; 

do while (n < 10);
n+1;
%wtv(n); /*here's the problem I think*/
end;

想法是这样的:我想n在我的宏输入中使用(注释所在的位置)。代码显然只是一个简化的示例,这不是我想要做的,但你明白了!调用宏时如何使用变量(n例如)?我刚刚写的代码将使用 n 作为字符,并返回varn = 1, 而不是var1 = 1, var2 = 1, var3 = 1... var9 = 1

非常感谢!

4

2 回答 2

3

作为一个业余爱好者,你首先需要了解的是宏的几条规则:

  1. 宏输出文本/代码。
  2. 宏在代码运行/编译/提交之前运行。
  3. 始终尝试了解“宏观领域”中的内容以及“数据步骤领域”中的内容。因为“宏观土地”中的所有内容都会先计算出来,然后将其结果作为“数据步土地代码”输出并运行。如果您尝试从宏中的“数据步域”引用变量,您将遇到问题,因为宏不知道/看不到“数据步域”。

那么你的例子出了什么问题?

您的“do while”循环位于数据步骤中。“%wtv(n)”在宏域中,在数据步骤代码之前运行。

宏将输入文本“n”视为其参数,并尽职尽责地写出:

varn = 1; 

n 已被 &n 替换,因为文本“n”作为宏变量“&n”的值输入。宏地运行完毕,剩下的代码如下:

do while (n < 10);
n+1;
varn = 1;
end;

此代码尽职尽责地执行,但“varn = 1;” 将在 while 循环的每次迭代中保持不变,这可能不是您想要发生的。

那么你想要发生什么?如果您想使用代码来遍历由 n 索引的变量,请使用类似于 Hong Ooi 建议的响应的数组。一般来说,我的建议是在常规代码足够的情况下不要使用宏。

但是,出于某种有效的原因,您实际上想要使用宏循环魔法的可能性很小。它发生了。如果是这种情况,也许您不想要一个数据步骤“do while”循环,而是一个宏循环。在这种情况下,您的 wtv 宏可能会变为:

%macro wtv(n);
%local i;  /* explicit declarations are a good habit to get into */
%let i = 1;
%do %while (&i <= &n); 
var&i = 1;
%let i = %eval(&i + 1);
%end;
%mend wtv;  /* explicitly named mend statements are also good */ 

现在,您可以调用 %wtv(5),它应该解析为数据步骤代码:

var1 = 1;
var2 = 1;
var3 = 1;
var4 = 1;
var5 = 1;

您只需为其提供一个可观的数字并将其包含在数据步骤中,但缺点是您需要在不引用数据步骤变量的情况下执行此操作。因为宏在数据步骤之前运行,所以它们不能在运行时使用从数据步骤中获得的信息来驱动自己的操作。

如果您在编写代码时已经知道这个数字,那么您就大功告成了。在这种情况下,您根本不需要数据步骤“do while”循环或数组。

于 2013-08-10T00:23:04.610 回答
2

您不需要为此使用宏。请改用数组。

data;
    array var{9} var1-var9;
    do i=1 to 9;
       var{i} = 1;
    end;
    ...

事实上,你甚至不需要循环;您可以直接在array语句中初始化变量。

    array var{9} var1-var9 (9*1);
于 2013-08-09T22:13:29.780 回答