SAS 中的宏 Do Until 循环
Macro Do Until Loop in SAS
我的循环只进行了 1 次迭代。我应该创建三个宏变量:var1 = Month1、var2 = Month2 和 var3 = Month3 if qtr = qtr1。当我用 Put 语句检查它时,我的循环只创建 var1 = Month1 和 I = 1。它只进行一次迭代,所以我不确定我做错了什么。
%Let qtr = qtr1;
%Macro Firstqtr(qtr);
%Let I = 1;
%If &qtr = qtr1 %then %do %until (&I > 3);
%Let var&I = Month&I;
%let I = %eval(&I + 1);
%end;
%Mend Firstqtr;
%Firstqtr(qtr);
问题是宏变量 scope 之一。 qtr
在全局(第 1 行)和局部(作为宏参数)定义,因此使用局部(空)代替。
尝试在您的参数中传递它,如下所示:
%Let qtr = qtr1;
%Macro Firstqtr(qtr);
%Let I = 1;
%If &qtr = qtr1 %then %do %until (&I > 3);
%global var&i;
%Let var&I = Month&I;
%put var&i=&&var&i;
%let I = %eval(&I + 1);
%end;
%mend Firstqtr;
%Firstqtr(&qtr);
请注意,您正在创建的变量将具有局部作用域 - 要使它们成为全局变量,您可以这样声明它们(%global
语句)。
您的 %DO 循环永远不会 运行 考虑到您为宏的 QTR 参数所做的输入。您可以打开 MLOGIC 来查看此内容。
1228 options mlogic;
1229 %Firstqtr(qtr);
MLOGIC(FIRSTQTR): Beginning execution.
MLOGIC(FIRSTQTR): Parameter QTR has value qtr
MLOGIC(FIRSTQTR): %LET (variable name is I)
MLOGIC(FIRSTQTR): %IF condition &qtr = qtr1 is FALSE
MLOGIC(FIRSTQTR): Ending execution.
如果您想将 qtr1 作为值传递,可以在宏调用中对其进行硬编码。
%Firstqtr(qtr1);
或者你可以让你的调用通过你之前定义的宏变量。
%let qtr=qtr1;
%Firstqtr(&qtr);
如果您使用命名参数调用宏,则参数值与同名外部宏变量值之间的区别可能会更清楚。 注意:即使对于在宏定义中定义为位置的参数,您也可以在宏调用中使用参数名称。
%Firstqtr(qtr=&qtr);
option mprint;
%global qtr;
%Let qtr = qtr1;
%Macro Firstqtr(qtr);
%Let I = 1;
%If &qtr = &qtr %then %do %until (&I > 3);
%Let var&I = Month&I;
%let I = %eval(&I + 1);
%end;
%put &var1 &var2 &var3;
%Mend Firstqtr;
%Firstqtr(qtr);
您必须将 qtr 声明为全局变量,然后只有 if 条件才会通过。
我的循环只进行了 1 次迭代。我应该创建三个宏变量:var1 = Month1、var2 = Month2 和 var3 = Month3 if qtr = qtr1。当我用 Put 语句检查它时,我的循环只创建 var1 = Month1 和 I = 1。它只进行一次迭代,所以我不确定我做错了什么。
%Let qtr = qtr1;
%Macro Firstqtr(qtr);
%Let I = 1;
%If &qtr = qtr1 %then %do %until (&I > 3);
%Let var&I = Month&I;
%let I = %eval(&I + 1);
%end;
%Mend Firstqtr;
%Firstqtr(qtr);
问题是宏变量 scope 之一。 qtr
在全局(第 1 行)和局部(作为宏参数)定义,因此使用局部(空)代替。
尝试在您的参数中传递它,如下所示:
%Let qtr = qtr1;
%Macro Firstqtr(qtr);
%Let I = 1;
%If &qtr = qtr1 %then %do %until (&I > 3);
%global var&i;
%Let var&I = Month&I;
%put var&i=&&var&i;
%let I = %eval(&I + 1);
%end;
%mend Firstqtr;
%Firstqtr(&qtr);
请注意,您正在创建的变量将具有局部作用域 - 要使它们成为全局变量,您可以这样声明它们(%global
语句)。
您的 %DO 循环永远不会 运行 考虑到您为宏的 QTR 参数所做的输入。您可以打开 MLOGIC 来查看此内容。
1228 options mlogic;
1229 %Firstqtr(qtr);
MLOGIC(FIRSTQTR): Beginning execution.
MLOGIC(FIRSTQTR): Parameter QTR has value qtr
MLOGIC(FIRSTQTR): %LET (variable name is I)
MLOGIC(FIRSTQTR): %IF condition &qtr = qtr1 is FALSE
MLOGIC(FIRSTQTR): Ending execution.
如果您想将 qtr1 作为值传递,可以在宏调用中对其进行硬编码。
%Firstqtr(qtr1);
或者你可以让你的调用通过你之前定义的宏变量。
%let qtr=qtr1;
%Firstqtr(&qtr);
如果您使用命名参数调用宏,则参数值与同名外部宏变量值之间的区别可能会更清楚。 注意:即使对于在宏定义中定义为位置的参数,您也可以在宏调用中使用参数名称。
%Firstqtr(qtr=&qtr);
option mprint;
%global qtr;
%Let qtr = qtr1;
%Macro Firstqtr(qtr);
%Let I = 1;
%If &qtr = &qtr %then %do %until (&I > 3);
%Let var&I = Month&I;
%let I = %eval(&I + 1);
%end;
%put &var1 &var2 &var3;
%Mend Firstqtr;
%Firstqtr(qtr);
您必须将 qtr 声明为全局变量,然后只有 if 条件才会通过。