X-Mailer: ELM [version 2.2 PL16]
Newsgroups: bit.listserv.sas-l
Date:         Sat, 15 Aug 1992 10:47:08 CDT
Reply-To:     "R. Snyder" <rsnyder@LOBBY.TI.COM>
From:         "R. Snyder" <rsnyder@LOBBY.TI.COM>
Subject:      Re: Including macros into SAS program
Comments: To: WHITMIR1%NIEHS.BITNET@uga.cc.uga.edu
Comments: cc: sas-l@uga.cc.uga.edu
              "WHITMIR1%NIEHS.BITNET@uga.cc.uga.edu" at Aug 14, 92 1:38 pm

WHITMIR1@NIEHS.BITNET@uga.cc.uga.edu writes:
>
> Hello ,
>
> I have large nested IF THEN ELSE in my program.  I wanted to know if there is
 a
> way to write section of the code in macro to make the program more efficient.
> I know a little about macro but not enough to write one on my own!
> I looked at the section "Including macros into sas program" of SAS guide to
> macro processing.  The problem is I don't know how to write a macro.
> Could anybody help me on that. I included part of the sample program below.
> Thanks in advance.
>
> DATA ALL;
>  MERGE ONE(IN=IN1) TWO(IN=IN2);
>   BY ID;
> IF IN1 AND IN2;
>
> TSTREFMO = .;   TSTREFYR = .;
> IF (RC33 ^= 997 AND RC33 ^= 998) AND (RC46 ^= 997 AND RC46 ^= 998) THEN
>  DO;
>   IF RC33 = 1 THEN
>    DO;
>     TSTREFMO = TESTMO;
>     TSTREFYR = TESTYR;
>    END;
>   IF RC33 = 2  THEN
>    DO;
>     IF TESTMO IN (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) THEN
>      DO;
>       TSTREFMO = TESTMO - 1;
>       TSTREFYR = TESTYR;
>      END;
>     ELSE IF TESTMO = 1 THEN
>      DO;
>       TSTREFMO = 12;
>       TSTREFYR = TESTYR - 1;
>      END;
>    END;
> END;
> IF (TSTRF_DT NE . AND RC33_DT NE .) THEN
>  DO;
>   IF (RC33_DT NE TSTRF_DT) THEN
>    DO;
>     VAR1 = 'RC33 = ' || PUT(RC33,Z3.);
>     VAR2 = 'RC33_DT = ' || PUT(RC33MO,Z2.) || PUT(RC33YR,Z2.);
>     VAR3 = 'TSTRF_DT = ' || PUT(TSTREFMO,Z2.) || PUT(TSTREFYR,Z2.);
>     VAR4 = 'RC32_DT = ' || PUT(RC32MO,Z2.) || PUT(RC32YR,Z2.);
>     VAR5 = 'RC32A_DT = ' || PUT(RC32AMO,Z2.) || PUT(RC32AYR,Z2.);
>     OUTPUT;
>    END;
>  END;
>

I have included two examples of ways to replace in-lime code with a 'called'
routine. The first is the macro method that you requested. I suggest looking
at the %macro statement definition and the preceding "Macro Invocations"
section of the "SAS Guide to Macro Processing" to get started with writing
simple macros such as the one I've included. The second approach I've
illustrated involves using a suroutime and the 'link' statement. If you
do not need macro variables then this is also a practical approach. You may
also want to look at the '%include' statement in the "SAS Language
Reference".

This is option 1. Note that the macro definition must be input prior to
attempting to invoke it.

============================================================================

%macro complex;  /* Begin macro definition */

IF (RC33 ^= 997 AND RC33 ^= 998) AND (RC46 ^= 997 AND RC46 ^= 998) THEN
 DO;
  IF RC33 = 1 THEN
   DO;
    TSTREFMO = TESTMO;
    TSTREFYR = TESTYR;
   END;
  IF RC33 = 2  THEN
   DO;
    IF TESTMO IN (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) THEN
     DO;
      TSTREFMO = TESTMO - 1;
      TSTREFYR = TESTYR;
     END;
    ELSE IF TESTMO = 1 THEN
     DO;
      TSTREFMO = 12;
      TSTREFYR = TESTYR - 1;
     END;
   END;
END;

%mend complex;   /* End macro definition */

/* Begin SAS Program */

DATA ALL;
 MERGE ONE(IN=IN1) TWO(IN=IN2);
  BY ID;
IF IN1 AND IN2;

TSTREFMO = .;   TSTREFYR = .;

%complex;                     /* Invoke macro */

IF (TSTRF_DT NE . AND RC33_DT NE .) THEN
 DO;
  IF (RC33_DT NE TSTRF_DT) THEN
   DO;
    VAR1 = 'RC33 = ' || PUT(RC33,Z3.);
    VAR2 = 'RC33_DT = ' || PUT(RC33MO,Z2.) || PUT(RC33YR,Z2.);
    VAR3 = 'TSTRF_DT = ' || PUT(TSTREFMO,Z2.) || PUT(TSTREFYR,Z2.);
    VAR4 = 'RC32_DT = ' || PUT(RC32MO,Z2.) || PUT(RC32YR,Z2.);
    VAR5 = 'RC32A_DT = ' || PUT(RC32AMO,Z2.) || PUT(RC32AYR,Z2.);
    OUTPUT;
   END;
 END;

============================================================================

This is option 2. Note the addition of a return command after the main
body of the program.

/* Begin SAS Program */

DATA ALL;
 MERGE ONE(IN=IN1) TWO(IN=IN2);
  BY ID;
IF IN1 AND IN2;

TSTREFMO = .;   TSTREFYR = .;

link subr;                    /* Call subroutine */

IF (TSTRF_DT NE . AND RC33_DT NE .) THEN
 DO;
  IF (RC33_DT NE TSTRF_DT) THEN
   DO;
    VAR1 = 'RC33 = ' || PUT(RC33,Z3.);
    VAR2 = 'RC33_DT = ' || PUT(RC33MO,Z2.) || PUT(RC33YR,Z2.);
    VAR3 = 'TSTRF_DT = ' || PUT(TSTREFMO,Z2.) || PUT(TSTREFYR,Z2.);
    VAR4 = 'RC32_DT = ' || PUT(RC32MO,Z2.) || PUT(RC32YR,Z2.);
    VAR5 = 'RC32A_DT = ' || PUT(RC32AMO,Z2.) || PUT(RC32AYR,Z2.);
    OUTPUT;
   END;
 END;

 return;                                       /* NOTE */

 subr:

 IF (RC33 ^= 997 AND RC33 ^= 998) AND (RC46 ^= 997 AND RC46 ^= 998) THEN
 DO;
  IF RC33 = 1 THEN
   DO;
    TSTREFMO = TESTMO;
    TSTREFYR = TESTYR;
   END;
  IF RC33 = 2  THEN
   DO;
    IF TESTMO IN (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) THEN
     DO;
      TSTREFMO = TESTMO - 1;
      TSTREFYR = TESTYR;
     END;
    ELSE IF TESTMO = 1 THEN
     DO;
      TSTREFMO = 12;
      TSTREFYR = TESTYR - 1;
     END;
   END;
END;

return;

============================================================================

Regards,

Bob Snyder, Texas Instruments, Sherman, TX
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU