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
Rhodochrosite | Level 12

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;

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