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.
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.
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.
Astounding, you simply are ..... astounding!! 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.
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.
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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.