diff --git a/all.sas b/all.sas index d18573d..531a9ab 100644 --- a/all.sas +++ b/all.sas @@ -2216,6 +2216,14 @@ Usage: select count(*) into: orig from &lib..&ds; quit; + %local notfound; + proc sql outobs=10 noprint; + select distinct &col into: notfound separated by ' ' + from &lib..&ds + where &col not in ( + select &ccol from &clib..&cds + ); + %mp_abort(iftrue= (&syscc ne 0) ,mac=&sysmacroname ,msg=%str(syscc=&syscc after macro query) @@ -2226,7 +2234,7 @@ Usage: test_description=symget('desc'); test_result='FAIL'; test_comments="&sysmacroname: &lib..&ds..&col has &result values " - !!"not in &clib..&cds..&ccol "; + !!"not in &clib..&cds..&ccol.. First 10 vals:"!!symget('notfound'); %if &test=ANYVAL %then %do; if &result < &orig then test_result='PASS'; %end; @@ -4230,6 +4238,72 @@ filename &fref1 clear; %mend mp_filtervalidate; /** + @file + @brief Creates a dataset with column metadata. + @details This macro takes the `proc contents` output and "tidies it up" in the + following ways: + + @li Blank labels are filled in with column names + @li Formats are reconstructed with default values + @li Types such as DATE / TIME / DATETIME are inferred from the formats + + Example usage: + + %mp_getcols(sashelp.airline,outds=work.myds) + + @param ds The dataset from which to obtain column metadata + @param outds= (work.cols) The output dataset to create. Sample data: + |NAME $|LENGTH 8|VARNUM 8|LABEL $|FORMAT $49|TYPE $1 |DDTYPE $| + |---|---|---|---|---|---|---| + |AIR|8|2|international airline travel (thousands)|8.|N|NUMERIC| + |DATE|8|1|DATE|MONYY.|N|DATE| + |REGION|3|3|REGION|$3.|C|CHARACTER| + +

Related Macros

+ @li mf_getvarlist.sas + @li mm_getcols.sas + + @version 9.2 + @author Allan Bowe + @copyright Macro People Ltd - this is a licensed product and + NOT FOR RESALE OR DISTRIBUTION. + +**/ + +%macro mp_getcols(ds, outds=work.cols); + +proc contents noprint data=&ds + out=_data_ (keep=name type length label varnum format:); +run; +data &outds(keep=name type length varnum format label ddtype); + set &syslast(rename=(format=format2 type=type2)); + name=upcase(name); + if type2=2 then do; + length format $49.; + if format2='' then format=cats('$',length,'.'); + else if formatl=0 then format=cats(format2,'.'); + else format=cats(format2,formatl,'.'); + type='C'; + ddtype='CHARACTER'; + end; + else do; + if format2='' then format=cats(length,'.'); + else if formatl=0 then format=cats(format2,'.'); + else if formatd=0 then format=cats(format2,formatl,'.'); + else format=cats(format2,formatl,'.',formatd); + type='N'; + if format=:'DATETIME' then ddtype='DATETIME'; + else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY' + or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA' + or format=:'MONYY' + then ddtype='DATE'; + else if format=:'TIME' then ddtype='TIME'; + else ddtype='NUMERIC'; + end; + if label='' then label=name; +run; + +%mend mp_getcols;/** @file mp_getconstraints.sas @brief Get constraint details at column level @details Useful for capturing constraints before they are dropped / reapplied diff --git a/base/mp_assertcolvals.sas b/base/mp_assertcolvals.sas index c10ea3a..5ee518c 100644 --- a/base/mp_assertcolvals.sas +++ b/base/mp_assertcolvals.sas @@ -115,6 +115,14 @@ select count(*) into: orig from &lib..&ds; quit; + %local notfound; + proc sql outobs=10 noprint; + select distinct &col into: notfound separated by ' ' + from &lib..&ds + where &col not in ( + select &ccol from &clib..&cds + ); + %mp_abort(iftrue= (&syscc ne 0) ,mac=&sysmacroname ,msg=%str(syscc=&syscc after macro query) @@ -125,7 +133,7 @@ test_description=symget('desc'); test_result='FAIL'; test_comments="&sysmacroname: &lib..&ds..&col has &result values " - !!"not in &clib..&cds..&ccol "; + !!"not in &clib..&cds..&ccol.. First 10 vals:"!!symget('notfound'); %if &test=ANYVAL %then %do; if &result < &orig then test_result='PASS'; %end; diff --git a/base/mp_getcols.sas b/base/mp_getcols.sas new file mode 100644 index 0000000..8c5f315 --- /dev/null +++ b/base/mp_getcols.sas @@ -0,0 +1,67 @@ +/** + @file + @brief Creates a dataset with column metadata. + @details This macro takes the `proc contents` output and "tidies it up" in the + following ways: + + @li Blank labels are filled in with column names + @li Formats are reconstructed with default values + @li Types such as DATE / TIME / DATETIME are inferred from the formats + + Example usage: + + %mp_getcols(sashelp.airline,outds=work.myds) + + @param ds The dataset from which to obtain column metadata + @param outds= (work.cols) The output dataset to create. Sample data: + |NAME $|LENGTH 8|VARNUM 8|LABEL $|FORMAT $49|TYPE $1 |DDTYPE $| + |---|---|---|---|---|---|---| + |AIR|8|2|international airline travel (thousands)|8.|N|NUMERIC| + |DATE|8|1|DATE|MONYY.|N|DATE| + |REGION|3|3|REGION|$3.|C|CHARACTER| + +

Related Macros

+ @li mf_getvarlist.sas + @li mm_getcols.sas + + @version 9.2 + @author Allan Bowe + @copyright Macro People Ltd - this is a licensed product and + NOT FOR RESALE OR DISTRIBUTION. + +**/ + +%macro mp_getcols(ds, outds=work.cols); + +proc contents noprint data=&ds + out=_data_ (keep=name type length label varnum format:); +run; +data &outds(keep=name type length varnum format label ddtype); + set &syslast(rename=(format=format2 type=type2)); + name=upcase(name); + if type2=2 then do; + length format $49.; + if format2='' then format=cats('$',length,'.'); + else if formatl=0 then format=cats(format2,'.'); + else format=cats(format2,formatl,'.'); + type='C'; + ddtype='CHARACTER'; + end; + else do; + if format2='' then format=cats(length,'.'); + else if formatl=0 then format=cats(format2,'.'); + else if formatd=0 then format=cats(format2,formatl,'.'); + else format=cats(format2,formatl,'.',formatd); + type='N'; + if format=:'DATETIME' then ddtype='DATETIME'; + else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY' + or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA' + or format=:'MONYY' + then ddtype='DATE'; + else if format=:'TIME' then ddtype='TIME'; + else ddtype='NUMERIC'; + end; + if label='' then label=name; +run; + +%mend mp_getcols; \ No newline at end of file diff --git a/tests/crossplatform/mp_getcols.test.sas b/tests/crossplatform/mp_getcols.test.sas new file mode 100644 index 0000000..eb0ef7d --- /dev/null +++ b/tests/crossplatform/mp_getcols.test.sas @@ -0,0 +1,33 @@ +/** + @file + @brief Testing mp_getcols macro + +

SAS Macros

+ @li mp_getcols.sas + @li mp_assertcolvals.sas + @li mp_assertdsobs.sas + +**/ + + +/* valid filter */ +%mp_getcols(sashelp.airline,outds=work.info) + + +%mp_assertdsobs(work.info, + desc=Has 3 records, + test=EQUALS 3, + outds=work.test_results +) + +data work.check; + length val $10; + do val='NUMERIC','DATE','CHARACTER'; + output; + end; +run; +%mp_assertcolvals(work.info.ddtype, + checkvals=work.check.val, + desc=All values have a match, + test=ALLVALS +) \ No newline at end of file