DATA Step, Macro, Functions and more

Why doesn't this macro work?

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 129
Accepted Solution

Why doesn't this macro work?

%macro test(n);

%if &n=1 %then a;

%if &n=2 %then b;

%mend test;

%put %test(1)zz; /* produces azz */

data;

azz=0;

v1 = %test(1)zz;  /* produces error */

run;


Accepted Solutions
Solution
‎04-01-2015 08:58 AM
SAS Employee
Posts: 23

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

Hi!

It seems that when you build names like this, with macros, the result is not considered as one name by sas. Instead it's considered as two names that are concatenated. But if we put the expression inside of some macro function, we can put the parts together again. For example:

data;

  azz=0;

  v1 = %unquote(%test(1)zz);

run;

View solution in original post


All Replies
Super User
Posts: 19,804

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

%then a;


What are you expecting that portion of your code to do?

Frequent Contributor
Posts: 129

Re: Why doesn't this macro work?

In the data step, I want to execute the line

v1 = azz;

So with

%then a;

I'm expecting the macro to return the text 'a'. It does this when I use the macro in the %put statement.

Super User
Posts: 19,804

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

I cant test anything now, but would guess that it revolves with spaces so what you actually you see is

a zz.

You can look into the vvaluex function regardless because I think that's close to what you're looking for.

Super User
Posts: 7,782

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

I alos would have expected this to work.

This method works:

%macro test(n);

%global varname;

%if &n=1 %then %let varname=a;

%if &n=2 %then %let varname=b;

%mend test;

data test;

azz = 0;

bzz = 1;

%test(1);

v1 = &varname.zz;

%test(2);

v2 = &varname.zz;

run;

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Trusted Advisor
Posts: 3,214

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

Back to the basics of tokens....SAS(R) 9.4 Macro Language: Reference, Third Edition

As the compiler runs you have those words/tokens.  the %test(1) is a nice token and gets resolved. Than what you have caused is a change in the token of the datastep.. expecting azz as the next one token for the datastep. that is moving the pointer back to the beginning where the macro started.

It looks like that pointer for the next token is positioned AFTER the text insertion.  We could see this as unwanted unexpected behavior.  Should be easy to be solved by SAS. The only hurdle will be accepting this as a failure/defect/problem by SAS TS.   Did you made a call to those?   

The most easily answer of them is getting "works as designed"..... (sighhh)

---->-- ja karman --<-----
Solution
‎04-01-2015 08:58 AM
SAS Employee
Posts: 23

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

Hi!

It seems that when you build names like this, with macros, the result is not considered as one name by sas. Instead it's considered as two names that are concatenated. But if we put the expression inside of some macro function, we can put the parts together again. For example:

data;

  azz=0;

  v1 = %unquote(%test(1)zz);

run;

Super User
Posts: 10,028

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

You need put quote around it .

%macro test(n);

%if &n=1 %then  a ;

%if &n=2 %then b ;

%mend test;

%put %test(1)zz; /* produces azz */

data x;

azz=0;

v1 ="%test(1)zz";  /* produces error */

run;

Message was edited by: xia keshan

Trusted Advisor
Posts: 3,214

Re: Why doesn't this macro work?

SAS UE 

1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;

42         ;

43        

44         %macro test(n);

45         %if &n=1 %then %do; a %end;

46         %if &n=2 %then %do; b %end;

47         %mend test;

48        

49         %put %test(1)zz; /* produces azz */

azz

50        

51         data;

52         azz=0;

53         v1 = %test(1)zz;  /* produces error */

53         v1 = %test(1)zz;  /* produces error */

                         __

                         22

ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, *, **, +, -, /, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT, IN,

               LE, LT, MAX, MIN, NE, NG, NL, NOTIN, OR, ^=, |, ||, ~=. 

54         run;

The error message is seeming the (1) being seen by the datastep not removed by macro-processing. Changing the code into:

1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;

42         ;

43        

44         %macro test(n);

45         %if "&n"="" %then %do; a %end;

46         %if "&n"="1" %then %do; a %end;

47         %if "&n"="2" %then %do; b %end;

48         %mend test;

49        

50         %put %test(1)zz; /* produces azz */

azz

51        

52         data;

53         azz=0;

54         v1 = %test.zz;  /* produces error */

            __

            388

ERROR 388-185: Expecting an arithmetic operator.

            __

            200

ERROR 200-322: The symbol is not recognized and will be ignored.

You cannot leave the () away as it will fail to recognize the macro-name a dot as separation isn't valid syntax as the macro call is not a macro variable. 

---->-- ja karman --<-----
Super User
Posts: 10,028

Re: Why doesn't this macro work?

Sorry. I just push my code too quickly. See the code updated.

Super User
Posts: 7,782

Re: Why doesn't this macro work?

Xia, he wants to parametrize the name of the variable whose value should go into v1. So v1 should be numeric and have 0 (the value of azz) as value.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 10,028

Re: Why doesn't this macro work?

Posted in reply to KurtBremser

Oh. I never realize why OP would want do this . It is so weird .

%macro test(n);

%if &n=1 %then  a ;

%if &n=2 %then b ;

%mend test;

%put %test(1)zz; /* produces azz */

data x;

azz=0;

v1 =%nrbquote(%test(1)zz);  /* produces error */

run;

Trusted Advisor
Posts: 3,214

Re: Why doesn't this macro work?

Xia, indeed it is weird to parameterize a variables names. There are many more ways (arrays?) to do something smart.  
That is bringing us to the question why would BruceBad want to do this. It is some part of his mind probably doing something in many many steps.

---->-- ja karman --<-----
Super User
Posts: 10,028

Re: Why doesn't this macro work?

I like Kurt's code that should be OK too and more elegant ..

Regular Contributor
Posts: 217

Re: Why doesn't this macro work?

Posted in reply to BruceBrad

What output values are you expecting to see in variable V1?  Does V1 need to contain a character value representing the name of a variable or does V1 need to contain the value of a variable name?

Kurts code:

%macro test(n);

%global varname;

%if &n=1 %then %let varname=a;

%if &n=2 %then %let varname=b;

%mend test;

data test;

azz = 0;

bzz = 1;

%test(1);

v1 = &varname.zz;

%test(2);

v2 = &varname.zz;

run;

proc print data=test(obs=7);

run;

                                        Obs    azz    bzz    v1    v2

                                         1      0      1      0     1

XIA's code:

%macro test(n);

%if &n=1 %then  a ;

%if &n=2 %then b ;

%mend test;

%put %test(1)zz; /* produces azz */

data x;

azz=0;

v1 ="%test(1)zz";

run;

proc print data=x(obs=7);

run;

                                              Obs    azz    v1

                                               1      0     azz

%macro test(n);

%if &n=1 %then a;

%if &n=2 %then b;

%mend test;

%put %test(1)zz; /* produces azz */

data data4;

azz=0;

v1 = %unquote(%test(1)zz);  /*does not produce an error. V1 contains the value of variable AZZ */

run;

proc print data=data4;run;

                                               Obs    azz    v1

                                                1      0      0

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 20 replies
  • 653 views
  • 4 likes
  • 7 in conversation