Hello,
I have issue in this code, not sure why it is not working:
All that I am trying to do is:
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.)";
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.
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
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.
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
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=¶meter; 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=¶meter;
%mend;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.