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

I need a macro with 3 positional parameters. one is string, one is delimter and one is word number. If word number is larger than the no of words in the string, a log message has to be printed that word number is out of bounds.

call:  %test(there is a question, %str( ),1)

Result: there is a question

call : %xscan(there is a question, %str( ),-2)

Result: a question

1 ACCEPTED SOLUTION

Accepted Solutions
Jagadishkatam
Amethyst | Level 16

Please try the below macro,

/*positional parameters:*/

/*var=string*/

/*num=number of the word*/

/*del=delimiter*/

%macro test(var,num,del);

data _null_;

    %let count=%sysfunc(countw(&var));

    %let str=%sysfunc(scan("&var",&num,&del));

    %if &count >= &num %then %do;

    word=scan("&var",&num,&del);

    %put &str;

    %end;

    %else %do;

    %put "word number is out of bounds";

    %end;

run;

proc print;

run;

%mend;

%test(%str(ram rahul rohit),3," ")

Thanks,

Jagadish

Thanks,
Jag

View solution in original post

8 REPLIES 8
Jagadishkatam
Amethyst | Level 16

Please try the below macro,

/*positional parameters:*/

/*var=string*/

/*num=number of the word*/

/*del=delimiter*/

%macro test(var,num,del);

data _null_;

    %let count=%sysfunc(countw(&var));

    %let str=%sysfunc(scan("&var",&num,&del));

    %if &count >= &num %then %do;

    word=scan("&var",&num,&del);

    %put &str;

    %end;

    %else %do;

    %put "word number is out of bounds";

    %end;

run;

proc print;

run;

%mend;

%test(%str(ram rahul rohit),3," ")

Thanks,

Jagadish

Thanks,
Jag
sahaji
Calcite | Level 5

Thank You so much Jagadish. I'm in the process of learning Macros. This is giving the correct answer to me.

sahaji
Calcite | Level 5

Now I've one more scenario. Just need to change the above code.

Call:  %let sub_str = %test(this one is for learning, %str( ), -2);

          %put The value of sub_str = &sub_str;

Result: The value of sub_str = for learning

Amir
PROC Star

Hi,

How about:

%macro tail(string,n,dlm);

  %let result_scan=%scan(&string,&n,&dlm);

  %if %length(&result_scan) %then

  %do;

    %let result_indexw=%sysfunc(indexw(&string,&result_scan,&dlm));

    %let result=%substr(&string,&result_indexw);

    %put &result;

  %end;

  %else

    %put Word number is out of bounds;

%mend tail;

%tail(one two three four five,2,%str( ));

%tail(one two three four five,-2,%str( ));

%tail(one two three four five,222,%str( ));

giving:

two three four five

four five

Word number is out of bounds

Regards,

Amir.

sahaji
Calcite | Level 5

Amir,

Thanks for your reply. Great effort. This one is also very helpful. Thanks again.

sahaji
Calcite | Level 5

Now I've one more scenario. Just need to change the above code.

Call:  %let sub_str = %test(this one is for learning, %str( ), -2);

          %put The value of sub_str = &sub_str;

Result: The value of sub_str = for learning

Tom
Super User Tom
Super User

What do want as the result with &POS is out of range? What about when &POS=0?

What do want when delimiter is NOT space?

What about multiple adjacent delimiters?

One way to do this is to build the result into a variable and the expand the variable as the result of the macro call.

Here is an example. I leave it as an exercise to see what it does with multiple adjacent delimiters and how you could change that.

%macro test(str,dlm,pos);

%local i n top result ;

%let n=%sysfunc(countw(&str,&dlm));

%if &pos < 0 %then %let top=-1 ;

%else %let top=&n;

%if &pos=0 or &pos > &n or &pos < -&n %then %let result=Out of Bounds ;

%else %do i=&pos %to &top;

  %if &i>&pos %then %let result=&result.&dlm;

  %let result=&result.%qscan(&str,&i,&dlm);

%end;

&result.

%mend test;

277  %let sub_str = "%test(this one is for learning, %str( ), -2)";

278  %put The value of sub_str = &sub_str;

The value of sub_str = "for learning"

279  %let sub_str = "%test(this one|is|for learning,|, -2)";

280  %put The value of sub_str = &sub_str;

The value of sub_str = "is|for learning"

281  %let sub_str = "%test(this one|is|for learning,|, 22)";

282  %put The value of sub_str = &sub_str;

The value of sub_str = "Out of Bounds"

sahaji
Calcite | Level 5

Thank You so much Tom. This is really helpful for me as I'm in the learning process of Macros. Thanks for your time and really appreciate your response.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 2153 views
  • 7 likes
  • 4 in conversation