BookmarkSubscribeRSS Feed
12346
Calcite | Level 5

%let a=b;

%let b=c;

%let c=d;

%let d=a;

 

%put &a;

b

%put &&&a;

c

%put &&&&&&&a;

d

%put &&&&&&&&&&&&&&&a;

a

 

I want to count the number of "&" without hard cording by adding the "&" each of the time until i get the answer, like b=1, c=3, d=7, a=15

11 REPLIES 11
Tom
Super User Tom
Super User

Is there a question or are you just showing how it works?

You need to add two & to have that resolved to one & and cause macro processor to rescan the string.

So to get the value of mvar you need one.

To get the value of mvar named by the mvar you need one + two = three.

So for the number of & needed to get more and more levels of re-direction you basically have a geometric progression.  2**N + 1.  for N=0,1,2,3,....

novinosrin
Tourmaline | Level 20

Hi @Tom  May i request a moment of your time to help me understand how this works. For some reason i never understood indirect referencing with more than 2 ampersands. I would appreciate if you could lend me your time. Plz and thanks

 

%let a=b;

%let b=c;

%let c=d;

%let d=a;

 

%put &a;

b

%put &&&a;

c

%put &&&&&&&a;

d

%put &&&&&&&&&&&&&&&a;

a

Tom
Super User Tom
Super User

Just run it with the SYMBOLGEN option turned on and the SAS log will explain.

For example let's take the case of three & .

So on first pass && goes to & and &a goes to b.  So you now have &b.  Which evaluates to c.

With 5 & you will have three passes.  So the first six & get reduced to 3 & and &a goes to B.  So now you are back to case with three &.

novinosrin
Tourmaline | Level 20

Thank you Sir!

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Why?  Simply put, if you have more than one & or % on one line of code, then 100% there is a better way of doing things, and the code in question is messy and un-maintainable.  The code you present for example is (noting of course how I follow good pramming standards and place the dot after the macro variable name!):

%let a=a;

%put &a.;

 

mkeintz
PROC Star

@RW9

 

I think a use case can be made, at least for three ampersands.  Let's say you have a sequence of links that loop back to the starting node:

 

%let a=b; %let b=c; %let c=d; %let d=a;

 

If you're told to start at a, and then advance 6 links, you could do this (or start at detroit and make six steps through the circuit in the code below);

 

%macro t(start=,nsteps=);
  %let a=b;               %let b=c;                 %let c=d;               %let d=a;
  %let detroit=ann_arbor; %let ann_arbor=kalamazoo; %let kalamazoo=lansing; %let lansing=detroit;
  %let x=&start;
  %put **** START: &=x;
  %do i=1 %to &nsteps;
    %let x=&&&x;
  %end;
  %put END: &=nsteps &=x;
%mend;

%t(start=a,nsteps=6)
%t(start=detroit,nsteps=6)

Now the above makes 6 single-unit steps. And the user doesn't need to know how many links are in a circuit.  Now, it''s a bit far-fetched, but I suppose one could conceive of performing some number of 2-unit steps (7&), or  3-unit steps (15& !!!), etc.

 

I agree there is almost always a better way than over 3 ampersands, but I can imagine a three-& code being effective and appropriate.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
12346
Calcite | Level 5
Thanksss!! But can I put x=c then show the result nsteps=6?
mkeintz
PROC Star

I don't see how you could determine NSTEPS=6 when you would already be  at the same destination with NSTEPS=2 in this example.

 

But think about this.

  %let source=A;

   %let sink=B;

 

So why not

    %let X=&source.

 

  Then do a loop and count the number of iterations until macrovar X = macrovar sink.

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
12346
Calcite | Level 5
%let a=b;
%let b=c;
%let c=d;
%let d=a;
How to write a macro program to count the number of ampersands is needed for generating the specified result.
PeterClemmensen
Tourmaline | Level 20

What "specified result"?

Kurt_Bremser
Super User

@12346 wrote:
%let a=b;
%let b=c;
%let c=d;
%let d=a;
How to write a macro program to count the number of ampersands is needed for generating the specified result.

I do not see a single ampersand in your post, so there's nothing to count.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 11 replies
  • 1717 views
  • 0 likes
  • 7 in conversation