BookmarkSubscribeRSS Feed
pigface
Calcite | Level 5

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


9 REPLIES 9
LinusH
Tourmaline | Level 20

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.

Data never sleeps
pigface
Calcite | Level 5

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

shivas
Pyrite | Level 9

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

pigface
Calcite | Level 5

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

Alpay
Fluorite | Level 6

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;

pigface
Calcite | Level 5

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

Alpay
Fluorite | Level 6

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;

data_null__
Jade | Level 19

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.

pigface
Calcite | Level 5

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

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 2050 views
  • 3 likes
  • 5 in conversation