Sas 将宏变量值中的空格替换为带空格的引号

Sas 将宏变量值中的空格替换为带空格的引号,sas,sas-macro,Sas,Sas Macro,我想用带空格的双引号替换宏变量中传递的变量之间的空格,即“”。请在下面找到我使用的代码以及我得到的结果 %let str7=ABC DEF UVW XYZ; %let str8 = %qsysfunc(quote(%qsysfunc(tranwrd(%qsysfunc(compbl(%qsysfunc(strip(%upcase(&str7.))))),%str( ),%nrstr(%"))))); %put ^^^^&str8; 日志显示: 18%的认沽和str8 ^^^

我想用带空格的双引号替换宏变量中传递的变量之间的空格,即“”。请在下面找到我使用的代码以及我得到的结果

%let str7=ABC DEF UVW XYZ;

%let str8 = %qsysfunc(quote(%qsysfunc(tranwrd(%qsysfunc(compbl(%qsysfunc(strip(%upcase(&str7.))))),%str( ),%nrstr(%")))));

%put ^^^^&str8;
日志显示:

18%的认沽和str8

^^^^“ABC”“DEF”“UVW”“XYZ”

我需要这个是“ABC”“DEF”“UVW”“XYZ”

我也试过以下方法

proc fcmp outlib=work.funcs.funcs;

    function delimit_words(iString $) $;    
    result = '"' || tranwrd(cats(compbl(iString))," ", '" ,"') || '"';    
    return (result );
    endsub;

run;


%let x =   A  B  C   ;
%let y = %sysfunc(delimit_words(&x));
%put &y;
但它给了我以下的错误

错误:找不到%SYSFUNC或%QSYSFUNC宏函数中引用的定界词函数

我使用了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.

请在这方面提供帮助。

如果不调试上述任何一种方法,我可以提供第三种方法:

%let str8 = %sysfunc(prxchange(%bquote(s/\b/"/),-1,%quote(&str7.)));
*";
prxchange()
函数告诉SAS用一个
”替换每个单词边界(
\b
)。至于何时使用
bquote()
,vs
quote()
,都是在线记录的,但老实说,我通常采用反复试验的方法


*”
什么都不做,但是如果编辑器的语法突出显示被单引号弄糊涂了(就像我的一样),它会让事情看起来更好。

如果添加行,您的
FCMP
工作正常

options cmplib=work.funcs;
如果您运行的是SAS 9.3或更高版本,请添加到您的代码

通常,最好的方法不是这样做:而是首先创建带引号的宏变量。你是怎么创造的?例如,如果是从数据集创建的,则可以执行以下操作:

proc sql;
  select quote(strip(name)) into :varlist separated by ','
  from sashelp.class;
quit;
返回

“阿尔弗雷德”、“爱丽丝”、“芭芭拉”、“卡罗尔”、“亨利”、“詹姆斯”、“简”、“珍妮特”、“杰弗里”、“约翰”、“乔伊斯”、“朱迪” “路易丝”、“玛丽”、“菲利普”、“罗伯特”、“罗纳德”、“托马斯”、“威廉”

试试这个:

%let str7=ABC DEF UVW XYZ;

%let str8 ="%bquote(%sysfunc(tranwrd(%sysfunc(strip(&str7.)),%str( ),%nrstr(%",%"))))";

%put ^^^^&str8;

只要你想使用双引号,那么我认为你工作太辛苦了

%let str7=ABC DEF UVW XYZ;
%let str8="%sysfunc(tranwrd(&str7,%str( )," "))";
现在,如果原始字符串的格式不正确,并且可能在单词之间包含多个空格,那么首先需要使用
%COMPBL()
来清理它

%let str8=%sysfunc(compbl(&str7));
%let str8="%sysfunc(tranwrd(&str8,%str( )," "))";

感谢您提供了一个更整洁的方法,但它给了我以下错误。错误:文字包含不匹配的引号。我有一个拼写错误,现在已修复(buote代替引号)。很抱歉。proc sort data=&SUPPDS。out=&\u SUPPDS。;由&\u byvar。;%如果%superq(_qnam)ne%,则%do;%let uu tmpmv_n_qnam=%eval(%sysfunc(countw(%superq(qnam),%str());如果&uu tmpmv n\u qnam gt为1%,则为%do;%let_uutmpmv_qnam=%sysfunc(prxchange(%bquote(s/\b/“/),-1,%quote(&qnam.));*;%结束;%else%如果和tmpmv n_qnam等式为1%,则%do;%let uu tmpmv_qnam=%qsysfunc(引号(%qsysfunc(strip(%upcase)(&qnam.')));%结束;其中upcase(&_id)在(&_tmpmv_qnam)中;%结束;跑我已经按照您的方法更新了我的宏。但它仍然给我错误。我更新了我的帖子来描述同样的情况。请帮助。这将在句点和其他“单词”边界处分割单词,而不仅仅是在空格处。试试看,它是
%let str7=ABC D.EF