BookmarkSubscribeRSS Feed
rebelde52
Fluorite | Level 6

Hello,

 

Im stuck on how %eval needs to work in this code. Could anyone offer advice or what could be wrong?

 

%let exit=N ; 
,
,
long code in-between
'
'

%if %eval(&exit in(y, Y)) %then %let jump_out=1; %else %let jump_out=0;
    %end;

    %else %do; 
        %let msg = Please fill in all required parameters!; 
        %if %eval(&exit in(y, Y)) %then %do; %let msg=; %let jump_out=1; %end; %else %let jump_out=0;
    %end;

    %if &jump_out %then %abort cancel;
%end;

%mend ckInput;
%ckInput;

ERROR: More positional parameters found than defined.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: NOT ( %isBlank(&doc_path) | %isBlank(&out_path))
ERROR: The macro CKINPUT will stop executing
14 REPLIES 14
Reeza
Super User
Given the error message of &doc_path which is not shown in the code, not sure this is the right piece of code.

To get the full log when using macros, make sure to have the following options enabled.

options mprint symbolgen;
ballardw
Super User

Since your error message includes this bit:

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: NOT ( %isBlank(&doc_path) | %isBlank(&out_path))

And "NOT" does not appear anywhere in your shown code then the code you show is pretty obviously not the issue.

 

Note: This error:

ERROR: More positional parameters found than defined.

has about a 90% chance, in my humble experience, of having values passed as parameters to some macro that include more commas than you expect.

Consider this simple macro:

%macro dummy(parm);
   %put Parm is &parm.;
%mend;

Now lets show passing two different values of a parameter using another macro variable:

184  %let p1 = This is a simple parameter value.;
185  %dummy(&p1.);
Parm is This is a simple parameter value.

First value okay. Now the second:

187  %let p2=This parameter has a , in the middle.;
188  %dummy(&p2.);
ERROR: More positional parameters found than defined.

Even though this only passed a single macro value as the attempted parameter SAS treats the comma in the value as a delimiter for the parameter list.

One way around this, when you know or suspect a given parameter value may contain one or more commas:

199  %let p2=This parameter has a , in the middle.;
200  %dummy(%bquote(&p2.));
Parm is This parameter has a , in the middle.

%bquote is one of the macro language quoting functions and are used to get around some of the problems involved with passing values with characters like comma that may have special meaning where you don't want them. There are others depending on need and specific values.

So very likely you need to determine value value you are passing that contains one or more commas and address that.

 

The Option Mprint that @Reeza recommends is one way to find such if you don't know your data and code intimately. Though the main result is most likely to be the error message in closer proximity to the problem statement than just appearing after the attempted execution of one or more macro calls.

 

rebelde52
Fluorite | Level 6

Thank you for your feedback! 

 

And I should mention that the 

NOT ( %isBlank(&doc_path) | %isBlank(&out_path))

is part of my code

 

below it looks like this

 

%if NOT ( %isBlank(&doc_path) | %isBlank(&out_path)) %then %do;

 

Tom
Super User Tom
Super User

To see the code from your INCLUDE file set the SOURCE2 option.  Either set it permanently for any secondary input source by change the system option from NOSOURCE2 to SOURCE2 with an OPTIIONS statement.

 

Or just add if for the duration of that one include file using the / source2 option on the %INCLUDE statement.

 

Note:  What is the source of the %ISBLANK() macro? And what is its purpose?  Most of the ones I have seen are designed to test if its argument is either EMPTY or only contains spaces (aka "blank").  But in my experience it is almost never the case that an argument is not empty by only contains blanks.  So it is normally much easier to just use the built in %LENGTH() macro function to test is an argument is EMPTY.

 

So your test could more easily be done as :

%length(&doc_path.&out_path)

Which will be true when either of those macro variables in non-empty and will not generate an error even it either of them contain commas.

 

 

rebelde52
Fluorite | Level 6

Hello, 

 

I cant seem to figure out why I get those 2 errors in my code below. Is it due to the " | " in between the conditions or is this a character issue?

 

%let msg=;
%let exit= N;
%let doc_path=;
%let out_path=;

'
'
code in between
'
' %macro isBlank(param);   %sysevalf(%superq(param)=,boolean) %mend isBlank; %macro DirExist(dir) ;     %LOCAL rc fileref return;     %let rc = %sysfunc(filename(fileref,&dir)) ;     %if %sysfunc(fexist(&fileref))  %then %let return=1;        %else %let return=0; &return %mend DirExist; %macro ckInput/minoperator; %do %until ("&msg"="");     %display xnames;         %if NOT ( %isBlank(&doc_path) | %isBlank(&out_path)) %then %do; ERROR: More positional parameters found than defined. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: NOT ( %isBlank(&doc_path) | %isBlank(&out_path))
Tom
Super User Tom
Super User

Something in the part you left out must be changing the values of one or both of those macro variables because with the values you show it does not produce that error message:

%let doc_path=;
%let out_path=;

%macro isBlank(param);
  %sysevalf(%superq(param)=,boolean)
%mend isBlank;

%if NOT ( %isBlank(&doc_path) | %isBlank(&out_path)) %then %do;
  %put NOT blank ;
%end;
%else %do;
  %put IS blank ;
%end;
1260  %if NOT ( %isBlank(&doc_path) | %isBlank(&out_path)) %then %do;
1261    %put NOT blank ;
1262  %end;
1263  %else %do;
1264    %put IS blank ;
IS blank
1265  %end;

But if you put comma(s) into the macro variable then you get that message:

1266  %let doc_path=junk,junk;
1267  %let out_path=;
1268
1269  %macro isBlank(param);
1270    %sysevalf(%superq(param)=,boolean)
1271  %mend isBlank;
1272
1273  %if NOT ( %isBlank(&doc_path) | %isBlank(&out_path)) %then %do;
ERROR: More positional parameters found than defined.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
       NOT ( | 1)
ERROR: Skipping to next %END statement.
1274    %put NOT blank ;
1275  %end;
1276  %else %do;
1277    %put IS blank ;
IS blank
1278  %end;

You can fix it by quoting the value before passing it to the macro:

Either when you create the macro variable

%let doc_path=%bquote(junk,junk);

Or when you pass the macro variable to the %ISBLANK().

%if NOT ( %isBlank(%bquote(&doc_path)) | %isBlank(%bquote(&out_path))) %then %do;

 

 

rebelde52
Fluorite | Level 6
Could I still add the %bquote if my macro variable is blank? for example
doc_path= ; ??
Tom
Super User Tom
Super User

@rebelde52 wrote:
Could I still add the %bquote if my macro variable is blank? for example
doc_path= ; ??

Not needed.

 

But it shouldn't matter as long as you don't accidentally include a space inside the %BQUOTE() function call.

rebelde52
Fluorite | Level 6

Hello below is the begging of my macros code and I get 2 error messages: ERROR: More positional parameters found than defined. ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: NOT ( %isBlank(&doc_path) | %isBlank(&out_path))

 

Really stuck with this and appreciate any feedback . 

 

options center orientation=landscape nodate nonumber nofmterr mprint fullstimer compress=yes ls=max ps=max;

%let fpath  = %sysget(New_greenpath);
%let fname  = %sysget(New_greenname);
%let fpath1 = %qsubstr(&fpath,1,%length(&fpath)-%length(&fname)-1);
x "cd &fpath1";
%put &fpath;
%put &fpath1;

%include "first_program.sas";

ERROR: More positional parameters found than defined.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: NOT ( %isBlank(&doc_path) | %isBlank(&out_path))

 

Tom
Super User Tom
Super User

Looks like the error is in the code in the included file, which you have not shown.  The code you have shown does not include that expression.  You have not shown how that macro is defined or how those two macro variables are defined.

 

But your first two macro variables might have commas in them that could cause issues if they are used in defining those two macro variables.

 

In particular FPATH could cause trouble with your %qsubstr() call.

You should add some macro quoting.

%let fpath1 = %qsubstr(%superq(fpath),1,%length(&fpath)-%length(&fname)-1);

You might also want to get this %QSYSGET() macro so that you can add the macro quoting to the value retrieved from the environment variable in the initial assignment statement.

https://github.com/sasutils/macros/blob/master/qsysget.sas

%let fpath  = %qsysget(New_greenpath);
%let fname  = %qsysget(New_greenname);

 

rebelde52
Fluorite | Level 6

could I send you a private message?

 

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
  • 14 replies
  • 2876 views
  • 0 likes
  • 5 in conversation