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

Hi,

I was wondering if some kind person / SAS expert could tell me what I am doing wrong. The macro below ran before, but now it does not work and I cannot determine why. When I run the code below as a single run (i.e. not from a macro call) starting from *** Single Run %let i=1; .... until.... *** End single run; the code works fine. If I change %let i=2, it is also okay. Changing %let i=3,4,5....16 are all okay as simple SAS code. But then when I put in the %do loop and %macro statements, I get errors such as

"ERROR 180-322: or it is used out of proper order." and CREATE (as in: proc sql; create table) is underlined in red with 180 written underneath.

Could someone tell me what I am doing wrong?

%macro make_index;

%do i=1 %to 16;

*** Single run %let i=1;

proc sql;

    create table data_&&index_&i.._idx as

    select L.*, R.ret_&&index_&i as ret_indx

    from data_&&index_&i as L left join &indx as R

    on L.date = R.date and L.estper_beg<=R.date<=L.evtwin_end; quit;

proc sort; by sdc_dealnum cusip8 date; run;

data data_&&index_&i.._idx; set data_&&index_&i.._idx;

    label     ret_indx     = 'Return on Bond Index'

            dpr         = 'Daily Bond Price'

            ret            = 'Daily Bond Return';

    rename ret=ret_dpr date=dpr_date;

    drop bindx; run;

*** End single run;

%end;

%mend; %make_index;

Thanks so much!

Ian.

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

I can see what is happening, but it's harder to explain why it should be so.  The crux of the matter is that SAS is interpreting this section of code differently, depending on whether it appears inside or outside a macro definition:

*** Single run %let i=1;

proc sql;

Outside of a macro definition, this is a comment statement followed by a PROC SQL statement.

Inside a macro definition, it gets interpreted differently, as if the code were:

%let i=1;

*** Single run proc sql;

So there is no longer a PROC SQL statement, and the CREATE statement gives you the error message.

To get it to work is straightforward.  Get rid of the macro trigger.  For example, inside the macro definition, use:

*** Single run with i=1;

proc sql;

Good luck.

View solution in original post

4 REPLIES 4
Astounding
PROC Star

I can see what is happening, but it's harder to explain why it should be so.  The crux of the matter is that SAS is interpreting this section of code differently, depending on whether it appears inside or outside a macro definition:

*** Single run %let i=1;

proc sql;

Outside of a macro definition, this is a comment statement followed by a PROC SQL statement.

Inside a macro definition, it gets interpreted differently, as if the code were:

%let i=1;

*** Single run proc sql;

So there is no longer a PROC SQL statement, and the CREATE statement gives you the error message.

To get it to work is straightforward.  Get rid of the macro trigger.  For example, inside the macro definition, use:

*** Single run with i=1;

proc sql;

Good luck.

iank131
Quartz | Level 8

Astounding, you simply are ..... astounding!! Smiley Happy Such a simple thing!!  I just removed the commented  (i.e. asterisked) lines and .... it works!! This is why it worked before and not now. I was having problems with another macro I wrote and your explanation also helped me to solve that one too. Thanks again!

Ian.

Thanks for your help.

Ian.

ballardw
Super User

For commenting in macros it is best to use either the /* */ or %* instead of * preceding a statement.

Partially because of this behavior I almost never use the single statement comment starting with *. Then I don't have to change my commenting style when I'm within a macro.

Tom
Super User Tom
Super User

Macro will expand the macro statements inside of *; comments the same way it would inside of any other SAS statement.

You will also get in trouble if using unbalanced quotes inside of *; and %*; comments.

Even given these restrictions I still use *; comments inside of macro for comments that I want to appear in the SAS log when MPRINT is on.

For example:

%if &sort %then %do ;

* Sort dataset before using ;

  proc sort ;

    by id;

  run;

%end;

But when the comment is on pure macro logic code then I would use %* ; comments as printing them with MPRINT would just clutter and confuse the log.

%if &sort %then %do;

%* Add by variable into keep list ;

  %let keep=&byvar &keep;

%end;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 4 replies
  • 2653 views
  • 5 likes
  • 4 in conversation