BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
whymath
Barite | Level 11

I am trying to define a macro which is used for replace mutiple transtrn(), that is to say:

 

data test;
	method = '1,2,3,';
	method2 = transtrn(transtrn(transtrn(method,'1',"test method1"),'2',"test method2"),'3',"test method3");
	method3 = %transtrn(method,'1',"test method1",'2',"test method2",'3',"test method3");;
run;

I am expecting method3 will has the same value as method2. So I write macro %transtrn() like this:

option nomprint nomlogic;
%macro transtrn()/parmbuff;
*extract parameters;
%global header tail;
%let mstring = %substr(&syspbuff.,2,%length(&syspbuff.)-2);
%if &header eq %str() %then %do;
	%let header = %scan(%superq(mstring),1,%str(,));
%end;

*use prx-function to get substitute strings reliably;
%let pat = %sysfunc(prxparse(%str(/(('.*?')|(".*?")),(('.*?')|(".*?"))/)));
%if %sysfunc(prxmatch(&pat.,%superq(mstring))) %then %do;
	%let sub1 = %sysfunc(prxposn(&pat.,1,%superq(mstring)));
	%let sub2 = %sysfunc(prxposn(&pat.,4,%superq(mstring)));
%end;

*try recursion for multiple recall the prx-function part and combine every results into the final expression;
%let header = transtrn(&header.;
%let tail = &tail.,%str(&sub1.),%str(&sub2.));

%let left = %sysfunc(transtrn(%superq(mstring),%str(,&sub1.),%str()));
%let left = %sysfunc(transtrn(%superq(left),%str(,&sub2.),%str()));
%if %sysfunc(prxmatch(&pat.,%superq(left))) %then %transtrn(&left.);
%else %do;
	%let Rst = &header &tail.;
	&Rst.;
	%symdel header tail; 
%end;
%mend;

I tested my macro like this and everything seems right:

%put %transtrn(method,'1',"test method1",'2',"test method2",'3',"test method3");
transtrn(method ,'1',"test method1"),'2',"test method2"),'3',"test method3")

But when I apply it to my test program, it just wrong:

data test;
	method = '1,2,3,';
	method2 = transtrn(transtrn(transtrn(method,'1',"test method1"),'2',"test method2"),'3',"test method3");
	method3 = %transtrn(method,'1',"test method1",'2',"test method2",'3',"test method3");;
run;

Can someone help me? thanks a lot.

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

First thing, DO NOT use *text ; style comments. Inside macros either use /*text */ or %* text; The *text; style comments will be part of the resolved macro values

 

When I removed your commented lines I got what I believe to be your desired output. So change all those to /*  */

 

Personally I only use /* */ comments so I never have to worry about using the proper form

 

There were LOTS of clues in the Log when executing that data step:

488  data test;
489     method = '1,2,3,';
490     method2 = transtrn(transtrn(transtrn(method,'1',"test method1"),'2',"test
490! method2"),'3',"test method3");
491     method3 = %transtrn(method,'1',"test method1",'2',"test method2",'3',"test method3");;
NOTE: Line generated by the invoked macro "TRANSTRN".
1     *extract parameters;
      -
      386
      200
      76
ERROR: Undeclared array referenced: transtrn.
NOTE 137-205: Line generated by the invoked macro "TRANSTRN".
7        &Rst.;
              -
              22
ERROR 386-185: Expecting an arithmetic expression.

ERROR 200-322: The symbol is not recognized and will be ignored.

ERROR 76-322: Syntax error, statement will be ignored.

ERROR 22-322: Syntax error, expecting one of the following: +, =.

NOTE: Line generated by the invoked macro "TRANSTRN".
7        &Rst.;
              -
              76
ERROR 76-322: Syntax error, statement will be ignored.

492  run;

View solution in original post

2 REPLIES 2
ballardw
Super User

First thing, DO NOT use *text ; style comments. Inside macros either use /*text */ or %* text; The *text; style comments will be part of the resolved macro values

 

When I removed your commented lines I got what I believe to be your desired output. So change all those to /*  */

 

Personally I only use /* */ comments so I never have to worry about using the proper form

 

There were LOTS of clues in the Log when executing that data step:

488  data test;
489     method = '1,2,3,';
490     method2 = transtrn(transtrn(transtrn(method,'1',"test method1"),'2',"test
490! method2"),'3',"test method3");
491     method3 = %transtrn(method,'1',"test method1",'2',"test method2",'3',"test method3");;
NOTE: Line generated by the invoked macro "TRANSTRN".
1     *extract parameters;
      -
      386
      200
      76
ERROR: Undeclared array referenced: transtrn.
NOTE 137-205: Line generated by the invoked macro "TRANSTRN".
7        &Rst.;
              -
              22
ERROR 386-185: Expecting an arithmetic expression.

ERROR 200-322: The symbol is not recognized and will be ignored.

ERROR 76-322: Syntax error, statement will be ignored.

ERROR 22-322: Syntax error, expecting one of the following: +, =.

NOTE: Line generated by the invoked macro "TRANSTRN".
7        &Rst.;
              -
              76
ERROR 76-322: Syntax error, statement will be ignored.

492  run;
whymath
Barite | Level 11

You tell the truth.