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