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

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