BookmarkSubscribeRSS Feed
pobel
Calcite | Level 5

Hi All,

Please take a look at the following code:

Program

%macro a;

    part1; part2

%mend;

%macro b;

   %put *%a*;

%mend;

*** Try 1;

%b

*** Try 2;

%put *%a*;

Here is the result in the log:

Log

10   %b;

*part1; part2*

11

12   %put *%a*;

*part1

NOTE: Line generated by the invoked macro "A".

1    part1; part2

           -----

           180

ERROR 180-322: Statement is not valid or it is used out of proper order.

The same %PUT statement acts differently in the open code than in a macro definition.

In the open code, the semicolon between 'part1' and 'part2' was treated as the end of the %PUT statement. Just like when we directly submit "%put *part1; part2*;".

However, when the %PUT statement was in a macro program, the semicolon returned by "%a" was treated as a plain character.

Would anyone please explain this difference for me? I didn't find the answer from the HELP documentation.

Thanks a lot in advance!

Best regards!

6 REPLIES 6
Amir
PROC Star

Hi,

Interesting question, I can see that:

%put %quote(*%a*);

produces the desired result, making me think it is to do with macro quoting which is a large topic:

SAS(R) 9.3 Macro Language: Reference

Regards,

Amir.

pobel
Calcite | Level 5

Thanks Amir!

I have the same thought too, but didn't find any proof in the Help.

Peter_C
Rhodochrosite | Level 12

It is simpler than that.

The macro executes and generates text which is assumed to be valid syntax inopen code

When the text generated is a string it can resolve within " double quotes. However it must be valid code wherever the   macro executes .

When your macro executes it generates statements that might be valid inside a data step but which are not valid outside a data step.

It's not the macro at fault but its usage.

pobel
Calcite | Level 5

Thanks Peter.C!

What I cannot understand is:  why the returned code of a macro, when this macro was invoked inside another macro, was masked (the returned semicolon was not treated as the end of a statement).

If we add another %PUT statement in the macro A:

Program

%macro a;

    part1; part2

    %put This is when macro A execue.;

%mend;

%macro b;

   %put *%a*;

%mend;

*** Try 1;

%b

*** Try 2;

%put *%a*;

Log

19   %b

This is when macro A execue

*part1; part2*

20   %put *%a*;

*part1

This is when macro A execue

NOTE: Line generated by the invoked macro "A".

1    part1; part2

            -----

            180

ERROR 180-322: Statement is not valid or it is used out of proper order.

We can see from the log that when macro B executes, the execution of macro A was before B's %PUT statement. So I am guessing maybe there's an automatic quoting when a macro was invoked inside another macro definition. But I am not sure whether this guess is right or not.

Thanks again!

Astounding
PROC Star

You've noticed something, but our explanations can only be a "best guess".  We're seeing inputs and outputs, but not the process.  Here's my interpretation.

This has nothing to do with macro quoting, but has to do with the process of compiling a macro.  As part of the macro compilation process, macro language interprets the semicolon it can "see" (at the end of the %PUT statement) as ending the %PUT statement.  The introduction of a semicolon within %A does not change that interpretation.  In open code, however, the first semicolon ends the first statement.

pobel
Calcite | Level 5

Thank you, Astounding!

Your explanation is very helpful. Thank you very much on this one!

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 6 replies
  • 1412 views
  • 3 likes
  • 4 in conversation