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

Hi,

I have the following code, then input "2021JUNUN" should fall in 2nd condition &idx1_dw=%eval(&idx2_dw + 1), which give the result : after dw is 2021JUNUN

%macro DROPUN(S);
%let idx2_dw=%sysfunc(index(&s,JUN));
%let idx1_dw=%sysfunc(index(&s,UN));
%if &idx2_dw=0 %then %do; 
	%let cfun=%sysfunc(tranwrd(&S,UN,'07'x));
	%let cfun=%sysfunc(compress(&cfun,'07'x));
%end;
%else %if &idx1_dw=%eval(&idx2_dw + 1) %then %do;
	%let cfun=%qsysfunc(tranwrd(&S,%str(UNUN),%str(UN)));
	%let cfun=%qsysfunc(tranwrd(&S, %str(UN/UN), %str(UN)));
%end;
%else %if &idx1_dw=1 %then %do;
	%let l_dw=%eval(%length(&S)-2);
	%let cfun=%substr(&S,3,&l_dw);
%end;
%put after dw is &cfun;
%mend DROPUN;

%dropun(2021JUNUN);

However, when I put the code outside, it gives me correct result: 2021JUN

%let s=2021JUNUN;
%let cfun=%qsysfunc(tranwrd(&S,%str(UNUN),%str(UN)));
%put &cfun;
%dropun(2021JUNUN);

Can anyone please advise what is the issue here? Many thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
NicoM
Obsidian | Level 7

The code that you execute outside of your macro also works fine inside the macro. However, the problem is that you overwrite it again with the original value of your input S in the second if/else-block.

%else %if &idx1_dw=%eval(&idx2_dw + 1) %then %do;
	%let cfun=%qsysfunc(tranwrd(&S,%str(UNUN),%str(UN)));
	%let cfun=%qsysfunc(tranwrd(&S, %str(UN/UN), %str(UN)));
%end;

The second let-statement uses the original input S. Since the string "UN/UN" does not appear, nothing is translated and CFUN is set equal to S. This is what you get as an output at the end.

 

You probably want to modify the second let-statement to have CFUN as an input. The full code then looks like this:

%macro DROPUN(S);
%let idx2_dw=%sysfunc(index(&s,JUN));
%let idx1_dw=%sysfunc(index(&s,UN));
%if &idx2_dw=0 %then %do; 
	%let cfun=%sysfunc(tranwrd(&S,UN,'07'x));
	%let cfun=%sysfunc(compress(&cfun,'07'x));
%end;
%else %if &idx1_dw=%eval(&idx2_dw + 1) %then %do;
	%let cfun=%qsysfunc(tranwrd(&S,%str(UNUN),%str(UN)));
	%let cfun=%qsysfunc(tranwrd(&cfun, %str(UN/UN), %str(UN)));
%end;
%else %if &idx1_dw=1 %then %do;
	%let l_dw=%eval(%length(&S)-2);
	%let cfun=%substr(&S,3,&l_dw);
%end;
%put after dw is &cfun;
%mend DROPUN;

%dropun(2021JUNUN);

This gives the correct output.

after dw is 2021JUN

View solution in original post

3 REPLIES 3
NicoM
Obsidian | Level 7

The code that you execute outside of your macro also works fine inside the macro. However, the problem is that you overwrite it again with the original value of your input S in the second if/else-block.

%else %if &idx1_dw=%eval(&idx2_dw + 1) %then %do;
	%let cfun=%qsysfunc(tranwrd(&S,%str(UNUN),%str(UN)));
	%let cfun=%qsysfunc(tranwrd(&S, %str(UN/UN), %str(UN)));
%end;

The second let-statement uses the original input S. Since the string "UN/UN" does not appear, nothing is translated and CFUN is set equal to S. This is what you get as an output at the end.

 

You probably want to modify the second let-statement to have CFUN as an input. The full code then looks like this:

%macro DROPUN(S);
%let idx2_dw=%sysfunc(index(&s,JUN));
%let idx1_dw=%sysfunc(index(&s,UN));
%if &idx2_dw=0 %then %do; 
	%let cfun=%sysfunc(tranwrd(&S,UN,'07'x));
	%let cfun=%sysfunc(compress(&cfun,'07'x));
%end;
%else %if &idx1_dw=%eval(&idx2_dw + 1) %then %do;
	%let cfun=%qsysfunc(tranwrd(&S,%str(UNUN),%str(UN)));
	%let cfun=%qsysfunc(tranwrd(&cfun, %str(UN/UN), %str(UN)));
%end;
%else %if &idx1_dw=1 %then %do;
	%let l_dw=%eval(%length(&S)-2);
	%let cfun=%substr(&S,3,&l_dw);
%end;
%put after dw is &cfun;
%mend DROPUN;

%dropun(2021JUNUN);

This gives the correct output.

after dw is 2021JUN
tinaz5012
Obsidian | Level 7

Thank you for your help, appreciate it!!

Astounding
PROC Star

For the future, SAS will help you solve these complex macro logic problems.  Add this before running the macro:

 

options mlogic symbolgen mprint;

(In this particular macro you would not need mprint, just for the record.)

 

To turn the options off once you are finished debugging and don't need the annoying diagnostic messages:

 

options nomlogic nosymbolgen nomprint;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 1641 views
  • 4 likes
  • 3 in conversation