我希望创建一个循环,以便为每个数据集运行两个宏
%Let Classification = Data1 data2 data3 data4;
%let index = 1;
%do %until (%Scan(&Classification,&index," ")=);
%Macro1;
%Macro2;
%end;
%let index = %eval(&Index + 1);
问题是我的宏没有预先加载并存储在宏库中,如果我将上面的宏作为宏运行,是否可以这样做?
任何建议都值得使这个宏循环工作
编辑:
在我理想的情况下,循环会像宏一样运行
%Macro;
里面看起来像
%Macro Macro;
%let index = 1;
%do %until (%scan(&classification,&index," ")=);
<Lines of Code>
%end;
%let index = %eval(&Index + 1);
%end;
%mend;
另一个问题是循环中包含的宏使用&amp;分类来区分data1,data2,data3,data4,因为我们处理不同的代码行。
答案 0 :(得分:3)
迭代索引可能更容易。使用countw()
函数查找要执行的迭代次数。
%macro loop(list);
%local index next ;
%do index=1 %to %sysfunc(countw(&list,%str( )));
%let next=%scan(&list,&index,%str( ));
... code to process &NEXT ...
%end;
%mend ;
然后将列表作为参数值传递给宏。
%Let Classification = Data1 data2 data3 data4;
%loop(&classification);
答案 1 :(得分:2)
SAS不允许在开放代码中使用%DO
语句。当您提交开放代码循环时,您将获得日志消息
ERROR: The %DO statement is not valid in open code.
...
ERROR: The %END statement is not valid in open code.
@Tom提到宏%SCAN
测试应该检查空字符串。另一种常见且更健壮的方法是在令牌提取之前进行检查。当分类传递为空时,%do %until
将很难迭代。 %do %while
在内部宏调用之前测试classification
扫描。 null宏值的另一个常见测试是检查0长度并利用0 = false ^ 0 =真正的自动评估。
当循环要使用标记值调用其他宏时,最佳做法是传递标记值,而不是让被调用的宏假定在迭代之前已存在标记符号(也就是宏变量)(在包含的范围内)宏调用。
示例
%macro mydispatch (classification=);
%local index token;
%let index = 1;
%do %while ( %length (%scan (&classification, &index)));
%let token = %scan(&classification,&index));
%* emit code specifically for token;
* this is for &token;
%* iterated invocations, perform two analysis for each data set listed in classification;
%* second analysis is passed another argument specifying the data set that should be used to store output;
%analysis_1 (data=&token)
%analysis_2 (data=&token, out=WORK.results_&token.)
%let index = %eval(&index+1);
%end;
%mend mydispatch;
%mydispatch (classification=data1 data2 data3 data4)
答案 2 :(得分:1)
宏在自动调用库中(我假设你指的是什么?)对上面的工作方式没有任何影响。如果它不在自动调用库中,您必须首先将目录连接到自动调用库。
重新:你的编辑;是的,你需要将它放在一个宏中(我假设它最初是一个宏的子集)。目前,开放代码中不允许%do
(这可能会改变,但今天不会改变)。
请注意,您的代码中存在几个重要问题:
扫描功能错误;宏语言不使用引用,所以
%do %until (%Scan(&Classification,&index," ")=);
需要
%do %until (%Scan(&Classification,&index)=);
(空格是默认的分隔符),如果你真的需要澄清空间:
%do %until (%Scan(&Classification,&index,%str( ))=);
您的宏不使用参数;他们应该。 %macro1;
显然使用&classification
和&index
;相反,你应该把你想要的东西(&#34;单词&#34;来自&classification
)作为参数传递给它。