Hello,
At the start of my program, I am using the options sasautos = ('C:\CommonCode\Macros' sasautos);
and then calling in the macro %gpath;
options sasautos = ('C:\CommonCode\Macros' sasautos);
%gpath;
%include "&path\setup.sas";
Once I have the path from %gpath I use the macro variable in an %include to run setup.sas .
%include "&path\setup.sas";
In SAS interactive windows mode everything runs smoothly. In batch the &path. value is not getting captured outside the macro.
I get an error %include file \setup.sas not found.
Since I am declaring the path variable as global, I don't understand why it is not working in batch.
The %gpath macro runs fine but it writes the values of the variables twice to the log window.
PATH= C:\Template\Study\Dev
PGM= test
PATH= C:\Template\Study\Dev
PGM= test
%macro gpath;
%global Path Pgm;
%let PATH= %substr(%sysget(SAS_EXECFILEPATH),1,%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))-1);
%let PGM = %substr(%sysget(SAS_EXECFILENAME),1,%length(%sysget(SAS_EXECFILENAME))-4);
%put PATH= &PATH;
%put PGM= &PGM;
%mend;
%gpath;
Can someone help me understand why the batch program is not reading the macro variable and why the in the log the put statement is written twice?
thanks
KC.
@Kc2 - The explanation for your issue is here: https://documentation.sas.com/?docsetId=mcrolref&docsetTarget=p1ns5wvyfxbca8n1l3konj0yj6nq.htm&docse...
The environment variables you are using in %SYSGET are only available when using the Enhanced Editor running on Windows. They aren't available in batch mode. An alternative approach for batch mode is provided in the link.
@Kc2,
Hmm. Sounds like a tricky one.
Can you add the following options statement and re-run both?
OPTIONS MAUTOLOCDISPLAY;
I'm wondering if maybe a different autocall hierarchy exists in one environment vs. the other. If so, you might be getting different versions of the gpath macro and therefore differing behaviors. We should eliminate this possibility before digging further.
Jim
P.S. It might be helpful for you to post the relevant sections of the SAS logs from both versions. Something funny is going on. You may be executing slightly different versions of your program or slightly different versions of the macro.
Perhaps you could also run this code for both environments and see if there are any differences:
PROC OPTIONS OPTION=AUTOEXEC;
RUN;
@Kc2 - The explanation for your issue is here: https://documentation.sas.com/?docsetId=mcrolref&docsetTarget=p1ns5wvyfxbca8n1l3konj0yj6nq.htm&docse...
The environment variables you are using in %SYSGET are only available when using the Enhanced Editor running on Windows. They aren't available in batch mode. An alternative approach for batch mode is provided in the link.
Oh, good call, @SASKiwi. I didn't even look at the contents of the macro itself.
Yes, certain things like macro variables differ environment to environment. For program name, EG as I recall has a macro variable, _CLIENTTASKLABEL. I think I usually use %SYSFUNC(GETOPTION(sysin) for batch submitted SAS programs.
The suggestions I originally made might be helpful for a macro problem, but that's not the issue here.
Jim
Thanks @jimbarbour - I learnt from finding this answer too!
This does not solve my problem
I need to automatically get the path of the program (one folder above the program) and the program name.
The %sysfunc(getoption(SysIn)) gives the full path of the program program:
log statement
29 options sasautos = ('C:\CommonCode\Macros' sasautos);
30
31 %gpath;
The current program is C:\Template\Study\Dev\test.sas
The current program is C:\Template\Study\Dev\test.sas
32
33 %include "&path\setup.sas";
WARNING: Physical file does not exist, C:\setup.sas.
ERROR: Cannot open %INCLUDE file \setup.sas.
In the interactive mode the macro variable &path. resolves to C:\Template\Study\Dev
When used in the %include statement %include "&path\setup.sas"; it reads C:\Template\Study\Dev\setup.sas and runs the Setup.sas program
In batch I need to find a way for the system extract from %sysfunc(getoption(SysIn)) the value of the program and the path separately
&pgm= test
&path= C:\Template\Study\Dev
so that when the %include statement is called the &path. will point to the right folder structure.
@Kc2,
I have a macro function that will return a three character abbreviation for the type of session I'm running.
I then use the type of session to determine which bit of code to execute.
In my Autoexec.sas, I have some macro variables defined which are needed by this macro:
%LET Nte1 = NOTE:;
%LET Nte2 = NOTE-;
%LET Warn1 = WARN:;
%LET Warn2 = WARN-;
%LET Err1 = ERROR:;
%LET Err2 = ERROR-;
%LET sQuote = %STR(%');
Here, below is the macro if it's helpful.
/*-------------------------------------------------------------------------------*/
/* Macro: Get_Process_Mode
/* Author: Jim Barbour (Jim.Barbour@gmail.com)
/* Date: 23 August 2019
/* Info: This is a macro function. This macro checks the automatic macro
/* variable SysProcessMode and returns a three character abbreviation
/* specifying the process mode as follows:
/* CLI = Command Line Interface, a MS DOS Command window or .bat file.
/* DMS = SAS Display Manager, a.k.a. "PC SAS" or "SAS for Windows".
/* SEG = SAS Enterprise Guide ("EG").
/* SCS = SAS Connect Session, code submitted via an RSUBMIT.
/*
/* Process mode indicates how a given SAS session was instanciated, i.e..
/* from the command line or via a .bat file (CLI), via Display Manager
/* (DMS), via SAS Enterprise Guide (SEG), or via an RSUBMIT (SCS).
/*-------------------------------------------------------------------------------*/
/* CHANGE LOG
/*-------------------------------------------------------------------------------*/
/* Name: Jim Barbour Date: 23 August 2019
/* Info: Original implementation.
/*-------------------------------------------------------------------------------*/
%MACRO Get_Process_Mode(Override=, Debug=NO);
%LOCAL L_Process_Mode;
%IF %QUPCASE(&Debug) = YES %THEN
%DO;
%PUT &Nte2;
%PUT &Nte1 **************************;
%PUT &Nte2 Starting Get_Process_Mode.;
%PUT &Nte2 &=SysProcessMode &=Override &=L_Process_Mode;
%END;
%IF %BQUOTE(&Override) ^= %BQUOTE() %THEN
%IF %EVAL(%QUPCASE(&Override) IN CLI, DMS, SEG, SCS) %THEN
%DO;
%LET L_Process_Mode = %QUPCASE(&Override);
%END;
%ELSE
%DO;
%PUT &Warn2;
%PUT &Warn2 +----------------------------------------------+;
%PUT &Warn1 | Invalid override of &Override in Get_Process_Mode. |;
%PUT &Warn2 +----------------------------------------------+;
%Abort_Pgm;
%*Set_RC(SYSCC, 4);
%END;
%ELSE
%IF %QUPCASE(&SysProcessMode) = %QUPCASE(SAS DMS Session) %THEN
%DO;
%LET L_Process_Mode = DMS;
%END;
%ELSE
%IF %QUPCASE(&SysProcessMode) = %QUPCASE(SAS Workspace Server) %THEN
%DO;
%LET L_Process_Mode = SEG;
%END;
%ELSE
%IF %QUPCASE(&SysProcessMode) = %QUPCASE(SAS Batch Mode) %THEN
%DO;
%LET L_Process_Mode = CLI;
%END;
%ELSE
%IF %QUPCASE(&SysProcessMode) = %QUPCASE(SAS Connect Session) %THEN
%DO;
%LET L_Process_Mode = SCS;
%END;
%ELSE
%DO;
%PUT &Warn2;
%PUT &Warn2 +-------------------------------------------------------------+;
%PUT &Warn1 | Unknown mode of &squote.&SysProcessMode.&squote in Get_Process_Mode. |;
%PUT &Warn2 +-------------------------------------------------------------+;
%END;
%IF %QUPCASE(&Debug) = YES %THEN
%DO;
%PUT &Nte2 Ending Get_Process_Mode.;
%PUT &Nte2 &=SysProcessMode &=Override &=L_Process_Mode;
%PUT &Nte2 **************************;
%END;
%IF &True %THEN
%DO;
&L_Process_Mode
%END;
%MEND Get_Process_Mode;
Then a macro like the below can be written to execute the appropriate code for a given session type:
%MACRO Get_Path(Debug=NO);
%GLOBAL lCmnt Pgm Path;
%IF %QUPCASE(&Debug) = YES %THEN
%DO;
%PUT &Nte1 Debug is on in macro &SysMacroName;
%LET lCmnt = ;
%END;
%ELSE
%DO;
%LET lCmnt = *;
%END;
%IF %Get_Process_Mode = DMS %THEN
%DO;
%LET Path = %QSUBSTR(%SYSGET(SAS_EXECFILEPATH),1,%LENGTH(%SYSGET(SAS_EXECFILEPATH))-%LENGTH(%SYSGET(SAS_EXECFILENAME))-1);
%LET Pgm = %QSUBSTR(%SYSGET(SAS_EXECFILENAME),1,%LENGTH(%SYSGET(SAS_EXECFILENAME))-4);
%END;
%ELSE
%IF %Get_Process_Mode = SEG %THEN
%DO;
%LET Path = %QSYSFUNC(COMPRESS(&_SASPROGRAMFILE,&sQuote));
%&lCmnt.PUT &Nte1 &=Path;
%IF %BQUOTE(&Path) = %BQUOTE() %THEN
%LET Path = Embedded_In_Project;
%ELSE
%LET Path = %QSUBSTR(&Path, 1, %EVAL(%QSYSFUNC(LENGTH(&Path)) - %QSYSFUNC(INDEX(%QSYSFUNC(REVERSE(&Path)),\))));
%&lCmnt.PUT &Nte1 &=Path;
%LET Pgm = %QSYSFUNC(STRIP(%QSYSFUNC(TRANWRD(%QSYSFUNC(COMPRESS(&_CLIENTTASKLABEL, &sQuote)),.sas,))));
%&lCmnt.PUT &Nte1 &=Pgm;
%END;
%ELSE
%IF %Get_Process_Mode = CLI %THEN
%DO;
%LET Path = %QSUBSTR(%QSYSFUNC(GETOPTION(sysin)), 1, %EVAL(%QSYSFUNC(LENGTH(%QSYSFUNC(GETOPTION(sysin)))) - %QSYSFUNC(INDEX(%QSYSFUNC(REVERSE(%QSYSFUNC(GETOPTION(sysin)))),\))));
%&lCmnt.PUT &Nte1 &=Path;
%LET Pgm = %QSUBSTR(%QSYSFUNC(GETOPTION(sysin)), 1, %LENGTH(%QSYSFUNC(GETOPTION(sysin))) - 4);
%&lCmnt.PUT &Nte1 &=Pgm;
%LET Pgm = %SCAN(&Pgm, %EVAL(%QSYSFUNC(COUNT(&Pgm, \)) + 1), \);
%&lCmnt.PUT &Nte1 &=Pgm;
%END;
%ELSE
%IF %Get_Process_Mode = SCS %THEN
%DO;
%LET Path = Unknown;
%LET Pgm = %QSYSFUNC(STRIP(%QSYSFUNC(TRANWRD(%QSYSFUNC(COMPRESS(&_CLIENTTASKLABEL, &squote)),.sas,))));
%END;
%ELSE
%DO;
%PUT &Warn2;
%PUT &Warn2 +----------------------------------------------------------+;
%PUT &Warn1 | Unknown mode of &squote.%Get_Process_Mode&squote encountered in macro Get_Path. |;
%PUT &Warn2 +----------------------------------------------------------+;
%END;
%MEND Get_Path;
Jim
thank you Jim,
I was able to solve my problem by using the suggestion of @SASKiwi. : %sysfunc(getoption(sysin)) with the %substr function.
I will play with your macro.
Thanks for sharing.
KC
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.