Sas 循环一组宏

Sas 循环一组宏,sas,sas-macro,Sas,Sas Macro,我希望创建一个循环,以便为每个数据集运行两个宏 %Let Classification = Data1 data2 data3 data4; %let index = 1; %do %until (%Scan(&Classification,&index," ")=); %Macro1; %Macro2; %end; %let index = %eval(&Index + 1); 问题是我的宏不是预加载的,而是存储在宏库中,如果我将上述宏作为宏运行,

我希望创建一个循环,以便为每个数据集运行两个宏

%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;

另一个问题是循环中包含的宏在处理不同的代码行时使用&分类来区分data1、data2、data3、data4。

宏位于自动调用库中,我假设您所指的是什么?对上述工作方式没有任何影响。如果它不在自动调用库中,则必须首先将目录连接到自动调用库

在re:你的编辑;是的,您需要将其放在宏中。我最初假设它是宏的子集开放代码中当前不允许do。这可能会更改,但今天不允许

请注意,您的代码中有几个重要问题:

增量门不在循环中 扫描功能错误;宏语言不使用引号,因此

%执行%直到%扫描、分类和索引=

需要

%执行%直到%扫描、分类和索引=

空格是默认分隔符,如果确实需要澄清空格:

%执行%直到%扫描、分类和索引,%str=

宏不使用参数;他们应该这样做宏1;明确使用分类和索引;相反,您应该将希望单词来自的东西&分类作为参数传递给它


宏在自动调用库中,我想您指的就是这个库?对上述工作方式没有任何影响。如果它不在自动调用库中,则必须首先将目录连接到自动调用库

在re:你的编辑;是的,您需要将其放在宏中。我最初假设它是宏的子集开放代码中当前不允许do。这可能会更改,但今天不允许

请注意,您的代码中有几个重要问题:

增量门不在循环中 扫描功能错误;宏语言不使用引号,因此

%执行%直到%扫描、分类和索引=

需要

%执行%直到%扫描、分类和索引=

空格是默认分隔符,如果确实需要澄清空格:

%执行%直到%扫描、分类和索引,%str=

宏不使用参数;他们应该这样做宏1;明确使用分类和索引;相反,您应该将希望单词来自的东西&分类作为参数传递给它

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%直到将很难迭代。%do%在调用内部宏之前测试分类扫描。空宏值的另一个常见测试是检查0长度并利用0=false^0=true自动计算

当循环使用令牌值调用其他宏时,最佳做法是传递令牌值,而不是让被调用的宏假定在迭代宏调用之前,令牌符号aka宏变量已经存在于包含范围中

范例

%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)
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%直到将很难迭代。%do%在调用内部宏之前测试分类扫描。空宏值的另一个常见测试是检查0长度并利用0=false^0=true自动计算

当循环使用令牌值调用其他宏时,最佳做法是传递令牌值,而不是让被调用的宏假定在迭代宏调用之前,令牌符号aka宏变量已经存在于包含范围中

范例

%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)

在索引上迭代可能更容易。使用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);

在索引上迭代可能更容易。使用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);

嗨,我正在编辑我的问题来更好地解释我自己。我们可以再深入研究一下这个答案吗?在我的宏中,我需要它一次只运行一个来自&Classification的单词,我该怎么做呢?听起来很不错
好像你需要读一些关于宏语言的基础知识;您在这里描述的是基本功能。读几篇基本的论文或一本基本的宏观书籍,如果你还有问题就回来。像宏观参数这样的东西被掩盖了,比零碎的问题容易得多。嗨,我正在编辑我的问题来更好地解释我自己。我们可以再深入探讨一下这个答案吗?在我的宏中,我需要它一次只运行一个来自&Classification的单词,我将如何进行呢?听起来你需要阅读一些关于宏语言的基本入门知识;您在这里描述的是基本功能。读几篇基本的论文或一本基本的宏观书籍,如果你还有问题就回来。像宏观参数这样的东西被很好地涵盖了,而且比零碎的问题更容易理解。