Date: Thu, 23 Dec 2004 20:35:20 -0500
Reply-To: "Richard A. DeVenezia" <radevenz@IX.NETCOM.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Richard A. DeVenezia" <radevenz@IX.NETCOM.COM>
Subject: Re: Open() Function too Lenient!
m n wrote:
> Dear SAS-L,
>
> I've been trying to use the open() function as a
> parameter checker--when a macro contains a DATA= or
> OUT= parameter, I want to allow data set options but
> also robustly verify that the parameter is valid. For
> instance:
>
> %macro example(DATA=);
> %local DSID RC;
>
> %let DSID=%sysfunc(open(&DATA));
> %if &DSID eq 0 %then %put ERROR: DATA invalid;
> %else %do;
> %let RC=%sysfunc(close(&DSID));
>
> data _null_;
> set &DATA;
> /* Do something useful */
> run;
> %end;
> %mend example;
>
> %example(DATA=mydata (keep=x y z))
>
> This concept works spendidly for the most part
> (succeeds when the data set options are valid, but
> fails when the data set options are invalid, such as
> when you try to keep a variable that's not on the data
> set).
>
> But the open() function has a few quirks which break
> this approach. Specifically:
>
> 1.) It successfully opens the data set even if the
> data set options are followed by garbage as in:
> open("mydata (keep=x y z) agajfds#@$@#")
> The above works fine, and open() simply ignores
> everything after the data set options.
>
> 2.) It ignores certain leading garbage characters,
> such as a single quotation mark:
> open(" ' mydata (keep=x y z)")
>
> The latter case can easily be worked around by simply
> left()ing the DATA parameter and ensuring the first
> character is a '_' or a letter. The first problem,
> though, doesn't seem to be solvable without
> re-inventing a parsing wheel.
>
> Any suggestions? I recognize that I could use the
> exist() function, but that doesn't work with data set
> options.
Since you are generating text that would cross a step boundary, you can use
a data _null_ and check the syserr.
%macro check (data=);
data _null_;
if 0 then set &data;
stop;
run;
%mend;
%check (data=foo.bar)
%put syserr=&syserr;
%put msg=%sysfunc(sysmsg());
%check (data=sashelp.class)
%put syserr=&syserr;
%put msg=%sysfunc(sysmsg());
%check (data=sashelp.class(drop=foo))
%put syserr=&syserr;
%put msg=%sysfunc(sysmsg());
--
Richard A. DeVenezia
http://www.devenezia.com/
|