Literal包含无与伦比的报价。 (SAS)

时间:2014-11-01 03:16:06

标签: sas sas-macro

我试图获取宏变量中传递的值并在其周围加上引号。即空格分隔列表到空格分隔的引用列表。例如如下。我在之前的一篇文章中使用了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.

请帮助解决这个问题。

3 个答案:

答案 0 :(得分:2)

这是添加引号的另一种方法。它非常基本 - 它不会检查输入是否已被引用,并且列表项之间必须有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);

答案 1 :(得分:0)

您可以使用%str()函数在宏中使用不匹配的引号,如下所示:

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

我已将此应用于您的宏并重新组织/简化了一点。首先,您会看到我删除了多余的%bquote()个功能,并将%qsysfunc()更改为%sysfunc()

我还在为where子句构建字符串并将其保存到宏变量中,以便sort语句更突出,而且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;

答案 2 :(得分:0)

你似乎比这更难解决问题。为什么不使用where indexw(symget('_qnam'),upcase(&_id),' '); 函数?

ABC UVW

或者,如果您想将"ABC","UVW"转换为TRANWRD(),则可以执行简单的where upcase(&_id) in ("%sysfunc(tranwrd(&_qnam,%str( ),","))"); 函数调用。

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

但是,如果您的列表可能有额外的空格,例如,如果是手动输入,则需要先删除多余的空格。

$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $handle->query($sql);

if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "<br>";
    }
} else {
    echo "0 results";
}
$handle->close();