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

Hi ,

 

I am getting the below error when processing a macro:

 

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: eof
ERROR: The condition in the %DO %UNTIL loop, eof, yielded an invalid or missing value, .  The macro will stop executing.
ERROR: The macro MAXVAR will stop executing.

 

The code i am using is below:

%macro maxvar(libref,dstname,type);
options mprint mlogic symbolgen;
proc contents data = &libref..&dstname out=dst1 (keep = name type);
run;
data dst2 (keep = name);
set dst1;
where type = &type. ;
run;
proc sql noprint;
select name into :varlists separated by ' '  from dst2;
quit;
%put &varlists. ;
proc sql noprint;
select count(*) into :varcount from dst2;
quit;
%put &varcount.;
data minmax (keep = var v_min v_max);
array maxx(&varcount);
array minn(&varcount);
%do %until(eof);
set test.getrate end=eof;
array ch(&varcount) &varlists ;
%do j=1 %to &varcount ;
maxx(j)=max(maxx(j),lengthn(ch(j)));
minn(j)=min(minn(j),lengthn(ch(j)));
%end;
%end;
length var $32;
%do j=1 %to &varcount ;
var = vname(ch(j));
v_min=minn(j);
v_max=maxx(j);
output;
%end;
run;
%mend;

 

Just to give a idea, I am trying to find the maximum length of each character variable in a dataset. Could you please let me know what mistake i have done and what changes i need to make to remove this error.

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Your do loops shouldn't be macro do loops. You don't need any do loop since that's what a datastep does. You do want a RETAIN to hold values from one line to another. 

 

Use a conditional if to check if it's the last record and output the max for each variable in that case. 

 

As always you should create a macro off code that works in base SAS - remove all macro portions. 

 

Your array declaration is also incorrect as it doesn't have a $ to indicate character. You can avoid a good portion of the first step of your code by using _numeric_ and _character_ to reference all numeric or character variables. 

 

 

View solution in original post

4 REPLIES 4
Reeza
Super User

Your do loops shouldn't be macro do loops. You don't need any do loop since that's what a datastep does. You do want a RETAIN to hold values from one line to another. 

 

Use a conditional if to check if it's the last record and output the max for each variable in that case. 

 

As always you should create a macro off code that works in base SAS - remove all macro portions. 

 

Your array declaration is also incorrect as it doesn't have a $ to indicate character. You can avoid a good portion of the first step of your code by using _numeric_ and _character_ to reference all numeric or character variables. 

 

 

jagadeesh_2907
Calcite | Level 5

Thank you. I am bit confused on where to use the loops as macro and where can i use the normal loops. Could you please provide some tips for me on the same.

Reeza
Super User

In general use macro loops to repeat a proc or datastep.

It could also be used to generate statements that can't be done via a data step for some reason, for example the lag function. 

 

Within a datastep use a standard do loop. 

jagadeesh_2907
Calcite | Level 5
Thank you Reeza

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
  • 1415 views
  • 0 likes
  • 2 in conversation