宏的名称/标题作为宏SAS内的变量

时间:2015-06-18 15:02:00

标签: sas

我正在尝试使用PARMBUFF宏来重复具有20个不同客户端定义的数据步骤(下面的一个示例)。

DATA _NULL_;
%GLOBAL bank1;
%LET bank1 = O.OWNER LIKE 'XXXXX%';
RUN;

数据步骤将创建由上面创建的客户端宏变量定义的单独表。

%MACRO CLIENTBUILD/PARMBUFF; 
%LET N=%SYSFUNC(COUNTW(&SYSPBUFF,%STR(,)));
%DO I=1 %TO &N;
  %LET CLIENT=%SCAN(%QSYSFUNC(COMPRESS(%BQUOTE(&SYSPBUFF),%STR(%(%)))),&I,%STR(,));
CREATE TABLE CLIENT AS
SELECT DISTINCT C.DATE,
            C.TIME,
            C.RELEASE,
            C.TASK
FROM CALLS C
INNER JOIN OWN_GRNT O ON SUBSTR(C.TASK,1,9)= O.TASK 
AND    &CLIENT
;
%END;
%MEND;

我想用宏的NAME(String)创建这个表...但是我在引用表的名称的宏字符串时遇到了问题。 我尝试按如下方式重新格式化宏(为了尝试并使用

调出表的名称的宏的字符串/名称)
%MACRO CLIENTBUILD/PARMBUFF; 
%LET N=%SYSFUNC(COUNTW(&SYSPBUFF,%STR(,)));
%DO I=1 %TO &N;
  %LET CLIENT=%SCAN(%QSYSFUNC(COMPRESS(%BQUOTE(&SYSPBUFF),%STR(%(%)))),&I,%STR(,));
CREATE TABLE '&CLIENT' AS
SELECT DISTINCT C.DATE,
                C.TIME,
                C.RELEASE,
                C.TASK
FROM CALLS C
INNER JOIN OWN_GRNT O ON SUBSTR(C.TASK,1,9)= O.TASK 
AND    &CLIENT
;
%END;
%MEND;
Then calling the macro out with – 
PROC SQL;
%CLIENTBUILD(&NCT);
QUIT;

但这会导致错误:

ERROR: The value &CLIENT is not a valid SAS name.`

是否有解决方案来调出依赖于用于定义客户端的宏变量的宏标题?一旦解决,我想用....创建每个客户端数据集

Proc SQL; 

%CLIENTBUILD(&bank1,&bank2,&bank3,..........);

QUIT;

2 个答案:

答案 0 :(得分:3)

首先,一个建议。不要以这种方式构建您的应用程序。这是一个非常混乱和冒险的方法。您正在使用应该是参数的全局宏变量,并且您正在尝试文本解析这些宏变量的名称列表。

以这种方式编写宏:

%macro maketable(table=,where=);
  proc sql;
    create table &table. as 
      ...
      where &where.;
  quit;
%mend maketable;

然后从存储WHERE子句的数据集中构造对%maketable的调用(我假设这不仅仅是开放代码?如果是,请通过excel将其放入数据集中。)

proc sql;
  select cats('%maketable(table=',tablename,',where=%nrstr(',whereclause,'))'
     into :tablecall separated by ' '
     from my_whereclause;
quit;

然后在下一行添加&tablecall.,当您运行它时,您将获得所有表格。

(顺便说一句,你可能甚至不能制作20张桌子,但是制作1张桌子,其中20个值是变量 - 但是你没有解释你在这之后做了什么,所以很难告诉。)

如果必须这样做,您需要了解宏变量解析的工作原理。有关此问题的解释,请参阅my answer here,或有关此主题的my SGF paper。 SAS文档也非常擅长解释这一点。

基本上,您需要单独解析表名&table以定义表名,然后多次解析它以获取where子句。

以下是使用sashelp.class的示例。

%let abc= age gt 13;
%let def= age lt 13;
%let ghi= age eq 13;
%macro doit/parmbuff;
    %LET N=%SYSFUNC(COUNTW(&SYSPBUFF,%STR(,)));
    %DO I=1 %TO &N;
      %LET CLIENT=%SCAN(%QSYSFUNC(COMPRESS(%BQUOTE(&SYSPBUFF),%STR(%(%)))),&I,%STR(,));
      %PUT &=CLIENT;

      proc sql;
        create table &client. as 
            select * from sashelp.class
            where &&&client.;
      quit;
    %end;
%mend doit;

%doit(abc,def,ghi);

&&&client&client解析为abc,然后在那里留下&符号(&abc) - 然后解析,然后将&abc解析为value(where子句)。

答案 1 :(得分:0)

您不需要为此类应用程序使用PARMBUFF。只是不要使用逗号作为分隔符。例如,您可以使用空格或|如下例所示。

%macro doall(list);
  %local i item ;
  %do i=1 %to %sysfunc(countw(&list,|));
    %let item=%scan(&list,&i,|);
    ... process current item ...
  %end;
%mend doall ;
%doall(A|B|C|D);