文字包含不匹配的引号.(SAS)



我正在尝试获取宏变量中传递的值,并在其周围加引号。即,从空格分隔的列表到空格分隔的带引号列表。例如下面给出的。我使用了Jeff在我之前的一篇文章中给出的以下方法。

data test;
   id =1; _var="ABC"; output;
   id =1; _var="DEF"; output;
   id =1; _var="UVW"; output;
   id =2; _var="UVW"; output;
   id =3; _var="ABC"; output;
   id =3; _var="UVW"; output;
   id =3; _var="XYZ"; output;
   id =4; _var="ABC"; output;
   id =4; _var="XYZ"; output;
run;
%macro __test1(_byvar=, _qnam=, _id=);
    proc sort data= test out=_test;
        by &_byvar.;
  %if %superq(_qnam) ne %then
  %do; 
            %let __tmpmv_qnam = %qsysfunc(prxchange(%bquote(s/b/"/),-1,%bquote(&_qnam))); 
            *";
            %put ^^^^^&__tmpmv_qnam.;
      where upcase(&_id) in (&__tmpmv_qnam);
  %end;
    run;
%mend;
%__test1 (_byvar=id ,_qnam = ABC UVW, _id=_var);

日志显示以下错误:

SYMBOLGEN:  Macro variable _QNAM resolves to ABC UVW  
ERROR: Literal contains unmatched quote.

请帮我解决这个问题。

这里有一种添加引号的替代方法。这是非常基本的-它不检查输入是否已经被引用,列表项之间必须正好有1个空格,输入列表中不能有前导或尾随空格,但你可以根据自己的需求进行调整:

%let list = a b c;
%macro qlist(LIST);
%sysfunc(compbl(
%do i = 1 %to %eval(%sysfunc(count(&LIST, %str( ))) + 1);
    "%scan(&LIST,&i)" %str( )
%end;
))
%mend qlist;
%put %qlist(&list);

通过使用%str()函数,您可以在宏中拥有不匹配的引号,如:

%str(%')         <-- gives an unmatched single quote
%str(%")         <-- gives an unmatched double quote

我已经将此应用于您的宏,并对其进行了一点重组/简化。首先,您将看到我删除了多余的%bquote()函数,并将%qsysfunc()更改为仅%sysfunc()

我还在为where子句构建字符串,并将其保存到宏变量中,这样排序语句就更突出,where子句的结果也更容易调试。

%macro __test1(_byvar=, _qnam=, _id=);
  %local list where_clause;
  %if %length(_qnam) gt 0 %then%do; 
      %let list = %sysfunc(prxchange(s/b/%str(%")/,-1,&_qnam)); 
      %let where_clause = where upcase(&_id) in (&list);
  %end;
  proc sort data= test out=_test;
      by &_byvar.;
      &where_clause;
  run;
%mend;

你似乎让问题变得更难了。为什么不直接使用INDEXW()函数呢?

where indexw(symget('_qnam'),upcase(&_id),' ');

或者,如果您想将ABC UVW转换为"ABC","UVW",那么一个简单的TRANWRD()函数调用就可以了

where upcase(&_id) in ("%sysfunc(tranwrd(&_qnam,%str( ),","))");

但是,如果您的列表可能有多余的空格,例如,如果是手动键入的,您将首先删除多余的空格。

%let _qnam=%sysfunc(compbl(&_qnam));

最新更新