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.
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.
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.
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.
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.
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.