Date: Wed, 5 Jan 2005 11:51:52 -0700
Reply-To: Jack Hamilton <JackHamilton@FIRSTHEALTH.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Jack Hamilton <JackHamilton@FIRSTHEALTH.COM>
Subject: Re: Exit SAS gracefully / Condtional execution of code without
SAS macro
Content-Type: text/plain; charset=us-ascii
I recall hearing an explanation of why %IF can't be made to work in open
code, but I can't remember exactly what it is. Anyone else remember?
It would cause an incompatibility or ambiguity of some kind, I think.
It's not too hard to ignore only a single statement in open code:
===== SAS v9
%let go = 1;
data _null_;
%sysfunc(ifc(&GO., put 'go was true', put 'go was false', put 'go
was missing'));
run;
%let go = 0;
data _null_;
%sysfunc(ifc(&GO., put 'go was true', put 'go was false', put 'go
was missing'));
run;
=====
It's more complicated with multiple statements.
--
JackHamilton@FirstHealth.com
Manager, Technical Development
Metrics Department, First Health
West Sacramento, California USA
Coelum, non animum mutant, qui trans mare currunt.
>>> "baxter" <baxter.com@GMAIL.COM> 01/05/2005 2:00 AM >>>
Hi.
I'm currently writing a small SAS macro that generates a pin number
which has to be entered and re-ran within 60 seconds for the rest of
the program to be run. I shan't bore you with the reason why but
suffice to say that depending on certain variable values, things could
be overwritten that weren't meant to be!
My problem is simply that of preventing the rest of the code to be run
if the wrong pin number is entered. Ideally, I'd like SAS to stop
processing subsequent statements but I can't find any code that will
stop SAS elegantly without it closing down the whole "SAS System"
(such
as ABORT).
Therefore, I've decided to set a macro variable (__contProg) which
will
execute subsequent statements only if it is set to 1. But this means
the subsequent statements would have to be in SAS Macro as you can't
do
%IF &__contProg=1 etc. in open code and I really don't want to have to
bury such statements in macros.
Anyway, the code is below. Any ideas on exiting gracefully or
conditionally executing in open code will be gratefully received.
Many thanks, Rich
============
%LET type=replace; * If type = replace then the macro will execute;
option nomprint nosymbolgen;
%MACRO checkIt(varName=,varVal=,pin=,secs=);
%GLOBAL __gPinTime __gPinNum __contProg;
%LET __contProg=0;
%* Number of seconds to allow for pin number to be entered;
%IF &secs= %THEN %LET secs=60;
%* Give pin a default value if none has been entered;
%IF &pin= %THEN %LET pin=-1;
%* Give the global pin a default numeric value if it is blank;
%IF &__gPinTime= %THEN %LET __gPinTime=-1;
%* Give the global pin time a default numeric value if it is
blank;
%IF &__gPinNum= %THEN %LET __gPinNum=0;
%* If varName has not been set, the macro does not know which
criteria
to use for allowing
code to be executed. Therefore, the macro will exit early;
%IF &&varName= %THEN %DO;
%PUT ;
%PUT The varName macro variable has not been set. Please set it
before running the program;
%PUT The program will now exit;
/* %GOTO Exit;*/
%END;
%* Else if varname is equal to the value which might be dangerous,
we
ask for a pin number;
%IF &&&varName=&varVal %THEN %DO;
%* The following few blocks check that all is correct else a new
pin
number is generated.;
%IF (&__gPinNum=) %THEN %DO;
%PUT ;
%PUT ERROR: It looks like this is the first time you have ran the
program. As you have ;
%PUT ERROR: chosen "&&varName"="&varVal", and that this choice can
overwrite data, ;
%PUT ERROR: you have to enter a pin number to run it (which is
generated after this message). ;
%PUT ERROR: Please check to be certain that it is OK to overwrite
previous output from this program. ;
%PUT ERROR: Note you have 1 minute to run the program again with
the
correct pin number.;
%LET genPin=y;
%END;
%ELSE %IF %EVAL((%SYSFUNC(INT(%SYSFUNC(TIME())))-&__gPinTime) gt
&secs) %THEN %DO;
%PUT ;
%PUT ERROR: Over &secs seconds has elapsed since the pin number was
given.;
%PUT ERROR: A new pin number will be generated.;
%LET genPin=y;
%END;
%ELSE %IF %EVAL(&pin ne &__gPinNum) %THEN %DO;
%PUT ;
%PUT ERROR: The pin numbers do not match.;
%PUT ERROR: A new pin number will be generated.;
%PUT ERROR: The program will exit. ;
%LET genPin=y;
%END;
%ELSE %LET genPin=n;
%* Checking done, generate the new pin number if need be else
continue
with the program;
%IF &genPin=y %THEN %DO;
DATA _NULL_;
%* Generate 6 digit randon number;
pin=RANUNI(0);
pin=INT(pin*1000000);
CALL SYMPUT("__gPinNum",PUT(pin,6.));
%* Record the time when the random number is generated (stored in
seconds);
Time=INT(Time());
CALL SYMPUT("__gPinTime",PUT(Time,5.));
RUN;
%PUT WARNING: The new pin number is &__gPinNum;
%* Routine to exit the submitted program early;
%LET __contProg=1;
%END;
%ELSE %IF &genPin=n %THEN %DO;
%PUT ;
%PUT WARNING: Pin number accepted. The rest of the program will
continue;
%END;
%END;
%MEND checkIt;
%checkIt(varName=type,varVal=replace,pin=16);
==============
"MMS <firsthealth.com>" made the following annotations.
------------------------------------------------------------------------------
This message, including any attachments, is intended solely for the use
of the named recipient(s) and may contain confidential and/or
privileged information. Any unauthorized review, use, disclosure or
distribution of this communication(s) is expressly prohibited.
If you are not the intended recipient, please contact the sender by
reply e-mail and destroy any and all copies of the original message.
Thank you.
=============================================================================