Morning all,
I have a file that contains a load of %includes to different programs in different locations
In these programs there are fuctions that are supposed to get the path where that particular program is saved. However it only resoves the path where the %include program is saved.
Does anyone have a solution for this?
For example:
This is program A saved here "C:\"
%include 'W:\B.sas';
This is program B
%let pig=%sysget(SAS_EXECFILEPATH);
%put &pig.;
When I run program A I get:
C:\A.SAS instead of what I want which is W:\B.SAS
Hope this makes sence
Pigface
Not really. How do you assign SAS_EXECFILEPATH? Are you sure that is has the value of W:\B.SAS?
Running the job with options source2 mlogic; would might help you to debug.
When I run program B on its own not through a %include it returns the path where it is saved
When I run program A it calls program B via a %incude but brings back the path where progam A is saved when I want it to bring the path back where progam B is saved
Hi,
I guess(not tested) your program B macros are included in Auto call libraries.
You can also set that using options or directly in auto call library.
options set=Test "w:\B.SAS";
%let TEST=%sysfunc(sysget(TEST));
%PUT &TEST;
Thanks,
Shiva
Thanks. No idea what auto call libaries are. It is just a nomal SAS progam saved in another folder on our drive
I think I understand your workaround but what I really wanted is an option that automatically fixes this issue because I have many programs that I am refering to with the %include and hence want to ensure that any function such as %sysget refers to the path of that particualr program and not the master %include program
You can get the name of the running program by using filerefs inside included programs.
Here, the physical path is specified in a filename statement referred as fileref t and its path resolved using PATHNAME function in the included program(s).
This will work when filename t is assigned in another program and a.sas and b.sas are included.
If one executes a.sas alone filename t wouldn't have been assigned or coıuld have been assigned to another file in an interactive session.
/* Master program */
filename t "d:\temp\zip\a.sas";
%include t;
filename t "d:\temp\zip\b.sas";
%include t;
/* a.sas */
%let path = %SYSFUNC(PATHNAME(t,F));
%put path = &path;
/* b.sas */
%let path = %SYSFUNC(PATHNAME(t,F));
%put path = &path;
Thanks Alpay but I need it to work both ways and this will not work if I run the programs independently outside the master program
Mike
An alternative could be using a generic macro to check whether fileref t exists first in current session.
If so, get the PATHNAME associated with this fileref.
Otherwise, use SYSIN option's value (in batch mode) or SAS_EXECFILEPATH macro variable's value (in interactive mode).
/* Save this as getpath.sas and compile in your session */
%macro getpath;
%if %SYSFUNC(FEXIST(t)) %then %let path = %SYSFUNC(PATHNAME(t,F));
%else %let Path = %SYSFUNC(IFC( "%SYSFUNC(GETOPTION(SYSIN))" ne "",
%SYSFUNC(GETOPTION(SYSIN)),
%SYSGET(SAS_EXECFILEPATH)));
%put Path = &Path;
%mend;
/* Master program */
filename t "d:\temp\zip\a.sas";
%include t;
filename t "d:\temp\zip\b.sas";
%include t;
/* a.sas */
%getpath;
%put 123;
/* b.sas */
%getPath;
%put ABC;
Call this macro as the first line in each INCLUDED file. When you use the quoted filename syntax in your
%INC 'program.sas'; SAS creates a FILEREF using the #LNnnnnnn naming convention. It SHOULD be the fileref with the largest value each time. Then you can query dictionary.extfiles for the LAST one created. The example creates a macro variable but I suppose you could SET SAS_EXECFILEPATH if you wanted to.
%macro whereAmI(arg);
%global includePath;
%let includePath=;
proc sql outobs=1 nowarn;
select xpath into :includePath
from dictionary.extfiles
where fileref eqt '#LN'
order by fileref descending;
quit;
run;
%put INCLUDEPATH=&includepath;
%mend whereAmI;
An alternative that would be better would be to write a macro to "replace" %INC. %XINC perhaps. The macro would find the full path of the quoted file name and create a macro variable or SET an enviornment variable and then %INC the file. The INCed could use the info as needed.
Thanks data_null_
I think that is a good workaround and seems to work if a run the program both in and out of the include
Would be interested to see if anyone else as any other ways
Pigface
Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.