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

Hello,

 

I have an error message shown in my macro coding, any idea where went wrong?

%let FormatList = A B C; 
 
%let FormatCNT=%sysfunc(countw(&FormatList));                                                                                                       
                                                                                                                                        
	%do JJ = 1 %to &FormatCNT;                                                                                                                    
	                                                                                                                                        
	%let Format=%scan(&FormatList,&JJ); 
    
	proc sql;
	     select distinct &Format. from test;
	quit;

%end;

350 %let FormatList = A B C;

351

352 %let FormatlistCNT=%sysfunc(countw(&Formatlist));

353

354 %do JJ = 1 %to &FormatlistCNT;

ERROR: The %DO statement is not valid in open code.

355

356 %let Format=%scan(&Formatlist,&JJ);

WARNING: Apparent symbolic reference JJ not resolved.

WARNING: Apparent symbolic reference JJ not resolved.

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric

operand is required. The condition was: &JJ

ERROR: Argument 2 to macro function %SCAN is not a number.

357

358 proc sql;

359 select distinct &Format. from test;

-----

79

ERROR 79-322: Expecting a FROM.

360 quit;

NOTE: The SAS System stopped processing this step because of errors.

NOTE: PROCEDURE SQL used (Total process time):

real time 0.00 seconds

cpu time 0.00 seconds

ERROR: The %END statement is not valid in open code.

361

362 %end;

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

You don't mention which version of SAS your using.

the %do / %end structure likely needs to be used in an actual %macro / %mend definition and then called:

 

%macro mymacro(formatlist =); 
%let FormatCNT=%sysfunc(countw(&FormatList));                                                                                                       
                                                                                                                                        
%do JJ = 1 %to &FormatCNT;                                                                                                                    
	%let Format=%scan(&FormatList,&JJ); 
	proc sql;
	     select distinct &Format. from test;
	quit;
%end;
%mend;
%mymacro(formatlist= A B C)

I prefer to have explicit parameters in Macros instead of letting something outside the macro just "happen" to have values used inside.

 

Obviously not tested as I don't have your test dataset.

View solution in original post

6 REPLIES 6
ballardw
Super User

You don't mention which version of SAS your using.

the %do / %end structure likely needs to be used in an actual %macro / %mend definition and then called:

 

%macro mymacro(formatlist =); 
%let FormatCNT=%sysfunc(countw(&FormatList));                                                                                                       
                                                                                                                                        
%do JJ = 1 %to &FormatCNT;                                                                                                                    
	%let Format=%scan(&FormatList,&JJ); 
	proc sql;
	     select distinct &Format. from test;
	quit;
%end;
%mend;
%mymacro(formatlist= A B C)

I prefer to have explicit parameters in Macros instead of letting something outside the macro just "happen" to have values used inside.

 

Obviously not tested as I don't have your test dataset.

ybz12003
Rhodochrosite | Level 12

Thank you so much!

SASKiwi
PROC Star

Your macro code must go inside a macro:

%let FormatList = A B C; 

%macro test;
 
%let FormatCNT=%sysfunc(countw(&FormatList));                                                                                                       
                                                                                                                                        
	%do JJ = 1 %to &FormatCNT;                                                                                                                    
	                                                                                                                                        
	%let Format=%scan(&FormatList,&JJ); 
    
	proc sql;
	     select distinct &Format. from test;
	quit;

%end;

%mend test;
ybz12003
Rhodochrosite | Level 12

Thanks for your help, SASKiwi.  But your code was not working.

SASKiwi
PROC Star

@ybz12003 - Please provide more details. Post your SAS log with any notes and errors. I doubt you would give your car to a mechanic for repair and just say "its not working" Smiley Happy

ed_sas_member
Meteorite | Level 14

Hi @ybz12003 

 

The iterative %DO and %END statements are valid only inside a macro definition.

That's why you get an error.

 

Best,

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 673 views
  • 2 likes
  • 4 in conversation