在defineKey

时间:2018-02-08 10:30:09

标签: sas sas-macro

我正在尝试围绕此question

的解决方案构建一个宏

我在这里可重现的示例没有做任何有用的事情,只是为了突出我得到的语法错误。

rc = mx.defineKey(&groups)行适用于第一种情况,执行rc = mx.defineKey('grp1','grp2')

然而,在第二种情况下,我以不同的方式定义&groups但是针对相同的值,它失败并出现错误:

  

注意:由宏变量“GROUPS”生成的行。 21个
  'GRP1', 'GRP2'              _              386               _               200               76 MPRINT(TEST2):rc = mx.defineKey('grp1','grp2');错误:数据步骤组件对象失败。在期间中止   编译阶段。错误386-185:期待算术表达式。

     

ERROR 200-322:符号无法识别,将被忽略。

     

ERROR 76-322:语法错误,语句将被忽略。

以下是非工作示例的工作示例。我想:

  • 了解为什么第二种情况不起作用
  • 通过groups以适当的方式定义grp_list来使其发挥作用。

可重现的代码:

data have;
input grp1 $ grp2 $ number;
datalines;
a c 3
b d 4
;

%macro test;
data want;
set have;
if _n_ = 1 then do;
    declare hash mx();
    %let groups = 'grp1','grp2';
    %put rc = mx.defineKey(&groups);
    %put rc = mx.defineKey('grp1','grp2');
    rc = mx.defineKey(&groups);
    rc = mx.definedata('number');
    rc = mx.definedone();
end;
run;
%mend;

%test

%macro test2;
data want;
set have;
if _n_ = 1 then do;
    declare hash mx();
    %let grp_list = grp1 grp2;
    %let groups = %str(%')%qsysfunc(tranwrd(&grp_list,%str( ),%str(%',%')))%str(%');
    %put rc = mx.defineKey(&groups);
    %put rc = mx.defineKey('grp1','grp2');
    rc = mx.defineKey(&groups);
    rc = mx.definedata('number');
    rc = mx.definedone();
end;
run;
%mend;

%test2

3 个答案:

答案 0 :(得分:2)

您需要删除宏引用,因为它会添加不正确的控制字符,这会破坏您的哈希定义。将相关行更改为:

rc = mx.defineKey(%unquote(&groups));

您也可以考虑定义一个单独的宏来引用每个列表项,并使用双引号而不是单引号,例如。

%macro quotelist(list);
  %local i word;
  %do %while(1);
    %let i = %eval(&i + 1);
    %let word = %scan(&list,&i,%str( ));
    %if &word = %then %return;
%sysfunc(quote(&word)) /*De-indent to avoid adding extra spaces*/
  %end;
%mend;

%put %sysfunc(translate(%quotelist(a b c),%str(,),%str( )));

这避免了与在单引号内解析宏变量相关的额外麻烦。

答案 1 :(得分:1)

不要将宏逻辑嵌入DATA步骤的中间。它可能会让您误以为它在数据步骤运行时运行而不是像数据步骤那样在数据步骤之前运行。

为什么要跳过篮球来添加单引号?只需使用双引号。

%macro test2;
%let grp_list = grp1 grp2;
%let groups = "%sysfunc(tranwrd(&grp_list,%str( ),"%str(,)"))";
%put rc = mx.defineKey(&groups);
%put rc = mx.defineKey("grp1","grp2");
data want;
  set have;
  if _n_ = 1 then do;
    declare hash mx();
    rc = mx.defineKey(&groups);
    rc = mx.definedata("number");
    rc = mx.definedone();
  end;
run;
%mend test2;

答案 2 :(得分:0)

此问题是由于宏报价引起的。当你通过put打印它时,它很好。但是,当您使用defineKey方法调用它时。 SAS解析器可以看到其他引用。这就是在执行之前你在复杂阶段失败的方法。 (符号无法识别 - 即宏引用)。如果删除宏引用,它将起作用。

%macro test2;
data want;
set have;
if _n_ = 1 then do;
    declare hash mx();
    %let grp_list = grp1 grp2;
    %let groups = %str(%')%qsysfunc(tranwrd(&grp_list,%str( ),%str(%',%')))%str(%');
    %put rc = mx.defineKey(&groups);
    %put rc = mx.defineKey('grp1','grp2');
    rc = mx.defineKey(%unquote(&groups));
    rc = mx.definedata('number');
    rc = mx.definedone();
end;
run;
%mend;