diff --git a/all.sas b/all.sas index 2080418..c2e5e43 100644 --- a/all.sas +++ b/all.sas @@ -1856,7 +1856,7 @@ Usage: %if "&sysprocessmode " = "SAS Stored Process Server " %then %do; data _null_; - putlog 'stpsrvset program error and syscc'; + putlog 'stpsrvset program err and syscc'; rc=stpsrvset('program error', 0); call symputx("syscc",0,"g"); run; @@ -1902,6 +1902,62 @@ Usage: %mend mp_abort; /** @endcond *//** + @file + @brief Append (concatenate) two or more files. + @details Will append one more more `appendrefs` (filerefs) to a `baseref`. + Uses a binary mechanism, so will work with any file type. For that reason - + use with care! And supply your own trailing carriage returns in each file.. + + Usage: + + filename tmp1 temp; + filename tmp2 temp; + filename tmp3 temp; + data _null_; file tmp1; put 'base file'; + data _null_; file tmp2; put 'append1'; + data _null_; file tmp3; put 'append2'; + run; + %mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3) + + + @param [in] baseref= Fileref of the base file (should exist) + @param [in] appendrefs= One or more filerefs to be appended to the base + fileref. Space separated. + + @version 9.2 + @author Allan Bowe, source: https://github.com/sasjs/core + +

SAS Macros

+ @li mp_abort.sas + @li mp_binarycopy.sas + + +**/ + +%macro mp_appendfile( + baseref=0, + appendrefs=0 +)/*/STORE SOURCE*/; + +%mp_abort(iftrue= (&baseref=0) + ,mac=&sysmacroname + ,msg=%str(Baseref NOT specified!) +) +%mp_abort(iftrue= (&appendrefs=0) + ,mac=&sysmacroname + ,msg=%str(Appendrefs NOT specified!) +) + +%local i; +%do i=1 %to %sysfunc(countw(&appendrefs)); + %mp_abort(iftrue= (&syscc>0) + ,mac=&sysmacroname + ,msg=%str(syscc=&syscc) + ) + %mp_binarycopy(inref=%scan(&appendrefs,&i), outref=&baseref, mode=APPEND) +%end; + +%mend mp_appendfile;/** @file @brief Generic assertion @details Useful in the context of writing sasjs tests. The results of the @@ -2132,6 +2188,7 @@ Usage:

SAS Macros

@li mf_existds.sas + @li mf_getuniquename.sas @li mf_nobs.sas @li mp_abort.sas @@ -2217,13 +2274,25 @@ Usage: select count(*) into: orig from &lib..&ds; quit; - %local notfound; - proc sql outobs=10 noprint; - select distinct &col into: notfound separated by ' ' + %local notfound tmp1 tmp2; + %let tmp1=%mf_getuniquename(); + %let tmp2=%mf_getuniquename(); + + /* this is a bit convoluted - but using sql outobs=10 throws warnings */ + proc sql noprint; + create view &tmp1 as + select distinct &col from &lib..&ds where &col not in ( select &ccol from &clib..&cds ); + data &tmp2; + set &tmp1; + if _n_>10 then stop; + run; + proc sql; + select distinct &col into: notfound separated by ' ' from &tmp2; + %mp_abort(iftrue= (&syscc ne 0) ,mac=&sysmacroname diff --git a/base/mp_abort.sas b/base/mp_abort.sas index 51dbedf..099a7ee 100644 --- a/base/mp_abort.sas +++ b/base/mp_abort.sas @@ -208,7 +208,7 @@ %if "&sysprocessmode " = "SAS Stored Process Server " %then %do; data _null_; - putlog 'stpsrvset program error and syscc'; + putlog 'stpsrvset program err and syscc'; rc=stpsrvset('program error', 0); call symputx("syscc",0,"g"); run; diff --git a/base/mp_appendfile.sas b/base/mp_appendfile.sas new file mode 100644 index 0000000..77537d2 --- /dev/null +++ b/base/mp_appendfile.sas @@ -0,0 +1,57 @@ +/** + @file + @brief Append (concatenate) two or more files. + @details Will append one more more `appendrefs` (filerefs) to a `baseref`. + Uses a binary mechanism, so will work with any file type. For that reason - + use with care! And supply your own trailing carriage returns in each file.. + + Usage: + + filename tmp1 temp; + filename tmp2 temp; + filename tmp3 temp; + data _null_; file tmp1; put 'base file'; + data _null_; file tmp2; put 'append1'; + data _null_; file tmp3; put 'append2'; + run; + %mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3) + + + @param [in] baseref= Fileref of the base file (should exist) + @param [in] appendrefs= One or more filerefs to be appended to the base + fileref. Space separated. + + @version 9.2 + @author Allan Bowe, source: https://github.com/sasjs/core + +

SAS Macros

+ @li mp_abort.sas + @li mp_binarycopy.sas + + +**/ + +%macro mp_appendfile( + baseref=0, + appendrefs=0 +)/*/STORE SOURCE*/; + +%mp_abort(iftrue= (&baseref=0) + ,mac=&sysmacroname + ,msg=%str(Baseref NOT specified!) +) +%mp_abort(iftrue= (&appendrefs=0) + ,mac=&sysmacroname + ,msg=%str(Appendrefs NOT specified!) +) + +%local i; +%do i=1 %to %sysfunc(countw(&appendrefs)); + %mp_abort(iftrue= (&syscc>0) + ,mac=&sysmacroname + ,msg=%str(syscc=&syscc) + ) + %mp_binarycopy(inref=%scan(&appendrefs,&i), outref=&baseref, mode=APPEND) +%end; + +%mend mp_appendfile; \ No newline at end of file diff --git a/base/mp_assertcolvals.sas b/base/mp_assertcolvals.sas index 5ee518c..7176782 100644 --- a/base/mp_assertcolvals.sas +++ b/base/mp_assertcolvals.sas @@ -30,6 +30,7 @@

SAS Macros

@li mf_existds.sas + @li mf_getuniquename.sas @li mf_nobs.sas @li mp_abort.sas @@ -115,13 +116,25 @@ select count(*) into: orig from &lib..&ds; quit; - %local notfound; - proc sql outobs=10 noprint; - select distinct &col into: notfound separated by ' ' + %local notfound tmp1 tmp2; + %let tmp1=%mf_getuniquename(); + %let tmp2=%mf_getuniquename(); + + /* this is a bit convoluted - but using sql outobs=10 throws warnings */ + proc sql noprint; + create view &tmp1 as + select distinct &col from &lib..&ds where &col not in ( select &ccol from &clib..&cds ); + data &tmp2; + set &tmp1; + if _n_>10 then stop; + run; + proc sql; + select distinct &col into: notfound separated by ' ' from &tmp2; + %mp_abort(iftrue= (&syscc ne 0) ,mac=&sysmacroname diff --git a/tests/crossplatform/mp_appendfile.test.sas b/tests/crossplatform/mp_appendfile.test.sas new file mode 100644 index 0000000..1252d0e --- /dev/null +++ b/tests/crossplatform/mp_appendfile.test.sas @@ -0,0 +1,41 @@ +/** + @file + @brief Testing mp_appendfile.sas macro + +

SAS Macros

+ @li mp_appendfile.sas + @li mp_assert.sas + +**/ + + +filename tmp1 temp; +filename tmp2 temp; +filename tmp3 temp; +data _null_; file tmp1; put 'base file'; +data _null_; file tmp2; put 'append1'; +data _null_; file tmp3; put 'append2'; +run; +%mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3) +data _null_; + infile tmp1; + input; + put _infile_; + call symputx(cats('check',_n_),_infile_); +run; +%global check1 check2 check3; +%mp_assert( + iftrue=("&check1"="base file"), + desc=Line 1 of file tmp1 is correct, + outds=work.test_results +) +%mp_assert( + iftrue=("&check2"="append1"), + desc=Line 2 of file tmp1 is correct, + outds=work.test_results +) +%mp_assert( + iftrue=("&check3"="append2"), + desc=Line 3 of file tmp1 is correct, + outds=work.test_results +) \ No newline at end of file