BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Kc2
Quartz | Level 8 Kc2
Quartz | Level 8

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.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
SASKiwi
PROC Star

@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.

View solution in original post

7 REPLIES 7
jimbarbour
Meteorite | Level 14

@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;
SASKiwi
PROC Star

@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.

jimbarbour
Meteorite | Level 14

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

SASKiwi
PROC Star

Thanks @jimbarbour  - I learnt from finding this answer too!

Kc2
Quartz | Level 8 Kc2
Quartz | Level 8

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. 

 

 

jimbarbour
Meteorite | Level 14

@Kc2,

 

I have a macro function that will return a three character abbreviation for the type of session I'm running.

  • CLI = Command Line Interface (command prompt)
  • SEG = SAS Enterprise Guide
  • DMS = Display Manager Session ("PC SAS")
  • SCS = SAS Connect Session (SAS via RSubmit)

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

 

Kc2
Quartz | Level 8 Kc2
Quartz | Level 8

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

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 7 replies
  • 2021 views
  • 3 likes
  • 3 in conversation