DATA Step, Macro, Functions and more

Macro to create a tempory file [Windows]

Reply
Contributor
Posts: 24

Macro to create a tempory file [Windows]

[ Edited ]

As some of you may know, I have a large collection of (legacy) sas macros (http://www.datavis.ca/sasmac/

Some of these need to

create a temporary file and I've used the utility macros below in a quite a few top-level macros.  Under Windows, there has always been the problem that it tries to use `drive:\temp` as the directory, and this fails if that directory doesn't exist. 

 

I suppose I could just use `.` (the current directory), but perhaps someone has a better way?

 

/* ---------------------------------------------------------------
TITLE:  Handle temporary files in a system- and version-independent way.
 --------------------------------------------------------------- */

%macro tempfile(fileref,ls,options);
   %global tempfn;
   %if %length(&ls)=0 %then %let ls=80;

   %if %sysevalf(&sysver  > 6.10) %then %do;
		filename &fileref temp &options
			%if %length(&ls)>0 %then lrecl=&ls;
			;		
		%end;
	%else %do;
		%if &sysscp = CMS
			%then %let tempfn=&fileref output a;
		%else %if &sysscp = WIN 
			%then %let tempfn=&fileref..tmp;
		%else /* assume unix */ 
			%let tempfn=/tmp/&fileref..tmp;
		filename &fileref "&tempfn" lrecl=&ls &options;
		%end;
%mend;

%macro tempdel(fileref);
   %global tempfn;
	%if length(&tempfn)=0 %then %goto done;
    *-- Avoid annoying flash with X commands;
    %if %sysevalf(&sysver  > 6.10) %then %do;
        %let rc=%sysfunc(fdelete(&fileref));
        %let rc=%sysfunc(filename(&fileref,''));
    %end;

    %else %do;
		%if &sysscp = CMS
			%then cms erase &tempfn;
		%else %if &sysscp = WIN
			%then %do;
				options noxsync noxwait; run;
				%sysexec(erase &tempfn); run;
				options   xsync   xwait; run;
			%end;
		%else /* assume flavor of UNIX */
				%sysexec(rm -f &tempfn);
    %end;
	 filename &fileref clear;
	 %let tempfn=;
%done:
%mend;

 

Super User
Posts: 5,500

Re: Macro to create a tempory file [Windows]

Posted in reply to michael_friendly

Couldn't you just create it on the fly:

 

x 'mkdir temp';

 

That could go right before the FILENAME statement.  It might hiccup if that directory already exists, but you can test it to see if you get the result you want.

 

Of course if you ever want to find the directory, you have to know where it will be located.  But that's another story for another day.

Contributor
Posts: 24

Re: Macro to create a tempory file [Windows]

Posted in reply to Astounding

Under Windows I avoid 'x' commands, and try to avoid hicupps too.

Super User
Posts: 5,500

Re: Macro to create a tempory file [Windows]

Posted in reply to michael_friendly

Well, you could always use %sysexec instead of X.

 

There are functions to check everything ... does a file exist, does a SAS data set exist ... there must be one that checks whether a folder exists.  Since you're in the middle of a macro, assuming you find the proper function, you could use %IF/%THEN to determine whether or not to issue:

 

%sysexec mkdir temp;

 

Quotes are no longer needed when you switch from X to %SYSEXEC.

Super Contributor
Posts: 271

Re: Macro to create a tempory file [Windows]

[ Edited ]
Posted in reply to michael_friendly

The link of your legacy macros is not working ! Never mind, was able to find it.  Thanks !

Contributor
Posts: 24

Re: Macro to create a tempory file [Windows]

Posted in reply to SAS_inquisitive

Fixed.

Super User
Posts: 19,785

Re: Macro to create a tempory file [Windows]

Posted in reply to michael_friendly

What about finding the path to the work library and using that? It seems like a good idea to me, since it will also get cleaned up in case?

Super User
Posts: 10,023

Re: Macro to create a tempory file [Windows]

Posted in reply to michael_friendly

Michael,

I don't know if the following can fit your macro. 

 

filename x temp;

 

So you use this TEMP filename at anywhere at any version of OS, if I was right .

Super User
Super User
Posts: 7,942

Re: Macro to create a tempory file [Windows]

Posted in reply to michael_friendly

@Reeza has the simplest method, 

filename your_file "%sysfunc(pathname(work))\your_file.txt";

 

Would get removed automatically at end of session then.

 

However, I am sure as part of the ongoing lifecycle management of those macros you would have a plan in place to review the code, identify new technologies/procedures etc. in subsequent releases of SAS and so would need to update these ongoing anyways, if thats the case then perhpaps new technology would remove the need for the temporary files?  For instance, the graphs produced, could be created as template files which are stored, then you just put whatever data you want through those, no need to create text files with the code.

Contributor
Posts: 24

Re: Macro to create a tempory file [Windows]

Just to be clearer:  The macro does use filename ... temp ... in

 

   %if %sysevalf(&sysver  > 6.10) %then %do;
		filename &fileref temp &options
			%if %length(&ls)>0 %then lrecl=&ls;
			;		
		%end;

A typical use for this is in my table macro, http://www.datavis.ca/sasmac/table.html where I convert numeric variables to their formatted character strings by printing them to a temporary file and then reading the result back in.  (Maybe there is now

an easier way to do this??).  The code for this is:

 

%if %length(&char)>0 %then %do;
   /*
    * Force the VAR= variables to character.  To do this cleanly, we
    * resort to printing the &out dataset, then reading it back as
    * character. 
    * In SAS 9.3, this only works if ODS LISTING is turned on. 
    */
   %tempfile(table,&ls);
   %if %sysevalf(&sysver >9.2) %then %do;
   	ods listing;
   %end;
   proc printto new print=table;
   options nodate nocenter nonumber ls=&ls ps=10000;
   proc print data=&out;
      id &var;
      var count;
      run;
   %if &syserr > 4 %then %let abort=1; %if &abort %then %goto DONE;
   proc printto print=print;


   %let tvar = %join(&var, $) $;
   %*put tvar=&tvar;

   %if %verify(&char,  %str(0123456789))=0
      %then %let clen=&char;
      %else %let clen=16;
   data &out;
      infile table length=len;
      length string $&ls &var $&clen;
      retain skipping 1;
      drop string skipping;
      input @1 string $varying. len @;
      if skipping=0 & string ^= ' ' then do;
         input @1 &tvar count;
         output;
         end;
      else input;
      if index(string,'COUNT')>0 then skipping=0;
   run;
   *proc contents data=&out;

%tempdel(table);
 %if %sysevalf(&sysver >9.2) %then %do;
 	ods listing close;
 %end;

 

 

Ask a Question
Discussion stats
  • 9 replies
  • 487 views
  • 0 likes
  • 6 in conversation