BookmarkSubscribeRSS Feed
david27
Quartz | Level 8

Hello,

 

I have issue in this code, not sure why it is not working:

All that I am trying to do is:

  • From a bunch of directories in a folder, I am just selecting 1 of them.
  • That 1 value needs to be used in the libname statement.

If I make that as %global then it would work. But don't think that is a good practice.

Can you please help?

 

%macro returnfoldername(key_985632=);
	filename ps_list pipe "ls -l /sasdata/path/to/folder";

	data _null_;
		infile ps_list;
		length process $ 200;
		input process $ char200.;

		if index(process,"&key_985632.")>0;
		call symput('returnfoldername_985632',substr(process,index(process,"&key_985632."),length(process)-index(process,"&key_985632.")+1
)
); run; &returnfoldername_985632.; %mend returnfoldername; options symbolgen mprint mlogic; %let camp_key=123456; libname follow1 "/sasdata/path/to/folder/%returnfoldername(key_985632=&camp_key.)";
6 REPLIES 6
PaigeMiller
Diamond | Level 26

Whenever you have errors in the log, show us the log — all of it for this macro, every single character for this macro, with nothing chopped out.

 

Copy the log as text and paste it into the window that appears when you click on the </> icon.

PaigeMiller_0-1663012019648.png

--
Paige Miller
david27
Quartz | Level 8

 

This is the code:

%macro returnfoldername(key_985632=);

filename ps_list pipe "ls -l /sasdata/MACME/PRD/CAMPAIGNS";
data _null_ ;
   infile ps_list ;
   length process $ 200;
   input process $ char200.;

if index(process,"&key_985632.")>0 ;
call symput('retval',substr(process,index(process,"&key_985632."),length(process)-index(process,"&key_985632.")+1));
run;
&retval.;
%mend returnfoldername;

options symbolgen mprint mlogic;
%let pr_co_fd_camp1=12772;
libname follow1		"/sasdata/MACME/PRD/CAMPAIGNS/%returnfoldername(key_985632=12772)"; 

 

 

This is the Log:

1 The SAS System                                                                                                                                                                                                                08:19 Tuesday, November 29, 2022

1          ;*';*";*/;quit;run;
2          OPTIONS PAGENO=MIN;
3          %LET _CLIENTTASKLABEL='Program';
4          %LET _CLIENTPROCESSFLOWNAME='Standalone Not In Project';
5          %LET _CLIENTPROJECTPATH='';
6          %LET _CLIENTPROJECTPATHHOST='';
7          %LET _CLIENTPROJECTNAME='';
8          %LET _SASPROGRAMFILE='';
9          %LET _SASPROGRAMFILEHOST='';
10         
11         ODS _ALL_ CLOSE;
12         OPTIONS DEV=SVG;
13         GOPTIONS XPIXELS=0 YPIXELS=0;
14         %macro HTML5AccessibleGraphSupported;
15             %if %_SAS_VERCOMP_FV(9,4,4, 0,0,0) >= 0 %then ACCESSIBLE_GRAPH;
16         %mend;
17         FILENAME EGHTML TEMP;
18         ODS HTML5(ID=EGHTML) FILE=EGHTML
19             OPTIONS(BITMAP_MODE='INLINE')
20             %HTML5AccessibleGraphSupported
MLOGIC(HTML5ACCESSIBLEGRAPHSUPPORTED):  Beginning execution.
MLOGIC(_SAS_VERCOMP_FV):  Beginning execution.
MLOGIC(_SAS_VERCOMP_FV):  Parameter FMAJOR has value 9
MLOGIC(_SAS_VERCOMP_FV):  Parameter FMINOR has value 4
MLOGIC(_SAS_VERCOMP_FV):  Parameter FMAINT has value 4
MLOGIC(_SAS_VERCOMP_FV):  Parameter VMAJOR has value 0
MLOGIC(_SAS_VERCOMP_FV):  Parameter VMINOR has value 0
MLOGIC(_SAS_VERCOMP_FV):  Parameter VMAINT has value 0
MLOGIC(_SAS_VERCOMP_FV):  %LOCAL  MAJOR
MLOGIC(_SAS_VERCOMP_FV):  %LOCAL  MINOR
MLOGIC(_SAS_VERCOMP_FV):  %LOCAL  MAINT
MLOGIC(_SAS_VERCOMP_FV):  %LOCAL  CURMAJ
MLOGIC(_SAS_VERCOMP_FV):  %LOCAL  CURMIN
MLOGIC(_SAS_VERCOMP_FV):  %LOCAL  CURMNT
MLOGIC(_SAS_VERCOMP_FV):  %LET (variable name is CURMAJ)
SYMBOLGEN:  Macro variable SYSVLONG resolves to 9.04.01M6P110718
SYMBOLGEN:  Macro variable CURMAJ resolves to 9
MLOGIC(_SAS_VERCOMP_FV):  %IF condition %eval(&CurMaj EQ V) is FALSE
MLOGIC(_SAS_VERCOMP_FV):  %LET (variable name is MAJOR)
SYMBOLGEN:  Macro variable FMAJOR resolves to 9
MLOGIC(_SAS_VERCOMP_FV):  %LET (variable name is MINOR)
SYMBOLGEN:  Macro variable FMINOR resolves to 4
MLOGIC(_SAS_VERCOMP_FV):  %LET (variable name is MAINT)
SYMBOLGEN:  Macro variable FMAINT resolves to 4
MLOGIC(_SAS_VERCOMP_FV):  %LET (variable name is CURMIN)
SYMBOLGEN:  Macro variable SYSVLONG resolves to 9.04.01M6P110718
MLOGIC(_SAS_VERCOMP_FV):  %LET (variable name is CURMNT)
SYMBOLGEN:  Macro variable SYSVLONG resolves to 9.04.01M6P110718
SYMBOLGEN:  Macro variable MAJOR resolves to 9
SYMBOLGEN:  Macro variable CURMAJ resolves to 9
MLOGIC(_SAS_VERCOMP_FV):  %IF condition %eval(&major NE &CurMaj) is FALSE
SYMBOLGEN:  Macro variable MINOR resolves to 4
SYMBOLGEN:  Macro variable CURMIN resolves to 04
MLOGIC(_SAS_VERCOMP_FV):  %IF condition %eval(&minor NE &CurMin) is FALSE
SYMBOLGEN:  Macro variable MAINT resolves to 4
MLOGIC(_SAS_VERCOMP_FV):  %IF condition "&maint" = "" is FALSE
SYMBOLGEN:  Macro variable CURMNT resolves to 6
SYMBOLGEN:  Macro variable MAINT resolves to 4
MLOGIC(_SAS_VERCOMP_FV):  Ending execution.
MLOGIC(HTML5ACCESSIBLEGRAPHSUPPORTED):  %IF condition %_SAS_VERCOMP_FV(9,4,4, 0,0,0) >= 0 is TRUE
MPRINT(HTML5ACCESSIBLEGRAPHSUPPORTED):   ACCESSIBLE_GRAPH
MLOGIC(HTML5ACCESSIBLEGRAPHSUPPORTED):  Ending execution.
21             ENCODING='utf-8'
22             STYLE=HTMLBlue
23             NOGTITLE
24             NOGFOOTNOTE
25             GPATH=&sasworklocation
SYMBOLGEN:  Macro variable SASWORKLOCATION resolves to "/saswork/SAS_workF70B00008B0E_amz-psaslx01/SAS_workD77F00008B0E_amz-psaslx01/"
2 The SAS System                                                                                                                                                                                                                08:19 Tuesday, November 29, 2022

26         ;
NOTE: Writing HTML5(EGHTML) Body file: EGHTML
27         
28         %macro returnfoldername(key_985632=);
29         
30         filename ps_list pipe "ls -l /sasdata/MACME/PRD/CAMPAIGNS";
31         data _null_ ;
32            infile ps_list ;
33            length process $ 200;
34            input process $ char200.;
35         
36         if index(process,"&key_985632.")>0 ;
37         call symput('retval',substr(process,index(process,"&key_985632."),length(process)-index(process,"&key_985632.")+1));
38         run;
39         &retval.;
40         %mend returnfoldername;
41         
42         options symbolgen mprint mlogic;
43         %let pr_co_fd_camp1=12772;
44         libname follow1		"/sasdata/MACME/PRD/CAMPAIGNS/%returnfoldername(key_985632=12772)";
MLOGIC(RETURNFOLDERNAME):  Beginning execution.
MLOGIC(RETURNFOLDERNAME):  Parameter KEY_985632 has value 12772
SYMBOLGEN:  Macro variable KEY_985632 resolves to 12772
SYMBOLGEN:  Macro variable KEY_985632 resolves to 12772

             ______________________________
             49

             _____________________________________________________
             49
NOTE: Line generated by the macro variable "KEY_985632".
44         "; data _null_ ;    infile ps_list ;    length process $ 200;    input process $ char200.;  if index(process,"12772
           ______________________________________________________________________________________________________________
           49
NOTE: Line generated by the macro variable "KEY_985632".
44         ")>0 ; call symput('retval',substr(process,index(process,"12772
           __________________________________________________________
           49
SYMBOLGEN:  Macro variable KEY_985632 resolves to 12772
NOTE: Line generated by the macro variable "KEY_985632".
44         "),length(process)-index(process,"12772
           __________________________________
           49
WARNING: Apparent symbolic reference RETVAL not resolved.
NOTE 137-205: Line generated by the invoked macro "RETURNFOLDERNAME".
44         filename ps_list pipe "ls -l /sasdata/MACME/PRD/CAMPAIGNS"; data _null_ ;    infile ps_list ;    length process $ 200;    input process $ char200.;  if index(process,"&key_985632.")>0 ; call
                                  __
                                  22
44       ! symput('retval',substr(process,index(process,"&key_985632.")
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release.  Inserting white space between a quoted string and the succeeding identifier is recommended.

ERROR 22-7: Invalid option name LS.

MPRINT(RETURNFOLDERNAME):   follow1 "/sasdata/MACME/PRD/CAMPAIGNS/filename ps_list pipe "ls
MLOGIC(RETURNFOLDERNAME):  Ending execution.
MPRINT(RETURNFOLDERNAME):   -l /sasdata/MACME/PRD/CAMPAIGNS"; data _null_ ;    infile ps_list ;    length process $ 200;    input process $ char200.;  if index(process,"12772")>0 ; call 
symput('retval',substr(process,index(process,"12772"),length(process)-index(process,"12772")+1)); run; &retval.;"
ERROR: Libref FOLLOW1 is not assigned.
ERROR: Error in the LIBNAME statement.
45         
46         %LET _CLIENTTASKLABEL=;
47         %LET _CLIENTPROCESSFLOWNAME=;
48         %LET _CLIENTPROJECTPATH=;
49         %LET _CLIENTPROJECTPATHHOST=;
50         %LET _CLIENTPROJECTNAME=;
51         %LET _SASPROGRAMFILE=;
52         %LET _SASPROGRAMFILEHOST=;
53         
3 The SAS System                                                                                                                                                                                                                08:19 Tuesday, November 29, 2022

54         ;*';*";*/;quit;run;
55         ODS _ALL_ CLOSE;
56         
57         
58         QUIT; RUN;
59         

 

 

PaigeMiller
Diamond | Level 26

I think @Quentin has pointed out the flaw in what you are doing. Your macro %return_foldername uses DATA step code, and DATA step code cannot appear in a LIBNAME statement. That's what happens when you call a macro, the macro call is replaced with the code generated by the macro.

 

But this ought to work:

 

%macro returnfoldername();

filename ps_list pipe "ls -l /sasdata/MACME/PRD/CAMPAIGNS";
data _null_ ;
   infile ps_list ;
   length process $ 200;
   input process $ char200.;

if index(process,"&key_985632.")>0 ;
call symput('retval',substr(process,index(process,"&key_985632."),length(process)-index(process,"&key_985632.")+1));
run;

libname follow1 "/sasdata/MACME/PRD/CAMPAIGNS/&retval"; 

%mend returnfoldername;

%returnfoldername(key_985632=12772)

 

Naturally, I can't test this, but you can!

 

Also, in the case where if index(process,"&key_985632.")>0 ; fails, you will not assign a value to &retval and so your libname statement will likely be incorrect, you might want to build in some error checking for this case.

--
Paige Miller
andreas_lds
Jade | Level 19
  • If you want to use a variable created in a macro outside of that macro, it has to be global. The only way to keep the variable local is moving the libname statement into the macro.
  • You can't use data or proc steps in a macro that is used as function. Enable option mprint to see what happens, actually.
Quentin
Super User

Hi,

 

I'm confused about the big picture.  Are you saying "I know there is a folder in a certain directory and I know the folder's name starts with 123456, but I don't know the full name of the folder so need to find it"?

 

You're right that generally it is good to avoid generating global macro variables.

 

As Andreas mentioned, a general rule of function-style macros is that they can't contain SAS statements/steps.  They can only contain macro language statements.  This is because when a macro executes, it executes the macro language statements, but it only generates the SAS statements.  So as written, SAS starts to compile your libname statement, then in the middle of doing that suddenly it hits a filename statement and everything breaks.

 

You have a few options.

 

One is to abandon the function-style macro approach.  You could move your LIBNAME statement into the macro definition.  This changes your macro purpose from ReturnFolderName to MakeLibref.  That's probably the quickest/easiest change.

 

If you want to keep this as a function-style macro you could rewrite the macro to use pure macro statements.  It's possible to do this sort of directory crawling with %sysfunc(open()) etc,  but I find it annoying.

 

Another option for keeping this as a function-style macro is to change the design to use DOSUBL, called by %sysfunc, to execute the SAS code generated by the macro. This is a bit more advanced, but DOSUBL is a great tool to consider.  For more on DOSUBL, see this paper, which I think of as new but is apparently almost 10 years old.  https://www.lexjansen.com/nesug/nesug13/139_Final_Paper.pdf

The Boston Area SAS Users Group is hosting free webinars!
Next up: Joe Madden & Joseph Henry present Putting Power into the Hands of the Programmer with SAS Viya Workbench on Wednesday Nov 6.
Register now at https://www.basug.org/events.
Tom
Super User Tom
Super User

If you want to return a macro variable from a macro then just make sure the macro variable exists before calling the macro.

2459  %macro mymacro(parameter);
2460  %let mymvar=&parameter;
2461  %mend;
2462  %let mymvar=BEFORE MACRO CALL;
2463  %put &=mymvar;
MYMVAR=BEFORE MACRO CALL
2464  %mymacro(after macro call);
2465  %put &=mymvar;
MYMVAR=after macro call

You can even use the %SYMEXIST() function to check if the macro variable exists or not.

%macro mymacro(parameter);
  %if not %symexist(mymvar) %then %global mymvar;
  %let mymvar=&parameter;
%mend;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 961 views
  • 0 likes
  • 5 in conversation