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

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
Lapis Lazuli | Level 10

You tell the truth.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 2 replies
  • 630 views
  • 1 like
  • 2 in conversation