BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
PrinceAde
Obsidian | Level 7

Hi everyone, please I have confusion on how an indirect references works sas macro.
I don't understand how this resolves to type2;

%let value1 = dogs;
%let value2 = cats;
%let value3 = birds;

%let type1 = value1;
%let type2 = value2;
%let type3 = value3;

%let animal = type2;
%let final = animal;

%put &&&&&&final;

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

3 iterations of resolution are done.

In the first, all double ampersandsvresolve to one ampersand, so you get

&&&final

In the second, the double ampersand becomes one, and &final resolves to animal, so you get

&animal

In the third, &animal resolves to

type2

which is what you get.

View solution in original post

8 REPLIES 8
PaigeMiller
Diamond | Level 26

If you run the macro debugging option

 

options symbolgen;

 

and then run your code again, you will see in the log:

 

 69         options symbolgen;
 70         %let value1 = dogs;
 71         %let value2 = cats;
 72         %let value3 = birds;
 73         
 74         %let type1 = value1;
 75         %let type2 = value2;
 76         %let type3 = value3;
 77         
 78         %let animal = type2;
 79         %let final = animal;
 80         
 81         %put &&&&&&final;
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable FINAL resolves to animal
 SYMBOLGEN:  Macro variable ANIMAL resolves to type2
 type2
 82         

 

So double && resolves to & (repeatedly), then &FINAL resolves to animal, then &ANIMAL resolves to type2.

 

Better yet, avoid this use of &&&&&&& and find other ways to accomplish the task. I never use  more than a triple ampersand.

--
Paige Miller
Kurt_Bremser
Super User

3 iterations of resolution are done.

In the first, all double ampersandsvresolve to one ampersand, so you get

&&&final

In the second, the double ampersand becomes one, and &final resolves to animal, so you get

&animal

In the third, &animal resolves to

type2

which is what you get.

ballardw
Super User

Maybe running this will give you some clue:

%put &final;
%put &&final;
%put &&&final;
%put &&&&final;
%put &&&&&final;
%put &&&&&&final;
%put &&&&&&&final;
%put &&&&&&&&final;
%put &&&&&&&&&final;
%put &&&&&&&&&&final;
%put &&&&&&&&&&&final;
%put &&&&&&&&&&&&final;
%put &&&&&&&&&&&&&final;
%put &&&&&&&&&&&&&&final;
%put &&&&&&&&&&&&&&&final;

If you start writing code that requires more than && for indirect referencing be prepared to spend a lot of time debugging as the more indirect you try to do something the number of & required to get to "desired" result goes up quickly.

 

Note that multiple sets of indirect references have the same results.

Look at &&&Final. The first && resolve to & so you get & followed by &final. With &final=animal then you get &animal or  a result of type2.

 

2 to the nth power -1.

That's how many & for each level (n) of indirect referencing needed. You have lots of && resolving to & with more indirects.

 

I really hope this was an exercise as I would strongly recommend not trying to get that many indirect references to work consistently.

ChrisNZ
Tourmaline | Level 20

There should be few cases where you need more than 2 levels, but even for 2, I prefer a more explicit syntax:

%let value1 = dogs;
%let value2 = cats;
%let value3 = birds;

%let type1 = value1;
%let type2 = value2;
%let type3 = value3;

%let animal = type2;
%let final = animal;

%put 1.%superq(final);
%put 2.%superq(%superq(final));
%put 3.%superq(%superq(%superq(final)));
%put 4.%superq(%superq(%superq(%superq(final))));
1.animal
2.type2
3.value2
4.cats

Kurt_Bremser
Super User

Just to give you some perspective: in more than two decades of professional work with SAS, and more than a decade as data warehouse administrator and chief developer, being responsible for 1000+ SAS jobs running in production, I never had to use an indirect macro variable reference. Not once.

I encountered this technique here for the first time.

So don't waste too many precious brain cycles on this. There's much more important SAS stuff to learn.

ChrisNZ
Tourmaline | Level 20

@Kurt_Bremser 

I've seen the construct &&&var&i used on regularly. I'm surprised you haven't.

 

Kurt_Bremser
Super User

Probably because I always keep data in datasets, which reduces the need for macro arrays.

Anyway, just deciphering a mass of ampersands takes much too much time when maintaining programs, that's why it's so impractical.

yabwon
Amethyst | Level 16

I think the macroArray package can make work with macro variable arrays (i.e. &&prefix&sufix constructs) easier.

 

Article describing it: https://www.lexjansen.com/pharmasug/2024/AP/PharmaSUG-2024-AP-108.pdf has been published in PharmaSUG 2024 proceedings  and re-published in WUSS 2024 proceedings.

 

The package itself is located here: https://github.com/SASPAC/macroarray

 

All the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



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