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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 8 replies
  • 1067 views
  • 7 likes
  • 4 in conversation