我正在尝试编写一个宏,其中我的参数具有多个值,而其中一些则带有空格。我希望能够读取字符串以及空格,但是空格是默认的分隔符会导致问题。
`%macro ab(where_p=);
data want;
set have;
%DO I =1 %TO %SYSFUNC(COUNTW(&WHERE_P));
%IF %LENGTH(&WHERE_P) > 0 %THEN %DO;
B_&I=%SCAN(%STR(&WHERE_P),&I);
%end;
%end;
run;
%mend;
%ab(WHERE_P=" ATF" " TRUST");`
此处无法按原样读取值,而是将一个空格读取为一个字符串,然后读取ATF,然后读取另一个空格,然后再读取TRUST。其中,应将“ ATF”作为一个字符串,将“ TRUST”作为第二个字符串。 有人可以使用扫描功能帮助读取此类数据吗? 谢谢
答案 0 :(得分:1)
尝试:
%macro ab(where_p=);
%let array_size = %EVAL(%SYSFUNC(COUNTC(&WHERE_P, '"'))/2);
data want;
set have;
array B_(&array_size) $20 (&where_p);
run;
%mend;
%ab(WHERE_P=" ATF" " TRUST" );
您首先找到报价的数量除以2的项目数量。 然后创建该大小的数组,并直接使用&WHERE_P分配值。
如果要允许WHERE_P中的字符串超过20个字符,则需要更改数组行中的长度。
答案 1 :(得分:1)
只需使用%SCAN()函数的功能来处理此问题。如果数据包括定界符,则需要用引号引起来。
%let WHERE_P=" ATF" " TRUST";
%let word1 = %scan(&where_p,1,%str( ),q);
所以,你的循环应该是这样的:
%IF %LENGTH(&WHERE_P) %THEN %DO I =1 %TO %SYSFUNC(COUNTW(&WHERE_P,%str( ),q));
B_&I=%SCAN(&where_p,&I,%str( ),q);
%end;
...
%ab(WHERE_P=" ATF" " TRUST");`
或者您可以使用不出现在数据中的其他定界符。如果你想在没有实际报价前导空格来传递,那么你需要使用宏引用。
%IF %LENGTH(&WHERE_P) %THEN %DO I =1 %TO %SYSFUNC(COUNTW(&WHERE_P,|));
B_&I=%sysfunc(quote(%qSCAN(&where_p,&I,|)));
%end;
...
%ab(WHERE_P=%str( ATF| TRUST));