Search code examples
sassas-macro

How to mask "OR" with variable list passed through using SYSPBUFF in macro


I'm using SYSPBUFF to pass through various numbers of parameters into a macro. Specifically, I am passing through a list of states. One of the states being used is Oregon or "OR" and that one state is causing me error.

I get the error "ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &ST^= ERROR: The condition in the %DO %WHILE loop, &ST^=, yielded an invalid or missing value, . The macro will stop executing.

I've used all the various quoting masks to try to resolve this issue but none of it is working.

&STATES includes the following states: AK,AZ,CA,HI,ID,NV,OR,WA

Here is my current code:

RSUBMIT;
PROC SQL;
connect to oracle
(path=DW user=&USER pw=&PW);
%macro DTCNT() / parmbuff; 
%let i=1;
%let ST=%scan(&SYSPBUFF,&I);  

%do %while (&ST^=);
CREATE TABLE MD_&ST._IP_ADJDT_CNTS_S1 AS
select *
from connection to oracle
  (SELECT adjudication_date,
          count (*) as LINE_CNT 
   from MD_r&NUM..&ST._IP_hdr_f
   group by adjudication_date
   order by adjudication_date);

      %let i=%eval(&I+1);  
      %let ST=%scan(&SYSPBUFF,&I);
      %end;
%mend DTCNT;
%DTCNT(&STATES);

disconnect from oracle;
QUIT;
ENDRSUBMIT;

Any assistance would be greatly appreciated.

Thanks in advance.


Solution

  • The issue here is Oregon. Its abbreviation is OR, which is also a reserved word (oops!). Remember the macro language is just text that is then parsed like normal - so when it finds &ST and translates to OR, it sees that as

    %do %while (or ^= )
    

    which causes it to get confused since it doesn't see anything to use with or.

    You can use macro quoting here to cause SAS not to treat it like the boolean operator. %SUPERQ is the goto one for me, but a few of them should work.

    Here's an example. I added some extra stuff to scan also to handle the parens.

    %let states=AK,AZ,CA,HI,ID,NV,OR,WA;
    %macro DTCNT() / parmbuff; 
    %let i=1;
    %put &=syspbuff.;
    %let ST=%scan(&SYSPBUFF,&I,%str(%(%),));
    %put &=st.;
    
    %do %while (%superq(ST)^=);
    %put &=st;
    %let i=%eval(&i.+1);
    %let ST=%scan(&SYSPBUFF,&I,%str(%(%),));  
    %end;
    %mend DTCNT;
    %DTCNT(&STATES);