Reputation: 1
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
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
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