SAS Tutorial: Coding PUTs Without Coding PUTs

Listing 5: The MULTIC Macro Source Code

Note that Listing 5 is composed of three parts:

This is in keeping with the original format as required for publication in the WISAS proceedings.

Listing 5a: The MULTIC SAS Macro Source Code, Part 1 of 3

001 %GLOBAL PHEAD1 PHEAD2 PHEAD3 PHEAD4 PHEAD5;
002 %MACRO MULTIC(DS_IN,FOUT,COLS,LS,PS,VR1,AT1,W1,P1,F1,VR2,AT2,W2,P2,F2,
003 VR3,AT3,W3,P3,F3,VR4,AT4,W4,P4,F4,VR5,AT5,W5,P5,F5,VR6,AT6,W6,P6,F6,
004 VR7,AT7,W7,P7,F7);
005 %*********************************************************************;
006 %** MACRO:....: MULTIC                                             ***;
007 %** FILE......: AAAA.PLAXCO.SASMACS(MULTIC)                        ***;
008 %** AUTHOR....: JIM PLAXCO                                         ***;
009 %** PURPOSE...: SAS MACRO TO BUILD A MULTICOLUMN REPORT            ***;
010 %** PARAMETERS: DS_IN = DATASET TO READ FROM                       ***;
011 %**             FOUT... REPORT FILE TO CREATE                      ***;
012 %**             COLS... NUMBER OF COLUMNS TO PRINT                 ***;
013 %**             LS..... NUMBER OF CHARACTERS PER LINE              ***;
014 %**             PS..... NUMBER OF LINES PER PAGE                   ***;
015 %**             VR1-7 = 1-7 VARAIBLES TO TURN INTO ARRAYS          ***;
016 %**                     ARRAY NAME IS AVR#, ELEMENT IS VR#1-N      ***;
017 %**             AT1-7 = ATTRIBUTES FOR EACH OF THE ARRAYS          ***;
018 %**             W1-7... OUTPUT WIDTH FOR THE VARIABLE              ***;
019 %**             P1-7... BLANK PADDING ON EACH SIDE OF THE OUTPUT   ***;
020 %**             F1-7... OUTPUT FORMATS FOR THE VARIABLES           ***;
021 %**                                                                ***;
022 %**  NOTE THAT MULTIC NEEDS THE NUMBER OF OBSERVATION TO BE PLACED ***;
023 %**  IN THE MACRO VARIABLE TOTOBS.                                 ***;
024 %**                                                                ***;
025 %**  NOTE THAT MULTIC NEEDS THE COLUMN HEADING INFO TO BE PLACED   ***;
026 %**  IN THE WORK DATASET WORK.HDR                                  ***;
027 %**                                                                ***;
028 %*********************************************************************;
029 %LOCAL CBRK CEND CI2 CNDX COLV ICNDX MI OBS P_CNT PLEN TESTCNT XERR;
030 %LET XERR=%EVAL(0);
031 %LET P_CNT=%EVAL(0);
032 %DO MI=1 %TO 5;
033  %IF "&&PHEAD&MI" NE ""  %THEN  %LET P_CNT=%EVAL(&P_CNT + 1);
034 %END;
035 %LET TESTCNT=%EVAL(&PS - &P_CNT - &HDRIN_N - 1);
036 %IF &TESTCNT  < 1 %THEN
037 %DO;
038    %PUT *** PARM ERROR: PAGE SIZE IS TOO SMALL.  THE TOTAL LINE;
039    %PUT ***             COUNT FOR THE PAGE AND COLUMN HEADING;
040    %PUT ***             EXCEEDS YOUR LINES PER PAGE VALUE;
041    %LET XERR=%EVAL(1);
042 %END;
043 %LET CBRK=%EVAL(&LS/&COLS);
044 %LET CEND=%EVAL(&COLS-1);
045 %LET OBS=%CMPRES(&TOTOBS);
046 %LET COLS=%CMPRES(&COLS);
047 
048 %LET MAXW=%EVAL(&HLEN * &COLS);
049 %IF &MAXW GT &LS %THEN
050 %DO;
051    %PUT *** PARM ERROR: LINE SIZE IS TOO SMALL FOR HEADERS;
052    %PUT ***             YOUR HEADERS NEED A LINE SIZE OF &MAXW;
053    %PUT ***             EITHER INCREASE PAGE SIZE OR;
054    %PUT ***             SHRINK COLUMN HEADINGS;
055    %LET XERR=%EVAL(1);
056 %END;
057 
058 %IF &XERR = 0 %THEN
059 %DO;
060 DATA _NULL_;
061 FILE &FOUT NOPRINT NOTITLES;
062 RETAIN NDX NOMORE 0;
063 RETAIN EVAR 0;
064 RETAIN PB 0CX;
065 RETAIN IC1 0 ;
066 %DO MI=1 %TO &CEND;
067   %LET COLPT&MI =%EVAL(&MI*&CBRK);
068   %LET ICNDX=%EVAL(&MI+1);
069   RETAIN IC&ICNDX 0 ;
070 %END;
071 RETAIN EPP 0 ;     /*  ELEMENTS PER PAGE         */
072 RETAIN EPC 0 ;     /*  ELEMENTS PER COLUMN       */
073 RETAIN ENDC1 1 ;   /*  LAST ELEMENT OF COLUMN 1  */
074 RETAIN PNDX 0 ;    /*  PAGE INDEX                */

Listing 5b: The MULTIC SAS Macro Source Code, Part 2 of 3

001 %DO MI=1 %TO 7;
002  %IF &&VR&MI NE  %THEN
003   %DO;
004     ARRAY A&&VR&MI.{&OBS.} &&AT&MI &&VR&MI..1-&&VR&MI.&&OBS ;
005     RETAIN &&VR&MI..1-&&VR&MI..&&OBS ;
006   %END;
007 %END;
008 DO UNTIL (NOMORE=1);
009   SET &DS_IN END=NOMORE;
010   NDX + 1;
011 %DO MI=1 %TO 7;
012  %IF &&VR&MI NE  %THEN
013   %DO;
014   A&&VR&MI.{NDX} = &&VR&MI;
015   %END;
016 %END;
017 END;
018 
019 EPP = INT(&COLS.* &TESTCNT.);
020 EPC = INT(EPP/&COLS.);
021 DO UNTIL(IC&COLS. &gt; &OBS.);
022   LINK HDR;
023     IC1 = INT(1+(PNDX*EPP)); PNDX+1;
024     ENDC = IC1 + EPC;
025 %DO CI=2 %TO &COLS ;
026 %LET CI2=%EVAL(&CI-1);
027   %IF &CI = 2 %THEN
028   %DO;
029     IC2 = ENDC;
030   %END;
031     %ELSE
032   %DO;
033     IC&CI = EPC + IC&CI2. ;
034   %END;
035 %END;

Listing 5c: The MULTIC SAS Macro Source Code, Part 3 of 3

001 %LET C1=%EVAL(1+&P1);
002 %DO MI=2 %TO 7;
003  %IF &&VR&MI NE  %THEN
004   %DO;
005     %LET BDX=%EVAL(&MI - 1);
006     %LET C&MI=%EVAL(&&C&BDX + &&P&BDX + &&W&BDX + &&P&MI);
007   %END;
008 %END;
009 
010   DO UNTIL( IC1 = ENDC );
011 %DO CI=1 %TO %EVAL(&COLS -1) ;
012    %LET CNDX=%EVAL((&CI-1)*&CBRK);
013    IF IC&CI &lt;= &TOTOBS THEN
014    PUT
015    %DO MI=1 %TO 7;
016        %IF &&VR&MI NE  %THEN
017           %DO;
018               @&&C&MI.+&CNDX. A&&VR&MI.{IC&CI.} &&F&MI
019           %END;
020    %END;
021    @ ;
022    %IF &CI NE &COLS %THEN
023       %DO;
024            PUT @&&COLPT&CI. '|' @ ;
025       %END;
026 %END;
027  IF IC&COLS &lt;= &TOTOBS THEN
028     PUT
029 %DO MI=1 %TO 7;
030  %IF &&VR&MI NE  %THEN
031   %DO;
032         %LET CNDX=%EVAL((&COLS-1)*&CBRK);
033         @&&C&MI.+&CNDX. A&&VR&MI.{IC&COLS.} &&F&MI
034   %END;
035 %END;
036     ;
037     ELSE PUT;
038 %DO MI=1 %TO &COLS;
039   IC&MI + 1;
040 %END;
041  END;
042  END;
043 RETURN;
044 **********************************************************************;
045 HDR:
046 PUT @01 PB IB1. @ ;
047 %DO MI=1 %TO 5;
048  %PUT PHEAD &MI =  &&PHEAD&MI;
049  %IF &quot;&&PHEAD&MI&quot; NE &quot;&quot;  %THEN
050   %DO;
051       %LET PLEN=%LENGTH(&&PHEAD&MI);
052       %LET COLV=%EVAL(1+(&LS-&PLEN)/2);
053       PUT @&COLV &quot;&&PHEAD&MI.&quot;;
054   %END;
055 %END;
056    PUT ' ';
057    DO HDR_LINE=1 TO LASTLINE BY 1;
058    SET HDR POINT=HDR_LINE NOBS=LASTLINE;
059    PUT
060 %DO CI=1 %TO &COLS;
061    %LET CNDX=%EVAL((&CI-1)*&CBRK);
062        @1+&CNDX HDRDATA $CHAR&CBRK..
063 %END;
064      ;
065 END;
066 RETURN;
067 %END;
068 %MEND MULTIC;

Return to the SAS Tutorial: Coding PUTs Without Coding PUTs tutorial.