Date: Sat, 3 Feb 1996 14:23:42 GMT
Reply-To: Jason Sharpe & Joel Fisher <JRSharpe@POP3.CRIS.COM>
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: Jason Sharpe & Joel Fisher <JRSharpe@POP3.CRIS.COM>
Organization: Concentric Internet Services
Subject: Re: Help with another macro problem
Hi Eric,
Based on the questions you've had about macro, it seems like you
might be missing a fundamental understanding of what the macro
facility is really doing for you. If your your not real experienced
with macro, a good trick to writing it is to NOT use macro until
you've written one or two possible code sections that you expect
to result from the macro code. Then reverse the process and
insert the macro code. For example:
FILENAME IFLOG1 "....";
DATA TEMP;
LENGTH IFSTMT $200.;
RECORD = 1;
SET PRSLOGIC POINT=RECORD;
IF WTFLAG EQ 1 THEN
DO; /* INT. BLOCK OF CODE #1, IF TO BE RUN IN THE SAME DATASTEP */
END; /* INT. BLOCK OF CODE #1, IF TO BE RUN IN THE SAME DATASTEP */
ELSE IF WTFLAG EQ 2 THEN
DO; /* INT. BLOCK OF CODE #2, IF TO BE RUN IN THE SAME DATASTEP */
END; /* INT. BLOCK OF CODE #2, IF TO BE RUN IN THE SAME DATASTEP */
RUN;
/* EXT. BLOCK OF CODE, IF TO BE RUN OUTSIDE THE DATASTEP */
DATA STEP2;
....
RUN;
The above is what you might be trying to get. There's a significant
difference in your final macro depending on whether the code is
to be executed inside the same DATASTEP or if it is to run outside.
If it's inside the same DATASTEP, then you probably don't want to
use macro. You have to have all IF/THEN/DO blocks present while the
DATASTEP is running. If the code is outside the DATASTEP, then you
will want macro. The following two macros will create either the
internal / external versions. I'll keep code executed by the macro
facility in lowercase. Note, the macro facility will process until
a DATA, PROC, or RUN boundary is encountered, then the code that
was generated prior to the boundary will execute, then the macro
facility will resume ...
/* VERSION 1 */
%macro makfiles;
/* PROCESS EACH RECORD IN PRSLOGIC ONE AT A TIME */
%do j = 1 %to &lastline;
FILENAME IFLOG&j ".....";
DATA TEMP;
LENGTH IFSTMT $200;
RECORD = &j;
SET PRSLOGIC POINT = RECORD;
IF WTFLAG EQ 1 THEN
DO; /* INT. BLOCK OF CODE #1 */
END; /* INT. BLOCK OF CODE #1 */
ELSE IF WTFLAG EQ 2 THEN
DO; /* INT. BLOCK OF CODE #2 */
END; /* INT. BLOCK OF CODE #2 */
/* STOP THE DATASTEP USING POINT= LOGIC */
STOP;
RUN;
%end; /* PROCESS EACH RECORD IN PRSLOGIC ONE AT A TIME */
%mend makfiles;
/* VERSION 2 */
%macro makfiles;
/* PROCESS EACH RECORD IN PRSLOGIC ONE AT A TIME */
%do j = 1 %to &lastline;
FILENAME IFLOG&j ".....";
DATA TEMP;
LENGTH IFSTMT $200;
RECORD = &j;
SET PRSLOGIC POINT = RECORD;
/* STORE VALUE OF WTFLAG FOR RECORD BEING POINTED TO */
/* ASSUMING WTFLAG IS NUMERIC ... */
CALL SYMPUT('CUR_FLAG', PUT(WTFLAG,BEST.) );
/* STOP DATASTEP USING POINT= LOGIC */
STOP;
/* YOU ABSOLUTELY MUST HAVE THIS RUN STMT TO CREATE A BOUNDARY */
RUN;
/* THE NEXT DATASTEP TO RUN DEPENDS ON THE RESOLUTION OF CUR_FLAG */
%if &cur_flag eq 1 %then
%do; /* DATASTEP #1 */
DATA ONE;
/* REMAINING CODE */
RUN;
%end; /* DATASTEP #1 */
/* ALTERNATIVE DATASTEP */
%if &cur_flag eq 2 %then
%do; /* DATASTEP #2 */
DATA TWO;
/* REMAINING CODE */
RUN;
%end; /* DATASTEP #2 */
%end; /* PROCESS EACH RECORD IN PRSLOGIC ONE AT A TIME */
%mend makfiles;
The most important thing to understand about macro is what it's for and
what it's not for. Macro is really nothing but a glorified word processor
to help write you SAS programs on the fly. It's not really meant to be
the actual program (although there are some who would argue this with me).
Try to always figure out what the program would be if there was no such
thing as macro. Code that is repetitive and code that has to be
conditionally EXISTING (not the same thing as executed) is probably
a good candidate to be produced by the macro facility.
Hope this helps,
Jason R. Sharpe
JRSharpe@pop3.cris.com