From db195a831151298b3e10c3282b2741b56a208167 Mon Sep 17 00:00:00 2001 From: Ivor Townsend Date: Mon, 10 Jan 2022 16:33:44 +0000 Subject: [PATCH 1/3] fix: proc append warnings for file attributes --- base/mp_dirlist.sas | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/base/mp_dirlist.sas b/base/mp_dirlist.sas index 371ddbf..f2b7e5d 100644 --- a/base/mp_dirlist.sas +++ b/base/mp_dirlist.sas @@ -50,6 +50,9 @@

SAS Macros

@li mp_dropmembers.sas + @li mf_existds.sas + @li mf_getvarlist.sas + @li mf_wordsInStr1ButNotStr2.sas

Related Macros

@li mp_dirlist.test.sas @@ -194,8 +197,46 @@ data &out_ds; run; /* update main table */ -proc append base=&outds data=&out_ds; -run; + +/* The latest update may not match the base table as the addition of file +attributes is conditional, so cannot always use proc append as warnings may be +generated */ + +%if %mf_existds(&outds) %then %do; + + %if %length(%mf_getvarlist(&outds)) > %length(%mf_getvarlist(&out_ds)) %then + %do; + %let varstr1 = %mf_getvarlist(&outds); + %let varstr2 = %mf_getvarlist(&out_ds); + %end; + + %else %do; + %let varstr1 = %mf_getvarlist(&out_ds); + %let varstr2 = %mf_getvarlist(&outds); + %end; + + %if "%mf_wordsInStr1ButNotStr2( + Str1=&varstr1 + ,Str2=&varstr2 + )" ne "" %then %do; + + data &outds; + set &outds &out_ds; + run; + + %end; + + %else %do; + proc append base=&outds data=&out_ds; + run; + %end; + +%end; + +%else %do; + proc append base=&outds data=&out_ds; + run; +%end; /* recursive call */ %if &maxdepth>&level or &maxdepth=MAX %then %do; From 259bcc0173d2c5bbf2edfb9d8142ec1f84031c8b Mon Sep 17 00:00:00 2001 From: Ivor Townsend Date: Mon, 10 Jan 2022 16:49:33 +0000 Subject: [PATCH 2/3] fix: proc append warnings for file attributes --- base/mp_dirlist.sas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/mp_dirlist.sas b/base/mp_dirlist.sas index f2b7e5d..b057872 100644 --- a/base/mp_dirlist.sas +++ b/base/mp_dirlist.sas @@ -52,7 +52,7 @@ @li mp_dropmembers.sas @li mf_existds.sas @li mf_getvarlist.sas - @li mf_wordsInStr1ButNotStr2.sas + @li mf_wordsinstr1butnotstr2.sas

Related Macros

@li mp_dirlist.test.sas @@ -215,7 +215,7 @@ generated */ %let varstr2 = %mf_getvarlist(&outds); %end; - %if "%mf_wordsInStr1ButNotStr2( + %if "%mf_wordsinstr1butnotstr2( Str1=&varstr1 ,Str2=&varstr2 )" ne "" %then %do; From 351ceeb357439acd591877aa8036c39592301c55 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Mon, 10 Jan 2022 18:42:52 +0000 Subject: [PATCH 3/3] fix: tidy up --- all.sas | 34 ++++++++++++++++++------- base/mp_dirlist.sas | 61 +++++++++++++-------------------------------- 2 files changed, 43 insertions(+), 52 deletions(-) diff --git a/all.sas b/all.sas index 20d5b25..3b004ee 100644 --- a/all.sas +++ b/all.sas @@ -3863,8 +3863,7 @@ run; Credit for the rename approach: https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375/highlight/true#M5003 - - usage: + Usage: %mp_dirlist(path=/some/location, outds=myTable, maxdepth=MAX) @@ -3880,12 +3879,12 @@ run; X CMD) do please raise an issue! - @param [in] path= for which to return contents - @param [in] fref= Provide a DISK engine fileref as an alternative to PATH + @param [in] path= (%sysfunc(pathname(work))) Path for which to return contents + @param [in] fref= (0) Provide a DISK engine fileref as an alternative to PATH @param [in] maxdepth= (0) Set to a positive integer to indicate the level of subdirectory scan recursion - eg 3, to go `./3/levels/deep`. For unlimited recursion, set to MAX. - @param [out] outds= the output dataset to create + @param [out] outds= (work.mp_dirlist) The output dataset to create @param [out] getattrs= (NO) If getattrs=YES then the doptname / foptname functions are used to scan all properties - any characters that are not valid in a SAS name (v7) are simply stripped, and the table is transposed @@ -3906,13 +3905,15 @@ run; - OS SPECIFIC variables, if getattrs= is used.

SAS Macros

+ @li mf_existds.sas + @li mf_getvarlist.sas + @li mf_wordsinstr1butnotstr2.sas @li mp_dropmembers.sas

Related Macros

@li mp_dirlist.test.sas @version 9.2 - @author Allan Bowe **/ %macro mp_dirlist(path=%sysfunc(pathname(work)) @@ -4050,9 +4051,24 @@ data &out_ds; set &out_ds(where=(filepath ne '')); run; -/* update main table */ -proc append base=&outds data=&out_ds; -run; +/** + * The above transpose can mean that some updates create additional columns. + * This necessitates the occasional use of datastep over proc append. + */ +%local basevars appvars usedatastep; +%let basevars=%mf_getvarlist(&outds); +%let appvars=%mf_getvarlist(&out_ds); +%let newvars=%length(%mf_wordsinstr1butnotstr2(Str1=&appvars,Str2=&basevars)); + +%if %mf_existds(&outds) and &newvars>0 %then %do; + data &outds; + set &outds &out_ds; + run; +%end; +%else %do; + proc append base=&outds data=&out_ds force nowarn; + run; +%end; /* recursive call */ %if &maxdepth>&level or &maxdepth=MAX %then %do; diff --git a/base/mp_dirlist.sas b/base/mp_dirlist.sas index b057872..8f9314d 100644 --- a/base/mp_dirlist.sas +++ b/base/mp_dirlist.sas @@ -6,8 +6,7 @@ Credit for the rename approach: https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375/highlight/true#M5003 - - usage: + Usage: %mp_dirlist(path=/some/location, outds=myTable, maxdepth=MAX) @@ -23,12 +22,12 @@ X CMD) do please raise an issue! - @param [in] path= for which to return contents - @param [in] fref= Provide a DISK engine fileref as an alternative to PATH + @param [in] path= (%sysfunc(pathname(work))) Path for which to return contents + @param [in] fref= (0) Provide a DISK engine fileref as an alternative to PATH @param [in] maxdepth= (0) Set to a positive integer to indicate the level of subdirectory scan recursion - eg 3, to go `./3/levels/deep`. For unlimited recursion, set to MAX. - @param [out] outds= the output dataset to create + @param [out] outds= (work.mp_dirlist) The output dataset to create @param [out] getattrs= (NO) If getattrs=YES then the doptname / foptname functions are used to scan all properties - any characters that are not valid in a SAS name (v7) are simply stripped, and the table is transposed @@ -49,16 +48,15 @@ - OS SPECIFIC variables, if getattrs= is used.

SAS Macros

- @li mp_dropmembers.sas @li mf_existds.sas @li mf_getvarlist.sas @li mf_wordsinstr1butnotstr2.sas + @li mp_dropmembers.sas

Related Macros

@li mp_dirlist.test.sas @version 9.2 - @author Allan Bowe **/ %macro mp_dirlist(path=%sysfunc(pathname(work)) @@ -196,45 +194,22 @@ data &out_ds; set &out_ds(where=(filepath ne '')); run; -/* update main table */ - -/* The latest update may not match the base table as the addition of file -attributes is conditional, so cannot always use proc append as warnings may be -generated */ - -%if %mf_existds(&outds) %then %do; - - %if %length(%mf_getvarlist(&outds)) > %length(%mf_getvarlist(&out_ds)) %then - %do; - %let varstr1 = %mf_getvarlist(&outds); - %let varstr2 = %mf_getvarlist(&out_ds); - %end; - - %else %do; - %let varstr1 = %mf_getvarlist(&out_ds); - %let varstr2 = %mf_getvarlist(&outds); - %end; - - %if "%mf_wordsinstr1butnotstr2( - Str1=&varstr1 - ,Str2=&varstr2 - )" ne "" %then %do; - - data &outds; - set &outds &out_ds; - run; - - %end; - - %else %do; - proc append base=&outds data=&out_ds; - run; - %end; +/** + * The above transpose can mean that some updates create additional columns. + * This necessitates the occasional use of datastep over proc append. + */ +%local basevars appvars usedatastep; +%let basevars=%mf_getvarlist(&outds); +%let appvars=%mf_getvarlist(&out_ds); +%let newvars=%length(%mf_wordsinstr1butnotstr2(Str1=&appvars,Str2=&basevars)); +%if %mf_existds(&outds) and &newvars>0 %then %do; + data &outds; + set &outds &out_ds; + run; %end; - %else %do; - proc append base=&outds data=&out_ds; + proc append base=&outds data=&out_ds force nowarn; run; %end;