BookmarkSubscribeRSS Feed
sahoositaram555
Pyrite | Level 9

Hi all, 

%macro test1(s);
%do i=1 %to %sysfunc(countw(&s,%str( ),q));
    %let varname =%scan(&s,&i.);
    call execute('%freq(DATASET = b2,VAR=&varname.,_,OUTDS=d_&varname.)');
%end;
%mend test1;

 

%test1(a b c d e f g) ;                         /* like a b c d e f g ,    I have 35 variables to pass */ 

 

 

I'm getting an error :

 

VARNAME=a
NOTE: Line generated by the invoked macro "TEST1".
37 call execute('%freq(DATASET = b2,VAR=&varname.,
37 OUTDS=d_&varname.)');

ERROR 180-322: Statement is not valid or it is used out of proper order.

VARNAME=b

NOTE: Line generated by the invoked macro "TEST1".
37 call execute('%freq(DATASET = b2,VAR=&varname.,
37 OUTDS=d_&varname.)');

ERROR 180-322: Statement is not valid or it is used out of proper order.

ERROR 180-322: Statement is not valid or it is used out of proper order.

VARNAME=c

NOTE: Line generated by the invoked macro "TEST1".
37 call execute('%freq(DATASET = b2,VAR=&varname.,
37 OUTDS=d_&varname.)');

ERROR 180-322: Statement is not valid or it is used out of proper order.

 

---------------------------------------------------------------------

 

8 REPLIES 8
Kurt_Bremser
Super User

Modify your call execute like this:

call execute(cats('%nrstr(%freq(DATASET = b2,VAR=',"&varname.,_,OUTDS=d_&varname.))"));

The %nrstr prevents timing problems caused by mixed Base SAS/macro code, and the double quotes around the second part of the call allow resolution of macro variable &varname. Macro triggers are not resolved when enclosed by single quotes.

sahoositaram555
Pyrite | Level 9
Hi @Kurt_Bremser,
I'm getting a new type of error. Kindly have a look.

VARNAME=a
180: LINE and COLUMN cannot be determined.
NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN where the error has occurred.
ERROR 180-322: Statement is not valid or it is used out of proper order.

VARNAME=b
180: LINE and COLUMN cannot be determined.
NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN where the error has occurred.
ERROR 180-322: Statement is not valid or it is used out of proper order.


PaigeMiller
Diamond | Level 26

Hello @sahoositaram555 


The post in this thread by @FreelanceReinh is the answer you want.

--
Paige Miller
sahoositaram555
Pyrite | Level 9
Hi @Kurt_Bremser,
Thanks your for your help. Due to policy issues i really cant share the % freq macro.How ever, I have modified the code by the reference that you have given, and checked that a perticular type of syntax error is coming for all the variables.

kindly have a look to my full code and the log error.
%macro test1(s=);
%do kk=1 %to %sysfunc(countw(&s,%str( ),q));
%let varname =%scan(&s,&kk.);
data dd_&varname.;
OPTIONS SPOOL;
call execute(cats('%nrstr(%freq(DATASET = b2,TRT=trt, TRTFMT =_NONE_ ,BYVAR = _NONE_,FMTVAR= _NONE_,COND= _NONE_,PCTTYPE= COL,P= _NONE_,DENOMNODISP = _NO_,
delALLDS= _YES_,MAXnumLEN= 6,clopper_pearson = _NONE_
VAR=' "&varname.,_,OUTDS=d_&varname.))"));
run;
%end;
%mend test1;

%test1(s=a t s );


Error in the log:
GOPTIONS ACCESSIBLE;
26 %test1(s=a t s);

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.DD_a may be incomplete. When this step was stopped there were 0 observations and 0 variables.
WARNING: Data set WORK.DD_a was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

NOTE: Line generated by the macro variable "VARNAME".
26 "a,_,OUTDS=d_a
__________________
22


ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, *, **, +, ',', -, /, <, <=, <>, =, >, ><, >=, AND, EQ, GE,
GT, LE, LT, MAX, MIN, NE, NG, NL, OR, ^=, |, ||, ~=.

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.DD_t may be incomplete. When this step was stopped there were 0 observations and 0 variables.
WARNING: Data set WORK.DD_t was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

NOTE: Line generated by the macro variable "VARNAME".
26 "t,_,OUTDS=d_t
________________________
22


ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, *, **, +, ',', -, /, <, <=, <>, =, >, ><, >=, AND, EQ, GE,
2 The SAS System 20:53 Thursday, September 5, 2019

GT, LE, LT, MAX, MIN, NE, NG, NL, OR, ^=, |, ||, ~=.

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.s may be incomplete. When this step was stopped there were 0 observations and 0 variables.
WARNING: Data set WORK.DD_s was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds

Kindly hep with your suggestion.
Kurt_Bremser
Super User

I think that you're keeping crucial parts of the log from us, as you use one positional parameter in the %freq call, while all others are named. That usually does not work as intended.

I've stripped your code down to the bare essentials, and it works:

%macro freq(dataset=,var=,outds=);
%put dataset=&dataset;
%put var=&var;
%put outds=&outds;
%mend;

%macro test1(s);
%do i=1 %to %sysfunc(countw(&s,%str( ),q));
    %let varname =%scan(&s,&i.);
    call execute(cats('%nrstr(%freq(DATASET = b2,VAR=',"&varname.,OUTDS=d_&varname.))"));
%end;
%mend test1;

data _null_;
%test1(a b c d e f g)
run;

Take this code and expand from there.

Before putting code in a macro, make sure that it works without all the macro code.

Quentin
Super User

You're missing a comma in:

call execute(cats('%nrstr(%freq(DATASET = b2,TRT=trt, TRTFMT =_NONE_ ,BYVAR = _NONE_,FMTVAR= _NONE_,COND= _NONE_,PCTTYPE= COL,P= _NONE_,DENOMNODISP = _NO_,
delALLDS= _YES_,MAXnumLEN= 6,clopper_pearson = _NONE_
VAR=' 
, /*need comma here*/
"&varname.,_,OUTDS=d_&varname.))")); run;

But more importantly, you don't need call execute here, and it makes the code harder to read.

 

You've already written a macro %DO loop.  Within that loop you can call %FREQ.  You don't need a DATA STEP and CALL EXECUTE, since you're not reading any data.

 

Below is an example like yours, modified to just call %FREQ within the %DO loop:

 

%macro test1(data=,var=);
%local i varname;
%do i=1 %to %sysfunc(countw(&var,%str( ),q));
  %let varname =%scan(&var,&i,%str( ),q);
  %put &=i &=varname ;
  %freq(data =&data,VAR=&varname)
%end;
%mend test1;

%macro freq(data=,var=) ;
  proc freq data=&data ;
    tables &var ;
  run ;
%mend freq ;

options mprint ;
%test1(data=sashelp.shoes,var=Product Region Returns)

 

 

FreelanceReinh
Jade | Level 19

Hi @sahoositaram555,

 

CALL EXECUTE can only be used in a DATA step. So, if macro test1 is not called within a DATA step, don't use CALL EXECUTE, but simply call the inner macro as usual: %freq(DATASET=...)

(no semicolon required).

 

The underscore (positional parameter between keyword parameters VAR and OUTDS? Not occurring in your log excerpt, though.) is likely to produce further error messages, but these will have nothing to do with the outer macro.

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

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
  • 8 replies
  • 2104 views
  • 7 likes
  • 5 in conversation