BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
DavidPhillips2
Rhodochrosite | Level 12

Is there a way in SAS 9.2 to dynamically change a Global variable within a SAS macro e.g.

%Global testVar;

%macro Test(variableToChange);

                %let variableToChange = “A”;

%mend;

%Test(testVar);

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Very close ... need to add an ampersand:

%let &variableToChange = "A";

It's not clear that you want quotes as part of the new value ... your example will change the variable to a set of three characters where the second character is A and the first and third characters are quotes.

Also, the local symbol table must not contain a macro variable named testVar. If it does, the local version will be changed not the global version.

View solution in original post

10 REPLIES 10
Astounding
PROC Star

Very close ... need to add an ampersand:

%let &variableToChange = "A";

It's not clear that you want quotes as part of the new value ... your example will change the variable to a set of three characters where the second character is A and the first and third characters are quotes.

Also, the local symbol table must not contain a macro variable named testVar. If it does, the local version will be changed not the global version.

DavidPhillips2
Rhodochrosite | Level 12

Is there a way for a SAS macro to return a value?  I found some documentation that looked like the below.  Where the paper left the semi-colon off but it didn’t work for me in SAS 9.2.

%macro Test(variableToChange);

            %let variableToChange = ‘A’;

              &variableToChange /*this would be returned??*/

%mend;

Astounding
PROC Star

This time you need to add two ampersands.  The text to be returned should be:

&&&variableToChange

&variableToChange resolves to TextVar.  Adding the two ampersands resolves to the value of &TextVar.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Is it good practice to do this however?  The term Global means the whole program, to change that within a specific section seems to defeat the purpose.  Take an example:

%global pi;

%let pi=3.14;

%macro print();

     proc print ...;

     %let pi=3.141;

%mend print;

%Check_Circle_Measurements();


%Print();


%Check_Circle_Measurements();


...


The print changes the calculation later on.  Ok, with this you can see that, but if you have several files included, would you not lose confidence in the fact that pi had changed?  This is one of the old obfuscation techniques, change something which appears to be one thing into another in a subtle manner so its hard to see.

DavidPhillips2
Rhodochrosite | Level 12

%let &variableToChange = “A”; worked for me on a simple scenario.  I tried using the same logic in a more complex macro and found that I’m running into an error on

%let &spacedList = &spacedList.%scan(%superQ(commaList), 1, str(,));

Where this works.

%let degStudLev = &degStudLev.%scan(%superQ(degStudLevComma), 1, str(,));

The full examples are below.  I’m thinking that I need to enclose commaList with something. 

/*outputs degStudLevdegS (Weird Output)*/

%Macro convertCommaListToSpaced(commaList, spacedList);

       %let &spacedList = &spacedList.%scan(%superQ(commaList), 1, str(,));

%mend;

%macro testmacro3();

       %let degStudLevComma = AH,AX,AV,AI;

       %let degStudLev= %str();

       %convertCommaListToSpaced(degStudLevComma, degStudLev);

       %put &degStudLev;

%mend;

%testmacro3;

/*outputs AH (Good Output)*/

%Macro convertCommaListToSpaced(commaList, spacedList);

       %let degStudLevComma = AH,AX,AV,AI;

       %let degStudLev= %str();

       %let degStudLev = &degStudLev.%scan(%superQ(degStudLevComma), 1, str(,));

%mend;


%macro testmacro3();

       %convertCommaListToSpaced(degStudLevComma, degStudLev);

       %put &degStudLev;

%mend;

%testmacro3;

DavidPhillips2
Rhodochrosite | Level 12

A little simpler example of the problem.

This produces: degStuLevComma.

/*outputs degStuLevComma*/

%Macro convertCommaListToSpaced(commaList, spacedList);

       %let test = A;

       %put &commaList;

%mend;

%macro testmacro3();

       %let degStudLevComma = AH,AX,AV,AI;

       %let degStudLev= %str();

       %convertCommaListToSpaced(degStudLevComma, degStudLev);

%mend;

%testmacro3;

DavidPhillips2
Rhodochrosite | Level 12

I found I can use this:

%let degStudLev = %convertCommaListToSpaced(commaList =%str(%quote(&degStudLevComma)), spacedList =&degStudLev); 

Still my result is not equivalent to running this without the macro.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Sorry to sound like a broken record, but the examples you have given above would be far simpler to put lists of options in datasets rather than trying to force macro language to do base language processing.

data list;

     val="A"; output;

     val="B"; output;

     val="C"; output;

run;


/* Use list in base code */

proc sql;

     create table WANT as

     select * from HAVE where ID in (select VAL from LIST);

quit;


/* Use list to create where list */

proc sql;

     select VAL into :V_LIST separated by " ";  /* Just change if you want commas */

quit;

data want;

     set have (where=(id in (&V_LIST.));

run;

Etc.  The above seems far simpler to me that all that %xyz(&&&ABC&&&YYX%something());

DavidPhillips2
Rhodochrosite | Level 12

RW9,


The input format is A,B,C.

Step 1 requires format A B C

Step 2 requires ‘A’, ‘B’, ‘C’

I need the macro to convert the input format to at least step 1. 

I also need to run this logic on 20 different inputs at different parts of the stored process.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Not sure what you mean by "input" as don't use stored processes, but:

data _null_;

     set input;

     call symput('step1',tranwrd(input,","," "));

     call symput('step2',"'"||tranwrd(input,",","','")||"'");

run;

Should do it.

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
  • 10 replies
  • 3324 views
  • 6 likes
  • 3 in conversation