Rhonda
Rhonda

Reputation: 1

Error: required operator not found in Macro: SAS

I'm working on this macro (see below) and this statement is not resolving : %if (&var_len > &&max&i) %then %let max&i=&var_len; and the error that is returned is: ERROR: Required operator not found in expression: (&var_len > &&max&i) ERROR: The macro PRCS_FREQ will stop executing

Does anyone have any idea on how I can improve this macro and to get this statement to resolve?

Macro:

%macro prcs_freq;
%do i=1 %to &n_of_var;
%global end&i f_line_count&i f_var&i;

%let max&i=1;
%let k=%eval(&i+1);
%if (&i < &n_of_var) %then %let end&i=%eval(&&cum&k-1);
%else %let end&i=&n_of_line;

%let f=%eval(&&cum&i+1);  /* line number for "Frequency" */
%let freq_pos&i=%index(%bquote(&&line&f),Frequency);  /* column position  of "Frequency" */
%let f_var&i=%upcase(%scan(%bquote(&&line&f),1,%str( )));
%let var_len=%length(&&f_var&i);
%let max&i=&var_len;

%global &&f_var&i;
%let &&f_var&i=&i; /* for Frequency */

%do j=&f+2 %to &&end&i;
  %let var_len=%length(%substr(%bquote(&&line&j),1,&&freq_pos&i-1));
  %if (&var_len > &&max&i) %then %let max&i=&var_len;
  %put *** f=&f  i=&i  j=&j  var_len=&var_len  freq_pos&i=&&freq_pos&i    
max&i=&&max&i  f_var&i=&&f_var&i;
%end; /* %do j= */
%let f_line_count&i=%eval(&&end&i-&&cum&i+1);
 %end; /* %do i= */

data _null_;
%do i=1 %to &n_of_var;
  file "&wk_dir/&&f_var&i...txt";
  %do j=&&cum&i %to &&end&i;
    put "%substr(%bquote(&&line&j),1,&&max&i+5)%substr(%bquote  (&&line&j),&&freq_pos&i)";
  %end;
%end;
run;



 /* test */
 %put =====;
 %put ===== Frequency;
 %put =====;
 %do i=1 %to &n_of_var;
 %put f_var&i=&&f_var&i   cum&i=&&cum&i   end&i=&&end&i          f_line_count&i=&&f_line_count&i   &&f_var&i=&&&&&&f_var&i;
%end;
%mend prcs_freq;

Upvotes: 0

Views: 4548

Answers (2)

Tom
Tom

Reputation: 51566

Doing complex calculations in macro code is frustrating and hard to debug. Since your macro is already generating a data step I suggest that you just replace a lot of the macro calculations with data step code. You can use CALL SYMPUTX() to generate any new macro variables that you need for later steps of the macro.

Upvotes: 0

Quentin
Quentin

Reputation: 6378

The symbolgen log shows that your macro variable &VAR_LEN resolves to: 10) . That unmatched parenthesis causes the problem, e.g.:

188  %macro ck;
189    %if 10) > 0 %then %put true;
190  %mend;
191  %ck;
ERROR: Required operator not found in expression: 10) > 0
ERROR: The macro CK will stop executing

The open parenthesis is the missing operator referred to in the error. I think the source of the extra unmatched parenthesis is this line:

%let var_len=%length(%substr(%bquote(&&line&j),1,&&freq_pos&i-1));

I think &&line&j is resolving to a value that has an unmatched close parenthesis. %BQUOTE would quote (mask) the parenthesis. But %substr() would unquote it. And then the %length function would see the close parenthesis as the end of the call to %length. Then the close parenthesis you mean to be the end of the call to %length becomes the extra parenthesis. If you change to %qsubstr() it should quote the parenthesis, and work appropriately.

Below is a test macro, illustrating what I think is the problem:

%macro test(line= ) ;
  %put &=line ;

  %let bad_var_len =%length( %substr(%bquote(&line),1,12)) ;
  %let good_var_len=%length(%qsubstr(%bquote(&line),1,12)) ;

  %put &=bad_var_len ;
  %put &=good_var_len ;

  %if &bad_var_len>0 %then %put true ;
%mend test; 

Here is the log from running it:

219  %test(line=%str(Hi mom%) how are you?))
LINE=Hi mom) how are you?
BAD_VAR_LEN=6 how )
GOOD_VAR_LEN=12
ERROR: Required operator not found in expression: &bad_var_len>0
ERROR: The macro TEST will stop executing.

Upvotes: 1

Related Questions