/******************* URBAN INSTITUTE MACRO LIBRARY *********************
: FmtSearch
Macro: Autocall macro to manage multiple SAS format libraries.
Description
28, "Keep Those Formats
Written by Pete Lund, presented at SUGI Rolling: A Macro to Manage the FMTSEARCH= Option."
<http://www2.sas.com/proceedings/sugi28/116-28.pdf>
: Open code
Use
: Pete Lund
Author
***********************************************************************/
FmtSearch(
%macro Action=M, /** Action to perform on catalog **/
A=, /** Action to perform on catalog (alt parameter) **/
Cat=, /** Name of format catalog **/
C=, /** Name of format catalog (alt parameter) **/
Status=Y,
Recurse=N
);
/*************************** USAGE NOTES *****************************
:
SAMPLE CALLFmtSearch( cat=General, action=E )
%
add the catalog General.Formats to the end of the format search/parameters
macro variablesCat (C): name of the format catalog
Action (A): What do you want to do with the catalog:
= put it at the beginning of the format search list,
B
even before WORK.FORMATS and LIBRARY.FORMATS= put it at the end of the format search list
E = remove it from the format search list
D = put it in the "middle" of the format search list. It
M
will go after WORK.FORMATS and LIBRARY.FORMATS and before-defined catalogs in the search list.
any user= simply lists the current format search list
L : The M does work, its just that when B has been previously
notes
used, WORK and LIBRARY have been explicitely set and a
later M will still go at the front. *********************************************************************/
/*************************** UPDATE NOTES ****************************
*********************************************************************/
***** ***** ***** MACRO SET UP ***** ***** *****;
%
%local _FMS i pos _ThisCat _Index1 _Index2 _ByVal NumCats;
%global _NewFMS _Recurse;
%if &C ne %str() %then %let Cat = &C;
%if &A ne %str() %then %let Action = &A;
%let Action = %upcase(&Action);
***** ***** ***** ERROR CHECKS ***** ***** *****;
%
%if %index(BMEDXLZ,&Action) eq 0 or
%length(&Action) ne 1 %then
%do;
%put ;%put %str(=====================================================================);
err_mput( macro=FmtSearch, msg=No valid action requested. Cat=&Cat Action=&Action )
%%put %str(=====================================================================);
%put ;
%goto Finish;
%end;
***** ***** ***** MACRO BODY ***** ***** *****;
%
%if &Cat eq %str() and &Action ne L and &Action ne X and &Action ne Z %then
%do;%put Here%str(%')s a list:;
%goto Finish;
%end;
%if &Action eq X %then
%do;
options fmtsearch=();
%let Cat = %str();
%end;
%let Cat = %sysfunc(tranwrd(%upcase(&Cat),%str(.FORMATS),%str()));
%if &Cat ne %str() %then %let Cat = %sysfunc(compbl(&Cat));
%let NumCats = %eval(%length(&Cat) - %length(%sysfunc(compress(&Cat,%str( )))) +1);
%if &Action eq Z %then %let NumCats = 1;
%if &NumCats ge 1 %then
%do;
%if &Action eq M or &Action eq B %then
%do;
%let _Index1 = &NumCats;
%let _Index2 = 1;
%let _ByVal = -1;
%end;
%else
%do;
%let _Index1 = 1;
%let _Index2 = &NumCats;
%let _ByVal = 1;
%end;
%do i = &_Index1 %to &_Index2 %by &_ByVal;
%let _ThisCat = %scan(&Cat,&i,%str( ));
%let _FMS =
%upcase(%sysfunc(compress(%sysfunc(getoption(fmtsearch)),%str(%(%)))));
%let _FMS = %sysfunc(tranwrd(&_FMS,%str(.FORMATS),%str()));
%if &Action eq Z %then
%do;
%put FMS: &_FMS;
%let _FMS = %sysfunc(tranwrd(&_FMS,%str(WORK),%str()));
%let _FMS = %sysfunc(tranwrd(&_FMS,%str(LIBRARY),%str()));
options fmtsearch=(&_FMS);
%end;
%if &Action eq D or &Action eq M or &Action eq B or &Action eq E %then
%do;
%let _NewFMS = %sysfunc(tranwrd(%str( &_FMS ),%str( &_ThisCat ),%str()));
%if &_NewFMS ne %str() %then
%do;
/*%if %substr(&_NewFMS,1,%sysfunc(min(12,%length(&_NewFMS)))) eq WORK LIBRARY %then %let _NewFMS = %substr(&_NewFMS,13);*/
%if %substr(&_NewFMS,1,%sysfunc(min(12,%length(&_NewFMS)))) eq WORK LIBRARY %then %let _NewFMS = %substr(&_NewFMS%str( ),13);
%end;
%if &Action eq D %then %str(options fmtsearch=(&_NewFMS););
%end;
%if &Action eq M %then
%do;
options fmtsearch=(&_ThisCat &_NewFMS);
%end;
%if &Action eq B %then
%do;
%let _NewCat = &_ThisCat;
%if %sysfunc(indexw(&_NewFMS,WORK)) eq 0 and &_ThisCat ne WORK %then
%let _NewCat = &_NewCat WORK;
%if %sysfunc(indexw(&_NewFMS,LIBRARY)) eq 0 and &_ThisCat ne LIBRARY %then
%let _NewCat = &_NewCat LIBRARY;
options fmtsearch=(&_NewCat &_NewFMS);
%end;
%if &Action eq E %then
%do;
options fmtsearch=(&_NewFMS &_ThisCat);
%end;
%end;
%end;
%if %mparam_is_yes( &Status ) %then
%do;
%put;
%put %str(=====================================================================);
%let _FMS = %upcase(%sysfunc(compress(%sysfunc(getoption(fmtsearch)),%str(%(%)))));
%if %sysfunc(indexw(%upcase(&_FMS),LIBRARY)) eq 0 %then
%let _FMS = LIBRARY* &_FMS;
%if %sysfunc(indexw(%upcase(&_FMS),WORK)) eq 0 %then %let _FMS = WORK* &_FMS;
%put Current FmtSearch Option value:;
%put ;
%put %str( )&_FMS;
%put ;
%if %index(&_FMS,*) ne 0 %then
%do;
%put %str( )*implicitly included by default.;
%put;
%end;
%let _FMS = %sysfunc(compress(&_FMS,%str(*)));
%put %str(=====================================================================);
%put Status of current catalogs:;
%put ;
%let i = 1;
%do %while(%scan(&_FMS,&i,%str( )) ne %str( ));
%let ThisCat = %scan(&_FMS,&i,%str( ));
%if %index(&ThisCat,.) eq 0 %then %let ThisCat = &ThisCat..FORMATS;
%if %sysfunc(cexist(&ThisCat)) eq 1 %then
%put NOTE: &ThisCat EXISTS;
%else
%put NOTE: &ThisCat DOES NOT EXIST;
%let i = %eval(&i + 1);
%end;
%put %str(=====================================================================);
%put ;
%end;
%Finish:
%let _Recurse = %str();
%***** ***** ***** CLEAN UP ***** ***** *****;
%mend FmtSearch;
/************************ UNCOMMENT TO TEST ***************************
libname Test 'D:\';
%FmtSearch( action=L )
%FmtSearch( cat=Test, action=0 )
%FmtSearch( cat=Test, action=E )
/**********************************************************************/
Manage Multiple SAS Format Libraries
Purpose: Autocall macro to manage multiple SAS format libraries.