1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-11 06:24:35 +00:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Allan Bowe
009485e5b9 Merge pull request #158 from sasjs/woff2
fix: support for WOFF2 and TTF
2022-02-03 19:51:39 +02:00
munja
eb01c8772d fix: support for WOFF2 and TTF 2022-02-03 18:51:07 +01:00
Allan Bowe
e3fb69928c Merge pull request #157 from sasjs/dependabot
chore: adding dependabot
2022-02-03 19:31:16 +02:00
munja
65afa14466 chore: removing leading spaces 2022-02-03 18:30:49 +01:00
munja
0176b19616 chore: adding dependabot 2022-02-03 18:29:31 +01:00
Allan Bowe
9f3dfd9a59 Merge pull request #156 from sasjs/csv
adding WOFF to mp_streamfile
2022-02-03 19:23:09 +02:00
munja
513ea354ab chore: updating headers in mp_streamfile and running all.sas 2022-02-03 16:45:42 +01:00
munja
7b686e11c9 feat: adding WOFF support to mp_streamfile (also re-ordering sections alphabetically) 2022-02-03 16:44:39 +01:00
munja
3997000266 fix: encoding issue in mp_ds2csv (option should have been in quotes) 2022-02-03 15:00:46 +01:00
Allan Bowe
6e177d4cae Merge pull request #155 from sasjs/cmplib
fix: auto-detect cmplib in mcfxx funcs, mp_ds2csv supports dates etc,…
2022-02-02 23:43:43 +02:00
munja
3554991ff8 fix: auto-detect cmplib in mcfxx funcs, mp_ds2csv supports dates etc, fix to mp_abort in viya due to abort cancel FILE hard stop (according to docs it should continue outside of the include) 2022-02-02 21:18:51 +01:00
13 changed files with 397 additions and 131 deletions

9
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: npm
directory: '/'
schedule:
interval: monthly
open-pull-requests-limit: 3
allow:
- dependency-type: "production"

View File

@@ -196,6 +196,8 @@ When contributing to this library, it is therefore important to ensure that all
We are currently on major release v4. Breaking changes should be marked with the [deprecated](https://www.doxygen.nl/manual/commands.html#cmddeprecated) doxygen tag. The following changes are planned when the next major (breaking) release becomes necessary:
* mp_testservice.sas to be renamed as mp_execute.sas (as it doesn't actually test anything)
* `insert_cmplib` option of mcf_xxx macros will be deprecated (the option is now checked automatically with value inserted only if needed)
* mcf_xxx macros to have `wrap=` option defaulted to YES for convenience
## Star Gazing

222
all.sas
View File

@@ -2106,7 +2106,10 @@ Usage:
%if %length(&mac)>0 %then %put NOTE- called by &mac;
%put NOTE - &msg;
%if %symexist(_SYSINCLUDEFILEDEVICE) %then %do;
%if %symexist(_SYSINCLUDEFILEDEVICE)
/* abort cancel FILE does not restart outside the INCLUDE on Viya 3.5 */
and "&SYSPROCESSNAME " ne "Compute Server "
%then %do;
%if "*&_SYSINCLUDEFILEDEVICE*" ne "**" %then %do;
data &errds;
iftrue='1=1';
@@ -4666,10 +4669,28 @@ quit;
@brief Export a dataset to a CSV file WITH leading blanks
@details Export a dataset to a file or fileref, retaining leading blanks.
When using SASJS headerformat, the input statement is provided in the first
row of the CSV.
Usage:
%mp_ds2csv(sashelp.class,outref="%sysfunc(pathname(work))/file.csv")
filename example temp;
%mp_ds2csv(sashelp.air,outref=example,headerformat=SASJS)
data; infile example; input;put _infile_; if _n_>5 then stop;run;
data _null_;
infile example;
input;
call symputx('stmnt',_infile_);
stop;
run;
data work.want;
infile example dsd firstobs=2;
input &stmnt;
run;
Why use mp_ds2csv over, say, proc export?
1. Ability to retain leading blanks (this is a major one)
@@ -4686,17 +4707,24 @@ quit;
@li LABEL - Use the variable label (or name, if blank)
@li NAME - Use the variable name
@li SASJS - Used to create sasjs-formatted input CSVs, eg for use in
mp_testservice.sas
mp_testservice.sas. This format will supply an input statement in the
first row, making ingestion by datastep a breeze. Special misisng values
will be prefixed with a period (eg `.A`) to enable ingestion on both SAS 9
and Viya. Dates / Datetimes etc are identified by the format type (lookup
with mcf_getfmttype.sas) and converted to human readable formats (not
numbers).
@param [out] outfile= The output filename - should be quoted.
@param [out] outref= (0) The output fileref (takes precedence if provided)
@param [in] outencoding= (0) The output encoding to use (unquoted)
@param [in] outencoding= (0) The (quoted) output encoding to use, eg `"UTF-8"`
@param [in] termstr= (CRLF) The line seperator to use. For SASJS, will
always be CRLF. Valid values:
@li CRLF
@li LF
<h4> SAS Macros </h4>
@li mcf_getfmttype.sas
@li mf_getuniquename.sas
@li mf_getvarformat.sas
@li mf_getvarlist.sas
@li mf_getvartype.sas
@@ -4713,7 +4741,7 @@ quit;
,termstr=CRLF
)/*/STORE SOURCE*/;
%local outloc delim i varlist var vcnt vat dsv vcom vmiss;
%local outloc delim i varlist var vcnt vat dsv vcom vmiss fmttype vfmt;
%if not %sysfunc(exist(&ds)) %then %do;
%put %str(WARN)ING: &ds does not exist;
@@ -4723,7 +4751,7 @@ quit;
%if %index(&ds,.)=0 %then %let ds=WORK.&ds;
%if &outencoding=0 %then %let outencoding=;
%else %let outencoding=encoding="&outencoding";
%else %let outencoding=encoding=&outencoding;
%if &outref=0 %then %let outloc=&outfile;
%else %let outloc=&outref;
@@ -4731,6 +4759,7 @@ quit;
%if &headerformat=SASJS %then %do;
%let delim=",";
%let termstr=CRLF;
%mcf_getfmttype(wrap=YES)
%end;
%else %if &dlm=COMMA %then %let delim=",";
%else %let delim=";";
@@ -4740,7 +4769,8 @@ quit;
/* first get headers */
data _null_;
file &outloc &outencoding lrecl=32767 termstr=&termstr;
length header $ 2000 varnm $32 dlm $1;
length header $ 2000 varnm vfmt $32 dlm $1 fmttype $8;
call missing(of _all_);
dsid=open("&ds.","i");
num=attrn(dsid,"nvars");
dlm=&delim;
@@ -4755,7 +4785,14 @@ data _null_;
%end;
%else %if &headerformat=SASJS %then %do;
if vartype(dsid,i)='C' then header=cats(varnm,':$char',varlen(dsid,i),'.');
else header=cats(varnm,':best.');
else do;
vfmt=coalescec(varfmt(dsid,i),'0');
fmttype=mcf_getfmttype(vfmt);
if fmttype='DATE' then header=cats(varnm,':date9.');
else if fmttype='DATETIME' then header=cats(varnm,':E8601DT26.6');
else if fmttype='TIME' then header=cats(varnm,':TIME12.');
else header=cats(varnm,':best.');
end;
%end;
%else %do;
%put &sysmacroname: Invalid headerformat value (&headerformat);
@@ -4810,14 +4847,29 @@ data _null_;
%let vcom=;
%end;
%if %mf_getvartype(&ds,&var)=N %then %do;
%if &headerformat = SASJS %then %do;
%let vcom=&delim;
%let fmttype=%sysfunc(mcf_getfmttype(%mf_getvarformat(&ds,&var)0));
%if &fmttype=DATE %then %let vfmt=DATE9.;
%else %if &fmttype=DATETIME %then %let vfmt=E8601DT26.6;
%else %if &fmttype=TIME %then %let vfmt=TIME12.;
%else %do;
%let vfmt=;
%let vcom=;
%end;
%end;
%else %let vcom=;
/* must use period - in order to work in both 9.4 and Viya 3.5 */
if missing(&var) and &var ne %sysfunc(getoption(MISSING)) then do;
&vmiss=cats('.',&var);
put &vmiss &vat;
end;
else put &var &vat;
else put &var &vfmt &vcom &vat;
%end;
%else %do;
%if &i ne &vcnt %then %let vcom=&delim;
put &var &&vlen&i &vcom &vat;
%end;
%end;
@@ -7877,9 +7929,10 @@ https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/mcrolref/n1j5tcc0n2xczyn1
this dataset.
It will then run an abort cancel FILE to stop the include running, and pass
the dataset back.
NOTE - it is NOT possible to read this dataset as part of _this_ macro -
when running abort cancel FILE, ALL macros are closed, so instead it is
necessary to invoke "%mp_abort(mode=INCLUDE)" OUTSIDE of any macro wrappers.
IMPORTANT NOTE - it is NOT possible to read this dataset as part of _this_
macro! When running abort cancel FILE, ALL macros are closed, so instead it
is necessary to invoke "%mp_abort(mode=INCLUDE)" OUTSIDE of macro wrappers.
@version 9.4
@@ -10747,17 +10800,16 @@ create table &outds as
%mp_streamfile(contenttype=csv,inloc=/some/where.txt,outname=myfile.txt)
@param [in] contenttype= (TEXTS) Either TEXT, ZIP, CSV, EXCEL
@param [in] inloc= /path/to/file.ext to be sent
@param [in] inref= fileref of file to be sent (if provided, overrides `inloc`)
@param [out] outname= the name of the file, as downloaded by the browser
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mp_binarycopy.sas
@param contenttype= Either TEXT, ZIP, CSV, EXCEL (default TEXT)
@param inloc= /path/to/file.ext to be sent
@param inref= fileref of file to be sent (if provided, overrides `inloc`)
@param outname= the name of the file, as downloaded by the browser
@author Allan Bowe
@source https://github.com/sasjs/core
**/
@@ -10783,16 +10835,16 @@ data _null_;
if xengine='STREAM' then call symputx('streamweb',1,'l');
run;
%if &contentype=ZIP %then %do;
%if &contentype=CSV %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type','application/zip');
rc=stpsrv_header('Content-type','application/csv');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.zip'
contenttype='application/zip'
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.txt'
contenttype='application/csv'
contentdisp="attachment; filename=&outname";
%end;
%end;
@@ -10810,19 +10862,10 @@ run;
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %if &contentype=XLSX %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.xls'
contenttype=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
contentdisp="attachment; filename=&outname";
%else %if &contentype=HTML %then %do;
%if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name="_webout.json"
contenttype="text/html";
%end;
%end;
%else %if &contentype=TEXT %then %do;
@@ -10838,28 +10881,48 @@ run;
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %if &contentype=CSV %then %do;
%else %do;
%put %str(ERR)OR: Content Type &contenttype NOT SUPPORTED by &sysmacroname!;
%return;
%end;
%else %if &contentype=WOFF or &contentype=WOFF2 or &contentype=TTF %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type','application/csv');
rc=stpsrv_header('Content-type',"font/%lowcase(&contenttype)");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
contenttype="font/%lowcase(&contenttype)";
%end;
%end;
%else %if &contentype=XLSX %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.txt'
contenttype='application/csv'
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.xls'
contenttype=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %if &contentype=HTML %then %do;
%if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name="_webout.json"
contenttype="text/html";
%else %if &contentype=ZIP %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type','application/zip');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.zip'
contenttype='application/zip'
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %do;
%put %str(ERR)OR: Content Type &contenttype NOT SUPPORTED by &sysmacroname!;
%return;
%end;
%if &inref ne 0 %then %do;
@@ -23584,12 +23647,12 @@ run;
> fmt3=TIME
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -23604,11 +23667,12 @@ run;
**/
%macro mcf_getfmttype(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(mcf_getfmttype)=1 %then %return;
@@ -23656,7 +23720,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;
@@ -23738,12 +23809,12 @@ endsub;
> outa=3 outb=4 outc=5 outd=0
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -23755,12 +23826,12 @@ endsub;
**/
%macro mcf_length(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(mcf_length)=1 %then %return;
%if &wrap=YES %then %do;
@@ -23782,7 +23853,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;
@@ -23835,12 +23913,12 @@ endsub;
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -23852,12 +23930,12 @@ endsub;
**/
%macro mcf_stpsrv_header(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(stpsrv_header)=1 %then %return;
%if &wrap=YES %then %do;
@@ -23884,7 +23962,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;
@@ -23922,12 +24007,12 @@ endsub;
run;
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -23939,12 +24024,12 @@ endsub;
**/
%macro mcf_string2file(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(mcf_string2file)=1 %then %return;
%if &wrap=YES %then %do;
@@ -23971,7 +24056,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;

View File

@@ -66,7 +66,10 @@
%if %length(&mac)>0 %then %put NOTE- called by &mac;
%put NOTE - &msg;
%if %symexist(_SYSINCLUDEFILEDEVICE) %then %do;
%if %symexist(_SYSINCLUDEFILEDEVICE)
/* abort cancel FILE does not restart outside the INCLUDE on Viya 3.5 */
and "&SYSPROCESSNAME " ne "Compute Server "
%then %do;
%if "*&_SYSINCLUDEFILEDEVICE*" ne "**" %then %do;
data &errds;
iftrue='1=1';

View File

@@ -3,10 +3,28 @@
@brief Export a dataset to a CSV file WITH leading blanks
@details Export a dataset to a file or fileref, retaining leading blanks.
When using SASJS headerformat, the input statement is provided in the first
row of the CSV.
Usage:
%mp_ds2csv(sashelp.class,outref="%sysfunc(pathname(work))/file.csv")
filename example temp;
%mp_ds2csv(sashelp.air,outref=example,headerformat=SASJS)
data; infile example; input;put _infile_; if _n_>5 then stop;run;
data _null_;
infile example;
input;
call symputx('stmnt',_infile_);
stop;
run;
data work.want;
infile example dsd firstobs=2;
input &stmnt;
run;
Why use mp_ds2csv over, say, proc export?
1. Ability to retain leading blanks (this is a major one)
@@ -23,17 +41,24 @@
@li LABEL - Use the variable label (or name, if blank)
@li NAME - Use the variable name
@li SASJS - Used to create sasjs-formatted input CSVs, eg for use in
mp_testservice.sas
mp_testservice.sas. This format will supply an input statement in the
first row, making ingestion by datastep a breeze. Special misisng values
will be prefixed with a period (eg `.A`) to enable ingestion on both SAS 9
and Viya. Dates / Datetimes etc are identified by the format type (lookup
with mcf_getfmttype.sas) and converted to human readable formats (not
numbers).
@param [out] outfile= The output filename - should be quoted.
@param [out] outref= (0) The output fileref (takes precedence if provided)
@param [in] outencoding= (0) The output encoding to use (unquoted)
@param [in] outencoding= (0) The (quoted) output encoding to use, eg `"UTF-8"`
@param [in] termstr= (CRLF) The line seperator to use. For SASJS, will
always be CRLF. Valid values:
@li CRLF
@li LF
<h4> SAS Macros </h4>
@li mcf_getfmttype.sas
@li mf_getuniquename.sas
@li mf_getvarformat.sas
@li mf_getvarlist.sas
@li mf_getvartype.sas
@@ -50,7 +75,7 @@
,termstr=CRLF
)/*/STORE SOURCE*/;
%local outloc delim i varlist var vcnt vat dsv vcom vmiss;
%local outloc delim i varlist var vcnt vat dsv vcom vmiss fmttype vfmt;
%if not %sysfunc(exist(&ds)) %then %do;
%put %str(WARN)ING: &ds does not exist;
@@ -60,7 +85,7 @@
%if %index(&ds,.)=0 %then %let ds=WORK.&ds;
%if &outencoding=0 %then %let outencoding=;
%else %let outencoding=encoding="&outencoding";
%else %let outencoding=encoding=&outencoding;
%if &outref=0 %then %let outloc=&outfile;
%else %let outloc=&outref;
@@ -68,6 +93,7 @@
%if &headerformat=SASJS %then %do;
%let delim=",";
%let termstr=CRLF;
%mcf_getfmttype(wrap=YES)
%end;
%else %if &dlm=COMMA %then %let delim=",";
%else %let delim=";";
@@ -77,7 +103,8 @@
/* first get headers */
data _null_;
file &outloc &outencoding lrecl=32767 termstr=&termstr;
length header $ 2000 varnm $32 dlm $1;
length header $ 2000 varnm vfmt $32 dlm $1 fmttype $8;
call missing(of _all_);
dsid=open("&ds.","i");
num=attrn(dsid,"nvars");
dlm=&delim;
@@ -92,7 +119,14 @@ data _null_;
%end;
%else %if &headerformat=SASJS %then %do;
if vartype(dsid,i)='C' then header=cats(varnm,':$char',varlen(dsid,i),'.');
else header=cats(varnm,':best.');
else do;
vfmt=coalescec(varfmt(dsid,i),'0');
fmttype=mcf_getfmttype(vfmt);
if fmttype='DATE' then header=cats(varnm,':date9.');
else if fmttype='DATETIME' then header=cats(varnm,':E8601DT26.6');
else if fmttype='TIME' then header=cats(varnm,':TIME12.');
else header=cats(varnm,':best.');
end;
%end;
%else %do;
%put &sysmacroname: Invalid headerformat value (&headerformat);
@@ -147,14 +181,29 @@ data _null_;
%let vcom=;
%end;
%if %mf_getvartype(&ds,&var)=N %then %do;
%if &headerformat = SASJS %then %do;
%let vcom=&delim;
%let fmttype=%sysfunc(mcf_getfmttype(%mf_getvarformat(&ds,&var)0));
%if &fmttype=DATE %then %let vfmt=DATE9.;
%else %if &fmttype=DATETIME %then %let vfmt=E8601DT26.6;
%else %if &fmttype=TIME %then %let vfmt=TIME12.;
%else %do;
%let vfmt=;
%let vcom=;
%end;
%end;
%else %let vcom=;
/* must use period - in order to work in both 9.4 and Viya 3.5 */
if missing(&var) and &var ne %sysfunc(getoption(MISSING)) then do;
&vmiss=cats('.',&var);
put &vmiss &vat;
end;
else put &var &vat;
else put &var &vfmt &vcom &vat;
%end;
%else %do;
%if &i ne &vcnt %then %let vcom=&delim;
put &var &&vlen&i &vcom &vat;
%end;
%end;

View File

@@ -51,9 +51,10 @@ https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/mcrolref/n1j5tcc0n2xczyn1
this dataset.
It will then run an abort cancel FILE to stop the include running, and pass
the dataset back.
NOTE - it is NOT possible to read this dataset as part of _this_ macro -
when running abort cancel FILE, ALL macros are closed, so instead it is
necessary to invoke "%mp_abort(mode=INCLUDE)" OUTSIDE of any macro wrappers.
IMPORTANT NOTE - it is NOT possible to read this dataset as part of _this_
macro! When running abort cancel FILE, ALL macros are closed, so instead it
is necessary to invoke "%mp_abort(mode=INCLUDE)" OUTSIDE of macro wrappers.
@version 9.4

View File

@@ -12,17 +12,16 @@
%mp_streamfile(contenttype=csv,inloc=/some/where.txt,outname=myfile.txt)
@param [in] contenttype= (TEXTS) Either TEXT, ZIP, CSV, EXCEL
@param [in] inloc= /path/to/file.ext to be sent
@param [in] inref= fileref of file to be sent (if provided, overrides `inloc`)
@param [out] outname= the name of the file, as downloaded by the browser
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mp_binarycopy.sas
@param contenttype= Either TEXT, ZIP, CSV, EXCEL (default TEXT)
@param inloc= /path/to/file.ext to be sent
@param inref= fileref of file to be sent (if provided, overrides `inloc`)
@param outname= the name of the file, as downloaded by the browser
@author Allan Bowe
@source https://github.com/sasjs/core
**/
@@ -48,16 +47,16 @@ data _null_;
if xengine='STREAM' then call symputx('streamweb',1,'l');
run;
%if &contentype=ZIP %then %do;
%if &contentype=CSV %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type','application/zip');
rc=stpsrv_header('Content-type','application/csv');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.zip'
contenttype='application/zip'
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.txt'
contenttype='application/csv'
contentdisp="attachment; filename=&outname";
%end;
%end;
@@ -75,19 +74,10 @@ run;
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %if &contentype=XLSX %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.xls'
contenttype=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
contentdisp="attachment; filename=&outname";
%else %if &contentype=HTML %then %do;
%if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name="_webout.json"
contenttype="text/html";
%end;
%end;
%else %if &contentype=TEXT %then %do;
@@ -103,28 +93,48 @@ run;
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %if &contentype=CSV %then %do;
%else %do;
%put %str(ERR)OR: Content Type &contenttype NOT SUPPORTED by &sysmacroname!;
%return;
%end;
%else %if &contentype=WOFF or &contentype=WOFF2 or &contentype=TTF %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type','application/csv');
rc=stpsrv_header('Content-type',"font/%lowcase(&contenttype)");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
contenttype="font/%lowcase(&contenttype)";
%end;
%end;
%else %if &contentype=XLSX %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.txt'
contenttype='application/csv'
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.xls'
contenttype=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %if &contentype=HTML %then %do;
%if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name="_webout.json"
contenttype="text/html";
%else %if &contentype=ZIP %then %do;
%if &platform=SASMETA and &streamweb=1 %then %do;
data _null_;
rc=stpsrv_header('Content-type','application/zip');
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
run;
%end;
%else %if &platform=SASVIYA %then %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name='_webout.zip'
contenttype='application/zip'
contentdisp="attachment; filename=&outname";
%end;
%end;
%else %do;
%put %str(ERR)OR: Content Type &contenttype NOT SUPPORTED by &sysmacroname!;
%return;
%end;
%if &inref ne 0 %then %do;

View File

@@ -31,12 +31,12 @@
> fmt3=TIME
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -51,11 +51,12 @@
**/
%macro mcf_getfmttype(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(mcf_getfmttype)=1 %then %return;
@@ -103,7 +104,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;

View File

@@ -32,12 +32,12 @@
> outa=3 outb=4 outc=5 outd=0
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -49,12 +49,12 @@
**/
%macro mcf_length(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(mcf_length)=1 %then %return;
%if &wrap=YES %then %do;
@@ -76,7 +76,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;

View File

@@ -47,12 +47,12 @@
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -64,12 +64,12 @@
**/
%macro mcf_stpsrv_header(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(stpsrv_header)=1 %then %return;
%if &wrap=YES %then %do;
@@ -96,7 +96,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;

View File

@@ -32,12 +32,12 @@
run;
@param [out] wrap= (NO) Choose YES to add the proc fcmp wrapper.
@param [out] insert_cmplib= (NO) Choose YES to insert the package into the
CMPLIB reference.
@param [out] lib= (work) The output library in which to create the catalog.
@param [out] cat= (sasjs) The output catalog in which to create the package.
@param [out] pkg= (utils) The output package in which to create the function.
Uses a 3 part format: libref.catalog.package
@param [out] insert_cmplib= DEPRECATED - The CMPLIB option is checked and
values inserted only if needed.
<h4> SAS Macros </h4>
@li mcf_init.sas
@@ -49,12 +49,12 @@
**/
%macro mcf_string2file(wrap=NO
,insert_cmplib=NO
,insert_cmplib=DEPRECATED
,lib=WORK
,cat=SASJS
,pkg=UTILS
)/*/STORE SOURCE*/;
%local i var cmpval found;
%if %mcf_init(mcf_string2file)=1 %then %return;
%if &wrap=YES %then %do;
@@ -81,7 +81,14 @@ endsub;
quit;
%end;
%if &insert_cmplib=YES %then %do;
/* insert the CMPLIB if not already there */
%let cmpval=%sysfunc(getoption(cmplib));
%let found=0;
%do i=1 %to %sysfunc(countw(&cmpval,%str( %(%))));
%let var=%scan(&cmpval,&i,%str( %(%)));
%if &var=&lib..&cat %then %let found=1;
%end;
%if &found=0 %then %do;
options insert=(CMPLIB=(&lib..&cat));
%end;

View File

@@ -59,6 +59,7 @@
"tests/sas9only"
],
"programFolders": [],
"binaryFolders": [],
"deployConfig": {
"deployServicePack": true,
"deployScripts": []

View File

@@ -93,4 +93,74 @@ run;
iftrue=("&test3b"="PASS"),
desc=Checking data row Test 3,
outds=work.test_results
)
)
/* test 4 - sasjs with compare */
filename example temp;
%mp_ds2csv(sashelp.air,outref=example,headerformat=SASJS)
data _null_; infile example; input;put _infile_; if _n_>5 then stop;run;
data _null_;
infile example;
input;
call symputx('stmnt',_infile_);
stop;
run;
data work.want;
infile example dsd firstobs=2;
input &stmnt;
run;
%mp_assert(
iftrue=(&syscc =0),
desc=Checking syscc prior to compare of sashelp.air,
outds=work.test_results
)
proc compare base=want compare=sashelp.air;
run;
%mp_assert(
iftrue=(&sysinfo le 41),
desc=Checking compare of sashelp.air,
outds=work.test_results
)
/* test 5 - sasjs with time/datetime/date */
filename f2 temp;
data work.test5;
do x=1 to 5;
y=x;
z=x;
end;
format x date9. y datetime19. z time.;
run;
%mp_ds2csv(work.test5,outref=f2,headerformat=SASJS)
data _null_; infile example; input;put _infile_; if _n_>5 then stop;run;
data _null_;
infile f2;
input;
putlog _infile_;
call symputx('stmnt2',_infile_);
stop;
run;
data work.want5;
infile f2 dsd firstobs=2;
input &stmnt2;
putlog _infile_;
run;
%mp_assert(
iftrue=(&syscc=0),
desc=Checking syscc prior to compare of test5,
outds=work.test_results
)
proc compare base=want5 compare=work.test5;
run;
%mp_assert(
iftrue=(&sysinfo le 41),
desc=Checking compare of work.test5,
outds=work.test_results
)