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:
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?
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;
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
Good point. I could have probably gone that route, but I found another solution. Thank you for your contribution though!
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;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.