首页 > 解决方案 > 宏内部的 SAS 子字符串

问题描述

我有一个在数据步骤(宏之外)中工作的示例代码,但是当我尝试将其转换为宏时它不起作用。我尝试了不同类型的方法来使用 CALL SYMPUTS、SYSFUNC、LET 等。下面列出的代码是我试图将其放入输入 T_Test2 的宏中的代码。

DATA asdhjkl;
    SET T_Test2;
    IF INPUT(SCAN(COL1, 1, "-"), best.)=0 THEN COL1=SUBSTR(COL1, INDEX(COL1,"-")+1);
    string="-00000000000000000000";
    DO I = 1 TO 20;
        COL1 = TRANWRD(COL1, trim(string), " ");
        string = substr(string, 1, length(string)-1);
        PUT string;
    END;
    COL1=COMPRESS(COL1);
RUN;

基本上我要做的是从另一个字符串(如 65-03)中取出“-0”的子字符串变体并删除 03。但它也更通用,因此如果它是 65-003 和 65-0003 等,它也可以工作.

标签: macrossas

解决方案


如果您希望将值转换为和示例之类的值65-00365-003那么65-3您的程序就太复杂了。您可以将第二部分转换为数字,然后生成字符串。或者,您可以使用正则表达式将后跟一个或多个零的连字符转换为一个连字符。

这是两种方法的数据步骤代码解决方案:

data test;
  input have $20. ;
  length want1-want2 $20;
  want1=catx('-',scan(have,1,'-'),input(scan(have,2,'-'),32.));
  want2=prxchange('s/-0*/-/',-1,have);
cards;
65-003
65-0003
;

或者您可以在宏代码中执行类似的操作来操作宏变量的值。该%eval()函数使用整数运算评估看起来像表达式的字符串,因此添加+会使003看起来像要评估的表达式。

%macro fix1(string);
%scan(&string,1,-)-%eval(+%scan(&string,2,-))
%mend fix1;

%macro fix2(string);
%sysfunc(prxchange(s/-0*/-/,-1,%superq(string)))
%mend fix2;

%put %fix1(65-003);

推荐阅读