2014-11-01 53 views
1

我想獲取傳遞給宏變量的值,並在其周圍加上引號。即空格分隔的列表到空格分隔的引用列表。例如下面給出。我在以前的一篇文章中使用了Jeff給出的以下方法。文字包含無與倫比的報價。 (SAS)

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); 

日誌diaplayed以下錯誤:

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); 
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; 
0

你似乎正在讓問題變得比現在更困難。爲什麼不使用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));