Manage the current directory within your SAS program

11

The concept of "current working directory" is important within any SAS program that reads or creates external files. In SAS, when you reference a file location with a relative path (for example, "./projects/mydata.pdf"), that file reference resolves to an absolute path by way of the working directory. You can control the initial working directory by modifying the shell scripts that launch the SAS process, or by specifying the SASINITIALFOLDER option in the SAS command or config file. But if you're using SAS Enterprise Guide or SAS Studio, it's likely that you don't have the ability to control how the SAS process starts. But don't worry -- there is still a way to find and change the working directory within your SAS programs.

Find the current directory in SAS

Tom (one of our SAS Communities Super Users) shared a simple SAS macro that allows you to learn the current working directory. The macro uses a trick to assign a SAS fileref to the current path ('.'), grab the full path of that fileref by using the PATHNAME function, and then clear the fileref.

Read the article for the full source (it's only about 7 lines). Here's how you would use it:

56         %put Current path is %curdir;
Current path is C:\WINDOWS\system32

As you might infer from my example here, I'm running this on a managed Windows environment. Most users cannot write to the "C:\WINDOWS\system32" path (and would not want to), so any relative file paths in my SAS code would cause errors. Maybe you've seen something like this:

25         ods html file="./test.html";
NOTE: Writing HTML Body file: ./test.html
ERROR: Insufficient authorization to access C:\WINDOWS\system32\test.html.
ERROR: No body file. HTML output will not be created.

If I want to use a relative path, I need to change the current working directory. Fortunately, there's a simple way to do that.

Change the current directory in SAS

Use the DLGCDIR function to change the working directory for your current SAS session. The DLGCDIR function was added in SAS 9.4 Maintenance 4 (released in 2016). Now I can change the working directory early in my program, and all relative file paths will resolve accordingly.

/* working path for my projects */
%let rc = %sysfunc(dlgcdir('u:/projects'));
 
ods html file="./test.html";
proc print data=sashelp.class; run;
ods html close;

I can use my account-specific environment variables to make these paths work for all users. For example, on Windows I can reference the USERPROFILE environment variable. (On Unix, I can use the HOME environment variable instead.)

/* working path for my projects */
%let user = %sysget(USERPROFILE);
%let rc = %sysfunc(dlgcdir("&user./Documents"));
 
/* create an output data folder if needed */
options dlcreatedir;
libname outdata "./data";
 
ods html file="./test.html";
data outdata.class;
 set sashelp.class;
run;
proc print data=outdata.class; run;
ods html close;

Here's my log output. Notice how the HTML file and the output data folder are both created at locations relative to my home directory.

25         /* working path for my projects */
26         %let user = %sysget(USERPROFILE);
27         %let rc = %sysfunc(dlgcdir("&user./Documents"));
NOTE: The current working directory is now "C:\Users\sascrh\Documents".
28         
29         options dlcreatedir;
30         libname outdata "./data";
NOTE: Library OUTDATA was created.
NOTE: Libref OUTDATA was successfully assigned as follows: 
      Engine:        V9 
      Physical Name: C:\Users\sascrh\Documents\data
31         
32         ods html file="./test.html";
NOTE: Writing HTML Body file: ./test.html
33         data outdata.class;
34          set sashelp.class;
35         run;

If using SAS Enterprise Guide, you can add DLGCDIR function steps to the startup statements that run when you connect to SAS, ensuring that your working directory starts in a valid location for SAS output. You can specify those statements in Tools->Options->SAS Programs, "Submit SAS code when server is connected." A SAS administrator can also add code to the AUTOEXEC file that runs when the SAS session begins, thus helping to manage this for larger groups of SAS users.

See also

Share

About Author

Chris Hemedinger

Director, SAS User Engagement

+Chris Hemedinger is the Director of SAS User Engagement, which includes our SAS Communities and SAS User Groups. Since 1993, Chris has worked for SAS as an author, a software developer, an R&D manager and a consultant. Inexplicably, Chris is still coasting on the limited fame he earned as an author of SAS For Dummies

11 Comments

    • Chris Hemedinger
      Chris Hemedinger on

      Good question! I think the answer is Yes, as long as the "change directory" operation is run in each of the nodes when you start. That means as part of an AUTOEXEC or the standard snippet of code that runs when you connect to a server. It's worth testing to make sure it does what you need. Also, as you know, since each grid node has its own file system, you would target a shared network file location for any output (data sets, other files) that you want to persist after the work is done.

  1. When you ran this, was test.html created within C:\Users\sascrh\Documents? When I ran it, test.html went into my SAS temporary working directory, as it normally does -- C:\Users\myname\AppData\Local\Temp\SAS Temporary Files\_TD5792_L56LT5CG426HQKP_

    • Chris Hemedinger
      Chris Hemedinger on

      Yes, the directory changes and output is directed to my documents folder. Check your USERPROFILE value.

      %let user = %sysget(USERPROFILE);
      %put &=user;
      

      And make sure you use the dot-slash notation in your ODS path:

      ods html file="./test.html";
      

      And if you're using EG and already have HTML destination turned on, remember that you'll get TWO HTML outputs -- one is the EG default, and one is the named file in your ODS statement. You'll have to turn off the HTML destination in your EG options or use ODS CLOSE _ALL_ if you want just the one output.

  2. Handy to read about dlgcdir — thanks!

    Note as you're calling from the macro environment, you don't need (and shouldn't have?) the quotes. e.g. this works fine:

    %let rc=%sysfunc(dlgcdir(C:\Program Files));

  3. Handily it appears this function also supports Windows environment variables, so instead of an extra sysget() line, you can submit:

    %let rc=%sysfunc(dlgcdir(%nrstr(%USERPROFILE%\Documents)));

  4. Francisco Rodriguez on

    Buenos días,
    Yo ejecuto procesos en SAS EG, para luego de crear un query, llevarlo a SAS VA para crear paneles de visualización. pero para esto necesito cambiar del perfil de SAS EG a SAS VA para subir las tablas al SAS VA y montar el panel.

    Mi pregunta es: En SAS EG, existe un comando que atraves de un program yo pueda hacer que mi segundo profile SAS VA (SAS Visaul Analytcs) se active?.

    • Chris Hemedinger
      Chris Hemedinger on

      Francisco,

      The best approach would be to have a single metadata environment that provided access to your SAS workspace AND to the SAS VA environment. There is not a way to trigger a profile "switch" during an open EG session (aside from the point-and-click method).

      However, you can set a desktop shortcut to launch EG with a specific profile selected. See this blog post for details.

  5. Previously, I easily controlled the output directory within the code. After an upgrade, it looks like whatever folder is set in options is where the output goes. Is there a way to have the output directory controlled instead by code, such as %let outdata = directory? This used to work just fine... Not sure what changed. Thanks

    • Chris Hemedinger
      Chris Hemedinger on

      CJ, when you refer to "output" are you talking about logs and listing output? Or data? The default output for these have typically been set in startup options or using special PROC PRINTTO steps. If you use something like "%let outdata=" to control output before, that tells me that there is something in your code that should pick up on that value. Maybe that's no longer triggered with your update in place. We would need to see example code/log to determine what's going on. It might be a good question for communities.sas.com.

  6. Hello All,

    I work in EPG for all my Base SAS work. Forever, I have been trying to find a nice way for SAS to automatically know where the EPG project is saved. After hunting, and searching, I finally tried my own solution:

    %LET b = %SYSFUNC(SUBSTR(%SYSFUNC(dequote(&_CLIENTPROJECTPATH)),1,%EVAL((%SYSFUNC(FIND((%SYSFUNC(deQUOTE(&_CLIENTPROJECTPATH))),%SYSFUNC(deQUOTE(&_CLIENTPROJECTNAME)))))-2)));

    %PUT &b;

    This was a mix of - Art Carpenter + Chris Hemedinger + GRIT.

Back to Top