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.