Jedi SAS Tricks: The %PATHNAME to Enlightenment

6

I often create temporary ODS output files - and getting rid of those files after I'm done is an extra chore I don't relish. For example, if I want to generate a PDF-only report and email it from SAS (see "Jedi SAS Tricks: Email from the Front – Part 2") there's no need to leave a copy of the PDF file cluttering up my hard drive after it's been sent. Or perhaps you generated a report to some other ODS destination, and closed the default HTML destination to avoid unnecessary output.

In SAS versions before the SAS9.4 M5 maintenance release, re-opening the default HTML destination directs all of the temporary HTML files created for reports to the SAS default directory. These "temporary" files will persist on the hard drive unless cleaned up. I need an easy way of placing my files in the path where the SAS WORK library is located. Files written there are automatically deleted when the SAS session terminates. I need a %PATHNAME macro function to enlighten my code! The DATA step PATHNAME function and a little macro magic should make this about as easy as winning a shootout with Greedo...

Building the %PATHNAME macro function

The PATHNAME function accepts a LIBREF or FILEREF as its first argument. If necessary for disambiguation, a second argument designates the name as a FILREF or LIBREF. Our macro will use the %qsysfunc() macro function to execute PATHNAME. The entire macro code is included in the ZIP file for this post. As the majority of the macro program text consists of self-documentation and parameter validation, we'll show just the working parts here:

%macro pathname(ref,mod);
   %if %superq(mod)= %then %let path=%qsysfunc(pathname(%superq(ref)));
   %else %let path=%qsysfunc(pathname(%superq(ref),%superq(mod)));
   %superq(path)
%mend;

If I save the pathname.sas program in my SAS session's autocall path, I can use the new macro "function" in-line with my SAS code to provide the path to the WORK library whenever I need it.

Using the %PATHNAME macro function

Here is an example of how to use our new %PATHNAME function:

ods _all_ close;
ods PDF file="%pathname(work)\myfile.pdf";
proc FedSQL;
title "This is a test";
select * 
   from sasuser.acities
   limit 10
;
quit;
ods pdf close;
ods html path="%pathname(work)";

You can use this technique to turn just about any SAS DATA step function into a macro function, making your everyday programming quicker and easier. As usual, you can download the %pathname macro and testing code from this link.

Until next time, may the SAS be with you!
Mark

Tags
Share

About Author

SAS Jedi

Principal Technical Training Consultant

Mark Jordan (a.k.a. SAS Jedi) grew up in northeast Brazil as the son of Baptist missionaries. After 20 years as a US Navy submariner pursuing his passion for programming as a hobby, in 1994 he retired, turned his hobby into a dream job, and has been a SAS programmer ever since. Mark writes and teaches a broad spectrum of SAS programming classes, and his book, "Mastering the SAS® DS2 Procedure: Advanced Data Wrangling Techniques" is in its second edition. When he isn’t writing, teaching, or posting “Jedi SAS Tricks”, Mark enjoys playing with his grand and great-grandchildren, hanging out at the beach, and reading science fiction novels. His secret obsession is flying toys – kites, rockets, drones – and though he usually tries to convince Lori that they are for the grandkids, she isn't buying it. Mark lives in historic Williamsburg, VA with his wife, Lori, and Stella, their cat. To connect with Mark, check out his SAS Press Author page, follow him on Twitter @SASJedi or connect on Facebook or LinkedIn.

6 Comments

    • SAS Jedi

      The %PATHNAME macro will return the full concatenated path, just as the PATHNAME function in BASE SAS would do. And, of course, you wouldn't want to use a concatenated library path in this particular application - the code produced wouldn't make sense. In that case, the calling process might search the text returned for the presence of a parenthesis '(' to detect a concatenated library and, if detected, take appropriate action.

  1. Great use of quoting functions! Of course, like any utility macro, there are many ways it can be enhanced.. One might be to test that the library is indeed a BASE engine (V9), as other engines (such as ODBC) are not directory based. A macro for this is referenced below, which might be used as follows:

    %macro pathname(ref,mod);
    %local engine;
    %let engine=%mf_getEngine(%superq(ref));
    %if &engine=V9 %then %do;
    %if %superq(mod)= %then %let path=%qsysfunc(pathname(%superq(ref)));
    %else %let path=%qsysfunc(pathname(%superq(ref),%superq(mod)));
    %superq(path)
    %end;
    %else %put Library has engine type &engine;
    %mend;

    source: https://github.com/macropeople/macrocore/blob/master/base/mf_getengine.sas

  2. Chris Hemedinger
    Chris Hemedinger on

    Extra tip: use the forward slash when building your file paths. SAS will make that work on Windows (where backslash is the usual delimiter) and on UNIX systems, so your program remains portable across different operating systems. Ex:

    ods PDF file="%pathname(work)/myfile.pdf";

    • SAS Jedi

      An EXCELLENT point, Chris! Windows is agnostic about which slash you use ("/" or "\"), as long as you are consistent. UNIX and LINUX only accept the forward slash (/). I'm a big fan of making my SAS programs as platform-independent as possible, and this is a good habit to get into. Unfortunately, I developed the habit of using "\"on Windows long before I learned to code in SAS, and breaking a bad habit is so much harder than learning it right the first time ;-)

Back to Top