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

I have tried so many different methods, and I can't find out how to change a part of a value of a macro variable.

 

My program assigns macro variables (RANGE1 through RANGEn) that contain a range that is used later in a conditional statement.  I have a couple of variables that I want to edit.  The values are:

  • (upper(WEIGHT_U)="KG" and WEIGHT not between 137 and 205)
  • (upper(WEIGHT_U)="LB" and WEIGHT not between 137 and 205)

I need to change "WEIGHT_U" to "WEIGHTU".  Below is a snippet of what I am trying to do where &cnt. is the number of range statements previously defined.

 

%macro vsrange;
   %do i=1 %to &cnt;
      %if %index(%substr(%str(&&range&i.),2,31),WEIGHT_U)>0 %then %do;
%let &&range&i=%sysfunc(tranwrd(&&range&i.,WEIGHT_U,WEIGHTU));
%end;
%end; %mend vsrange; %vsrange;

I am sure that there may be issues with the fact that the macro values contain quotes and parentheses.  I am trying to fix that in the %index() function.  I also can't have more than 32 characters (according to an error message), but I can't subset in the %let statement because that will alter the macro value.  It also looks like the %let statement is having a hard time assigning a value to an existing macro variable being referenced with &&.  Can anyone see what I should possibly do to make my necessary changes?

 

1 ACCEPTED SOLUTION

Accepted Solutions
djbateman
Lapis Lazuli | Level 10

I kept playing around, and it turns out that using a DATA _NULL_ step will do the trick:

 

%macro vsrange;
   %do i=1 %to &cnt;
      %if %index(%substr(%str(&&range&i.),2,31),WEIGHT_U)>0 %then %do;
         data _null_;
            call symputx("&&range&i",%sysfunc(tranwrd(&&range&i.,WEIGHT_U,WEIGHTU)));
         run;
      %end;
%end; %mend vsrange; %vsrange;

View solution in original post

3 REPLIES 3
WarrenKuhfeld
Ammonite | Level 13

Why double ampersands? From what you said, you want the macro variable names to start with "range" not some resolved value from some macro variable. It is often a good strategy to program problematic code in simpler terms.  This creates 10 macro variables (range1 - range10) with no problem.  

 

%macro x;
   %do i = 1 %to 10;
      %let range&i = &i;
      %end;
   %put _local_;   
   %mend;
%x

djbateman
Lapis Lazuli | Level 10

Good point.  I could have probably gone that route, but I found another solution.  Thank you for your contribution though!

djbateman
Lapis Lazuli | Level 10

I kept playing around, and it turns out that using a DATA _NULL_ step will do the trick:

 

%macro vsrange;
   %do i=1 %to &cnt;
      %if %index(%substr(%str(&&range&i.),2,31),WEIGHT_U)>0 %then %do;
         data _null_;
            call symputx("&&range&i",%sysfunc(tranwrd(&&range&i.,WEIGHT_U,WEIGHTU)));
         run;
      %end;
%end; %mend vsrange; %vsrange;

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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
  • 3 replies
  • 5845 views
  • 1 like
  • 2 in conversation
--> --> -->
OSZAR »