mirror of
https://github.com/sasjs/core.git
synced 2026-01-05 00:20:05 +00:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1613ab2c9e | ||
|
|
a2df4e35be | ||
|
|
aabbcfdf6b | ||
|
|
7b7759e1ce | ||
|
|
e5a3053600 | ||
|
|
9856d0ef58 | ||
|
|
77b37e5503 | ||
|
|
793319fe38 | ||
|
|
594a895ddd | ||
|
|
0d59266b8d | ||
|
|
4863aafaa8 | ||
|
|
6015320145 | ||
|
|
8c09c0bce0 | ||
|
|
437943b779 | ||
|
|
6a090e45b6 | ||
|
|
a7dc314204 | ||
|
|
37076eae89 | ||
|
|
9a9f8dc847 | ||
|
|
719b657267 | ||
|
|
671a615501 | ||
|
|
884b45bf12 | ||
|
|
ff6ae1b066 | ||
|
|
d581fec55e | ||
|
|
a5613a79bb | ||
|
|
c6703e16e8 | ||
|
|
6587dce95b | ||
|
|
b60e6448b9 | ||
|
|
46d9b58b32 | ||
|
|
349cbabc94 | ||
|
|
9de056a3fc | ||
|
|
ad497b322f | ||
|
|
7a6408ee44 | ||
|
|
336743f2b4 | ||
|
|
6e32eb3bd6 | ||
|
|
b377b83442 | ||
|
|
899b94bb6e | ||
|
|
d97efdff61 | ||
|
|
1097afbcb8 | ||
|
|
165b2d3568 | ||
|
|
44a80c8985 | ||
|
|
6e32d9b743 | ||
|
|
6b167e7a4c | ||
|
|
011672b1ed | ||
|
|
a7eb926810 | ||
|
|
cad7f13a0e |
@@ -237,6 +237,7 @@ If you find this library useful, please leave a [star](https://github.com/sasjs/
|
|||||||
|
|
||||||
The following repositories are also worth checking out:
|
The following repositories are also worth checking out:
|
||||||
|
|
||||||
|
* [SASJedi/sas-macros](https://github.com/SASJedi/sas-macros)
|
||||||
* [chris-swenson/sasmacros](https://github.com/chris-swenson/sasmacros)
|
* [chris-swenson/sasmacros](https://github.com/chris-swenson/sasmacros)
|
||||||
* [greg-wotton/sas-programs](https://github.com/greg-wootton/sas-programs)
|
* [greg-wotton/sas-programs](https://github.com/greg-wootton/sas-programs)
|
||||||
* [KatjaGlassConsulting/SMILE-SmartSASMacros](https://github.com/KatjaGlassConsulting/SMILE-SmartSASMacros)
|
* [KatjaGlassConsulting/SMILE-SmartSASMacros](https://github.com/KatjaGlassConsulting/SMILE-SmartSASMacros)
|
||||||
|
|||||||
@@ -40,6 +40,11 @@
|
|||||||
%else %if "&SYSVLONG" < "9.04.01M3" %then 0;
|
%else %if "&SYSVLONG" < "9.04.01M3" %then 0;
|
||||||
%else 1;
|
%else 1;
|
||||||
%end;
|
%end;
|
||||||
|
%else %if &feature=DBMS_MEMTYPE %then %do;
|
||||||
|
/* does dbms_memtype exist in dictionary.tables? */
|
||||||
|
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 0;
|
||||||
|
%else 1;
|
||||||
|
%end;
|
||||||
%else %if &feature=EXPORTXLS %then %do;
|
%else %if &feature=EXPORTXLS %then %do;
|
||||||
/* is it possible to PROC EXPORT an excel file? */
|
/* is it possible to PROC EXPORT an excel file? */
|
||||||
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1;
|
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1;
|
||||||
|
|||||||
29
base/mf_increment.sas
Normal file
29
base/mf_increment.sas
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Increments a macro variable
|
||||||
|
@details Useful outside of do-loops - will increment a macro variable every
|
||||||
|
time it is called.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
%let cnt=1;
|
||||||
|
%put We have run %mf_increment(cnt) lines;
|
||||||
|
%put Now we have run %mf_increment(cnt) lines;
|
||||||
|
%put There are %mf_increment(cnt) lines in total;
|
||||||
|
|
||||||
|
@param [in] MACRO_NAME the name of the macro variable to increment
|
||||||
|
@param [in] ITER= The amount to add or subtract to the macro
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mf_increment.test.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mf_increment(macro_name,incr=1);
|
||||||
|
|
||||||
|
/* iterate the value */
|
||||||
|
%let ¯o_name=%eval(&&¯o_name+&incr);
|
||||||
|
/* return the value */
|
||||||
|
&&¯o_name
|
||||||
|
|
||||||
|
%mend mf_increment;
|
||||||
@@ -225,7 +225,7 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
|
|||||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||||
put ",""SYSCC"" : ""&syscc"" ";
|
put ",""SYSCC"" : ""&syscc"" ";
|
||||||
syserrortext=quote(trim(symget('syserrortext')));
|
syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
|
||||||
put ",""SYSERRORTEXT"" : " syserrortext;
|
put ",""SYSERRORTEXT"" : " syserrortext;
|
||||||
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
@@ -233,7 +233,7 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
|
|||||||
put ",""SYSSITE"" : ""&syssite"" ";
|
put ",""SYSSITE"" : ""&syssite"" ";
|
||||||
sysvlong=quote(trim(symget('sysvlong')));
|
sysvlong=quote(trim(symget('sysvlong')));
|
||||||
put ',"SYSVLONG" : ' sysvlong;
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
syswarningtext=quote(trim(symget('syswarningtext')));
|
syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
|
||||||
put ",""SYSWARNINGTEXT"" : " syswarningtext;
|
put ",""SYSWARNINGTEXT"" : " syswarningtext;
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
||||||
put "}" ;
|
put "}" ;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
@param [in] mode (CREATE) Valid values:
|
@param [in] mode (CREATE) Valid values:
|
||||||
@li CREATE - Create the file (even if it already exists)
|
@li CREATE - Create the file (even if it already exists)
|
||||||
@li APPEND - Append to the file (don't overwrite)
|
@li APPEND - Append to the file (don't overwrite)
|
||||||
|
@param iftrue= (1=1) Supply a condition for which the macro should be executed
|
||||||
|
|
||||||
@returns nothing
|
@returns nothing
|
||||||
|
|
||||||
@@ -44,8 +45,12 @@
|
|||||||
,inref=____in /* override default to use own filerefs */
|
,inref=____in /* override default to use own filerefs */
|
||||||
,outref=____out /* override default to use own filerefs */
|
,outref=____out /* override default to use own filerefs */
|
||||||
,mode=CREATE
|
,mode=CREATE
|
||||||
|
,iftrue=%str(1=1)
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local mod;
|
%local mod;
|
||||||
|
|
||||||
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||||
|
|
||||||
%if &mode=APPEND %then %let mod=mod;
|
%if &mode=APPEND %then %let mod=mod;
|
||||||
|
|
||||||
/* these IN and OUT filerefs can point to anything */
|
/* these IN and OUT filerefs can point to anything */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
@file mp_cleancsv.sas
|
@file
|
||||||
@brief Fixes embedded cr / lf / crlf in CSV
|
@brief Fixes embedded cr / lf / crlf in CSV
|
||||||
@details CSVs will sometimes contain lf or crlf within quotes (eg when
|
@details CSVs will sometimes contain lf or crlf within quotes (eg when
|
||||||
saved by excel). When the termstr is ALSO lf or crlf that can be tricky
|
saved by excel). When the termstr is ALSO lf or crlf that can be tricky
|
||||||
@@ -7,14 +7,16 @@
|
|||||||
This macro converts any csv to follow the convention of a windows excel file,
|
This macro converts any csv to follow the convention of a windows excel file,
|
||||||
applying CRLF line endings and converting embedded cr and crlf to lf.
|
applying CRLF line endings and converting embedded cr and crlf to lf.
|
||||||
|
|
||||||
usage:
|
Usage:
|
||||||
|
|
||||||
fileref mycsv "/path/your/csv";
|
fileref mycsv "/path/your/csv";
|
||||||
%mp_cleancsv(in=mycsv,out=/path/new.csv)
|
%mp_cleancsv(in=mycsv,out=/path/new.csv)
|
||||||
|
|
||||||
@param in= provide path or fileref to input csv
|
@param in= (NOTPROVIDED) Provide path or fileref to input csv. If a period is
|
||||||
@param out= output path or fileref to output csv
|
found, it is assumed to be a file.
|
||||||
@param qchar= quote char - hex code 22 is the double quote.
|
@param out= (NOTPROVIDED) Output path or fileref to output csv. If a period
|
||||||
|
is found, it is assumed to be a file.
|
||||||
|
@param qchar= ('22'x) Quote char - hex code 22 is the double quote.
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -56,9 +58,14 @@
|
|||||||
else do;
|
else do;
|
||||||
/* outside a quote, change cr and lf to crlf */
|
/* outside a quote, change cr and lf to crlf */
|
||||||
if inchar='0D'x then do;
|
if inchar='0D'x then do;
|
||||||
|
crblank:
|
||||||
put '0D0A'x;
|
put '0D0A'x;
|
||||||
input inchar $char1.;
|
input inchar $char1.;
|
||||||
if inchar ne '0A'x then do;
|
if inchar='0D'x then do;
|
||||||
|
/* multiple CR indicates CR formatted file with blank lines */
|
||||||
|
goto crblank;
|
||||||
|
end;
|
||||||
|
else if inchar ne '0A'x then do;
|
||||||
put inchar $char1.;
|
put inchar $char1.;
|
||||||
if inchar=qchar then isq = mod(isq+1,2);
|
if inchar=qchar then isq = mod(isq+1,2);
|
||||||
end;
|
end;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_existds.sas
|
@li mf_existds.sas
|
||||||
|
|
||||||
<h4> Related Macros <h4>
|
<h4> Related Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ data &outds;
|
|||||||
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
|
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
|
||||||
OPERATOR_NM $10 RAW_VALUE $4000;*/
|
OPERATOR_NM $10 RAW_VALUE $4000;*/
|
||||||
set &inds;
|
set &inds;
|
||||||
length reason_cd $4032 vtype $1 vnum dsid 8;
|
length reason_cd $4032 vtype $1 vnum dsid 8 tmp $4000;
|
||||||
|
drop tmp;
|
||||||
|
|
||||||
/* quick check to ensure column exists */
|
/* quick check to ensure column exists */
|
||||||
if upcase(VARIABLE_NM) not in
|
if upcase(VARIABLE_NM) not in
|
||||||
@@ -168,18 +169,32 @@ data &outds;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
/* special logic */
|
/* special logic */
|
||||||
if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ','');
|
if OPERATOR_NM in ('IN','NOT IN','BETWEEN') then do;
|
||||||
else if OPERATOR_NM in ('IN','NOT IN') then do;
|
if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',',');
|
||||||
if substr(raw_value,1,1) ne '('
|
else do;
|
||||||
or substr(cats(reverse(raw_value)),1,1) ne ')'
|
if substr(raw_value,1,1) ne '('
|
||||||
then do;
|
or substr(cats(reverse(raw_value)),1,1) ne ')'
|
||||||
REASON_CD='Missing start/end bracket in RAW_VALUE';
|
then do;
|
||||||
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
|
REASON_CD='Missing start/end bracket in RAW_VALUE';
|
||||||
call symputx('reason_cd',reason_cd,'l');
|
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
|
||||||
call symputx('nobs',_n_,'l');
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
output;
|
call symputx('nobs',_n_,'l');
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
|
||||||
|
end;
|
||||||
|
/* we now have a comma seperated list of values */
|
||||||
|
if vtype='N' then do i=1 to countc(raw_value1, ',')+1;
|
||||||
|
tmp=scan(raw_value1,i,',');
|
||||||
|
if cats(tmp) ne '.' and input(tmp, ?? 8.) eq . then do;
|
||||||
|
REASON_CD='Non Numeric value provided';
|
||||||
|
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
return;
|
||||||
end;
|
end;
|
||||||
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
|
|
||||||
end;
|
end;
|
||||||
else raw_value1=raw_value;
|
else raw_value1=raw_value;
|
||||||
|
|
||||||
|
|||||||
@@ -94,8 +94,11 @@ create table &outds as
|
|||||||
/**
|
/**
|
||||||
* We cannot apply this clause to the underlying dictionary table. See:
|
* We cannot apply this clause to the underlying dictionary table. See:
|
||||||
* https://communities.sas.com/t5/SAS-Programming/Unexpected-Where-Clause-behaviour-in-dictionary-TABLE/m-p/771554#M244867
|
* https://communities.sas.com/t5/SAS-Programming/Unexpected-Where-Clause-behaviour-in-dictionary-TABLE/m-p/771554#M244867
|
||||||
|
* cannot use`where calculated libref="&lib"` either as it will STILL execute
|
||||||
|
* all the underlying constraint queries, causing exception errors in some
|
||||||
|
* cases: https://github.com/sasjs/core/issues/283
|
||||||
*/
|
*/
|
||||||
where calculated libref="&lib"
|
where a.TABLE_CATALOG="&lib"
|
||||||
%if "&ds" ne "" %then %do;
|
%if "&ds" ne "" %then %do;
|
||||||
and upcase(a.TABLE_NAME)="&ds"
|
and upcase(a.TABLE_NAME)="&ds"
|
||||||
and upcase(b.TABLE_NAME)="&ds"
|
and upcase(b.TABLE_NAME)="&ds"
|
||||||
|
|||||||
@@ -130,13 +130,13 @@ run;
|
|||||||
|
|
||||||
%local x curds;
|
%local x curds;
|
||||||
%if &flavour=SAS %then %do;
|
%if &flavour=SAS %then %do;
|
||||||
data _null_;
|
|
||||||
file &fref mod;
|
|
||||||
put "/* SAS Flavour DDL for %upcase(&libref).&curds */";
|
|
||||||
put "proc sql;";
|
|
||||||
run;
|
|
||||||
%do x=1 %to %sysfunc(countw(&dsnlist));
|
%do x=1 %to %sysfunc(countw(&dsnlist));
|
||||||
%let curds=%scan(&dsnlist,&x);
|
%let curds=%scan(&dsnlist,&x);
|
||||||
|
data _null_;
|
||||||
|
file &fref mod;
|
||||||
|
put "/* SAS Flavour DDL for %upcase(&libref).&curds */";
|
||||||
|
put "proc sql;";
|
||||||
|
run;
|
||||||
data _null_;
|
data _null_;
|
||||||
file &fref mod;
|
file &fref mod;
|
||||||
length lab $1024 typ $20;
|
length lab $1024 typ $20;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
@param [out] outds= (work.mp_getpk) The name of the output table to create.
|
@param [out] outds= (work.mp_getpk) The name of the output table to create.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_existfeature.sas
|
||||||
@li mf_getengine.sas
|
@li mf_getengine.sas
|
||||||
@li mf_getschema.sas
|
@li mf_getschema.sas
|
||||||
@li mp_dropmembers.sas
|
@li mp_dropmembers.sas
|
||||||
@@ -229,7 +230,12 @@ create table work.&tabs1 as select
|
|||||||
libname as libref
|
libname as libref
|
||||||
,upcase(memname) as dsn
|
,upcase(memname) as dsn
|
||||||
,memtype
|
,memtype
|
||||||
|
%if %mf_existfeature(DBMS_MEMTYPE)=1 %then %do;
|
||||||
,dbms_memtype
|
,dbms_memtype
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
,'n/a' as dbms_memtype format=$32.
|
||||||
|
%end;
|
||||||
,typemem
|
,typemem
|
||||||
,memlabel
|
,memlabel
|
||||||
,nvar
|
,nvar
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
that should be converted to JSON
|
that should be converted to JSON
|
||||||
|
|
||||||
<h4> Related Macros <h4>
|
<h4> Related Files </h4>
|
||||||
@li mp_ds2fmtds.sas
|
@li mp_ds2fmtds.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@@ -70,14 +70,14 @@
|
|||||||
@source https://github.com/sasjs/core
|
@source https://github.com/sasjs/core
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y
|
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y
|
||||||
,engine=DATASTEP
|
,engine=DATASTEP
|
||||||
,missing=NULL
|
,missing=NULL
|
||||||
,showmeta=N
|
,showmeta=N
|
||||||
,maxobs=MAX
|
,maxobs=MAX
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local tempds colinfo fmtds i numcols stmt_obs;
|
%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval
|
||||||
|
tmpds1 tmpds2 tmpds3 tmpds4;
|
||||||
%let numcols=0;
|
%let numcols=0;
|
||||||
%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;);
|
%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;);
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
by varnum;
|
by varnum;
|
||||||
run;
|
run;
|
||||||
/* move meta to mac vars */
|
/* move meta to mac vars */
|
||||||
data _null_;
|
data &colinfo;
|
||||||
if _n_=1 then call symputx('numcols',nobs,'l');
|
if _n_=1 then call symputx('numcols',nobs,'l');
|
||||||
set &colinfo end=last nobs=nobs;
|
set &colinfo end=last nobs=nobs;
|
||||||
name=upcase(name);
|
name=upcase(name);
|
||||||
@@ -126,7 +126,6 @@
|
|||||||
if format='' then fmt=cats('$',length,'.');
|
if format='' then fmt=cats('$',length,'.');
|
||||||
else if formatl=0 then fmt=cats(format,'.');
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
else fmt=cats(format,formatl,'.');
|
else fmt=cats(format,formatl,'.');
|
||||||
newlen=max(formatl,length);
|
|
||||||
end;
|
end;
|
||||||
else do;
|
else do;
|
||||||
typelong='num';
|
typelong='num';
|
||||||
@@ -134,23 +133,26 @@
|
|||||||
else if formatl=0 then fmt=cats(format,'.');
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
else if formatd=0 then fmt=cats(format,formatl,'.');
|
else if formatd=0 then fmt=cats(format,formatl,'.');
|
||||||
else fmt=cats(format,formatl,'.',formatd);
|
else fmt=cats(format,formatl,'.',formatd);
|
||||||
/* needs to be wide, for datetimes etc */
|
|
||||||
newlen=max(length,formatl,24);
|
|
||||||
end;
|
end;
|
||||||
/* 32 char unique name */
|
/* 32 char unique name */
|
||||||
newname='sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
|
newname='sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
|
||||||
|
|
||||||
call symputx(cats('name',_n_),name,'l');
|
call symputx(cats('name',_n_),name,'l');
|
||||||
call symputx(cats('newname',_n_),newname,'l');
|
call symputx(cats('newname',_n_),newname,'l');
|
||||||
call symputx(cats('len',_n_),newlen,'l');
|
|
||||||
call symputx(cats('length',_n_),length,'l');
|
call symputx(cats('length',_n_),length,'l');
|
||||||
call symputx(cats('fmt',_n_),fmt,'l');
|
call symputx(cats('fmt',_n_),fmt,'l');
|
||||||
call symputx(cats('type',_n_),type,'l');
|
call symputx(cats('type',_n_),type,'l');
|
||||||
call symputx(cats('typelong',_n_),typelong,'l');
|
call symputx(cats('typelong',_n_),typelong,'l');
|
||||||
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
||||||
|
/* overwritten when fmt=Y and a custom format exists in catalog */
|
||||||
|
if typelong='num' then call symputx(cats('fmtlen',_n_),200,'l');
|
||||||
|
else call symputx(cats('fmtlen',_n_),min(32767,ceil((length+3)*1.5)),'l');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
|
proc sql;
|
||||||
|
select count(*) into: lastobs from &ds;
|
||||||
|
%if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs));
|
||||||
|
|
||||||
%if &engine=PROCJSON %then %do;
|
%if &engine=PROCJSON %then %do;
|
||||||
%if &missing=STRING %then %do;
|
%if &missing=STRING %then %do;
|
||||||
@@ -187,26 +189,99 @@
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%if &fmt=Y %then %do;
|
%if &fmt=Y %then %do;
|
||||||
data _data_;
|
/**
|
||||||
|
* Extract format definitions
|
||||||
|
* First, by getting library locations from dictionary.formats
|
||||||
|
* Then, by exporting the width using proc format
|
||||||
|
* Cannot use maxw from sashelp.vformat as not always populated
|
||||||
|
* Cannot use fmtinfo() as not supported in all flavours
|
||||||
|
*/
|
||||||
|
%let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
|
%let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
|
%let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
|
%let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
|
proc sql noprint;
|
||||||
|
create table &tmpds1 as
|
||||||
|
select cats(libname,'.',memname) as fmtcat,
|
||||||
|
fmtname
|
||||||
|
from dictionary.formats
|
||||||
|
where fmttype='F' and libname is not null
|
||||||
|
and fmtname in (select format from &colinfo where format is not null)
|
||||||
|
order by 1;
|
||||||
|
create table &tmpds2(
|
||||||
|
FMTNAME char(32),
|
||||||
|
LENGTH num
|
||||||
|
);
|
||||||
|
%local catlist cat fmtlist i;
|
||||||
|
select distinct fmtcat into: catlist separated by ' ' from &tmpds1;
|
||||||
|
%do i=1 %to %sysfunc(countw(&catlist,%str( )));
|
||||||
|
%let cat=%scan(&catlist,&i,%str( ));
|
||||||
|
proc sql;
|
||||||
|
select distinct fmtname into: fmtlist separated by ' '
|
||||||
|
from &tmpds1 where fmtcat="&cat";
|
||||||
|
proc format lib=&cat cntlout=&tmpds3(keep=fmtname length);
|
||||||
|
select &fmtlist;
|
||||||
|
run;
|
||||||
|
proc sql;
|
||||||
|
insert into &tmpds2 select distinct fmtname,length from &tmpds3;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
create table &tmpds4 as
|
||||||
|
select a.*, b.length as maxw
|
||||||
|
from &colinfo a
|
||||||
|
left join &tmpds2 b
|
||||||
|
on cats(a.format)=cats(upcase(b.fmtname))
|
||||||
|
order by a.varnum;
|
||||||
|
data _null_;
|
||||||
|
set &tmpds4;
|
||||||
|
if not missing(maxw);
|
||||||
|
call symputx(
|
||||||
|
cats('fmtlen',_n_),
|
||||||
|
/* vars need extra padding due to JSON escaping of special chars */
|
||||||
|
min(32767,ceil((max(length,maxw)+3)*1.5))
|
||||||
|
,'l'
|
||||||
|
);
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* configure varlenchk - as we are explicitly shortening the variables */
|
||||||
|
%let optval=%sysfunc(getoption(varlenchk));
|
||||||
|
options varlenchk=NOWARN;
|
||||||
|
data _data_(compress=char);
|
||||||
|
/* shorten the new vars */
|
||||||
|
length
|
||||||
|
%do i=1 %to &numcols;
|
||||||
|
&&name&i $&&fmtlen&i
|
||||||
|
%end;
|
||||||
|
;
|
||||||
/* rename on entry */
|
/* rename on entry */
|
||||||
set &ds(rename=(
|
set &ds(rename=(
|
||||||
%do i=1 %to &numcols;
|
%do i=1 %to &numcols;
|
||||||
&&name&i=&&newname&i
|
&&name&i=&&newname&i
|
||||||
%end;
|
%end;
|
||||||
));
|
));
|
||||||
|
&stmt_obs;
|
||||||
|
|
||||||
|
drop
|
||||||
|
%do i=1 %to &numcols;
|
||||||
|
&&newname&i
|
||||||
|
%end;
|
||||||
|
;
|
||||||
%do i=1 %to &numcols;
|
%do i=1 %to &numcols;
|
||||||
length &&name&i $&&len&i;
|
|
||||||
%if &&typelong&i=num %then %do;
|
%if &&typelong&i=num %then %do;
|
||||||
&&name&i=left(put(&&newname&i,&&fmt&i));
|
&&name&i=cats(put(&&newname&i,&&fmt&i));
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
&&name&i=put(&&newname&i,&&fmt&i);
|
&&name&i=put(&&newname&i,&&fmt&i);
|
||||||
%end;
|
%end;
|
||||||
drop &&newname&i;
|
|
||||||
%end;
|
%end;
|
||||||
if _error_ then call symputx('syscc',1012);
|
if _error_ then do;
|
||||||
|
call symputx('syscc',1012);
|
||||||
|
stop;
|
||||||
|
end;
|
||||||
run;
|
run;
|
||||||
%let fmtds=&syslast;
|
%let fmtds=&syslast;
|
||||||
|
options varlenchk=&optval;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
proc format; /* credit yabwon for special null removal */
|
proc format; /* credit yabwon for special null removal */
|
||||||
@@ -225,8 +300,8 @@
|
|||||||
attrib _all_ label='';
|
attrib _all_ label='';
|
||||||
%do i=1 %to &numcols;
|
%do i=1 %to &numcols;
|
||||||
%if &&typelong&i=char or &fmt=Y %then %do;
|
%if &&typelong&i=char or &fmt=Y %then %do;
|
||||||
length &&name&i $32767;
|
length &&name&i $&&fmtlen&i...;
|
||||||
format &&name&i $32767.;
|
format &&name&i $&&fmtlen&i...;
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%if &fmt=Y %then %do;
|
%if &fmt=Y %then %do;
|
||||||
@@ -296,6 +371,7 @@
|
|||||||
filename _sjs4 temp lrecl=131068 encoding='utf-8';
|
filename _sjs4 temp lrecl=131068 encoding='utf-8';
|
||||||
data _null_;
|
data _null_;
|
||||||
file _sjs4;
|
file _sjs4;
|
||||||
|
length label $350;
|
||||||
put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{";
|
put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{";
|
||||||
do i=1 to &numcols;
|
do i=1 to &numcols;
|
||||||
name=quote(trim(symget(cats('name',i))));
|
name=quote(trim(symget(cats('name',i))));
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Logs the time the macro was executed in a control dataset.
|
@brief Logs a message in a dataset every time it is invoked
|
||||||
@details If the dataset does not exist, it is created. Usage:
|
@details If the dataset does not exist, it is created.
|
||||||
|
Usage:
|
||||||
|
|
||||||
%mp_perflog(started)
|
%mp_perflog(started)
|
||||||
%mp_perflog()
|
%mp_perflog()
|
||||||
%mp_perflog(startanew,libds=work.newdataset)
|
%mp_perflog(startanew,libds=work.newdataset)
|
||||||
%mp_perflog(finished,libds=work.newdataset)
|
%mp_perflog(finished,libds=work.newdataset)
|
||||||
%mp_perflog(finished)
|
%mp_perflog(finished)
|
||||||
|
|
||||||
|
|
||||||
@param label Provide label to go into the control dataset
|
@param label Provide label to go into the control dataset
|
||||||
|
|||||||
@@ -154,7 +154,9 @@ run;
|
|||||||
%else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE);
|
%else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE);
|
||||||
|
|
||||||
data &ds4;
|
data &ds4;
|
||||||
length &inds_keep $41 tgtvar_nm $32;
|
length &inds_keep $41 tgtvar_nm $32 _label_ $256;
|
||||||
|
if _n_=1 then call missing(_label_);
|
||||||
|
drop _label_;
|
||||||
set &ds2 &ds3 indsname=&inds_auto;
|
set &ds2 &ds3 indsname=&inds_auto;
|
||||||
|
|
||||||
tgtvar_nm=upcase(tgtvar_nm);
|
tgtvar_nm=upcase(tgtvar_nm);
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ data _null_;
|
|||||||
file sasjs lrecl=3000 ;
|
file sasjs lrecl=3000 ;
|
||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
||||||
put ' ,engine=DATASTEP ';
|
put ' ,engine=DATASTEP ';
|
||||||
put ' ,missing=NULL ';
|
put ' ,missing=NULL ';
|
||||||
put ' ,showmeta=N ';
|
put ' ,showmeta=N ';
|
||||||
put ' ,maxobs=MAX ';
|
put ' ,maxobs=MAX ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%local tempds colinfo fmtds i numcols stmt_obs; ';
|
put '%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval ';
|
||||||
|
put ' tmpds1 tmpds2 tmpds3 tmpds4; ';
|
||||||
put '%let numcols=0; ';
|
put '%let numcols=0; ';
|
||||||
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
|
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
@@ -138,7 +138,7 @@ data _null_;
|
|||||||
put ' by varnum; ';
|
put ' by varnum; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' /* move meta to mac vars */ ';
|
put ' /* move meta to mac vars */ ';
|
||||||
put ' data _null_; ';
|
put ' data &colinfo; ';
|
||||||
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
||||||
put ' set &colinfo end=last nobs=nobs; ';
|
put ' set &colinfo end=last nobs=nobs; ';
|
||||||
put ' name=upcase(name); ';
|
put ' name=upcase(name); ';
|
||||||
@@ -149,7 +149,6 @@ data _null_;
|
|||||||
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
put ' else fmt=cats(format,formatl,''.''); ';
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
put ' newlen=max(formatl,length); ';
|
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else do; ';
|
put ' else do; ';
|
||||||
put ' typelong=''num''; ';
|
put ' typelong=''num''; ';
|
||||||
@@ -157,23 +156,26 @@ data _null_;
|
|||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
put ' /* needs to be wide, for datetimes etc */ ';
|
|
||||||
put ' newlen=max(length,formatl,24); ';
|
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' /* 32 char unique name */ ';
|
put ' /* 32 char unique name */ ';
|
||||||
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
|
||||||
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
||||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' select count(*) into: lastobs from &ds; ';
|
||||||
|
put ' %if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs)); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if &engine=PROCJSON %then %do; ';
|
put ' %if &engine=PROCJSON %then %do; ';
|
||||||
put ' %if &missing=STRING %then %do; ';
|
put ' %if &missing=STRING %then %do; ';
|
||||||
@@ -210,26 +212,99 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
put ' data _data_; ';
|
put ' /** ';
|
||||||
|
put ' * Extract format definitions ';
|
||||||
|
put ' * First, by getting library locations from dictionary.formats ';
|
||||||
|
put ' * Then, by exporting the width using proc format ';
|
||||||
|
put ' * Cannot use maxw from sashelp.vformat as not always populated ';
|
||||||
|
put ' * Cannot use fmtinfo() as not supported in all flavours ';
|
||||||
|
put ' */ ';
|
||||||
|
put ' %let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' proc sql noprint; ';
|
||||||
|
put ' create table &tmpds1 as ';
|
||||||
|
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
||||||
|
put ' fmtname ';
|
||||||
|
put ' from dictionary.formats ';
|
||||||
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
|
put ' order by 1; ';
|
||||||
|
put ' create table &tmpds2( ';
|
||||||
|
put ' FMTNAME char(32), ';
|
||||||
|
put ' LENGTH num ';
|
||||||
|
put ' ); ';
|
||||||
|
put ' %local catlist cat fmtlist i; ';
|
||||||
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
|
put ' %do i=1 %to %sysfunc(countw(&catlist,%str( ))); ';
|
||||||
|
put ' %let cat=%scan(&catlist,&i,%str( )); ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
|
put ' select &fmtlist; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' create table &tmpds4 as ';
|
||||||
|
put ' select a.*, b.length as maxw ';
|
||||||
|
put ' from &colinfo a ';
|
||||||
|
put ' left join &tmpds2 b ';
|
||||||
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
|
put ' order by a.varnum; ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' set &tmpds4; ';
|
||||||
|
put ' if not missing(maxw); ';
|
||||||
|
put ' call symputx( ';
|
||||||
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
|
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
||||||
|
put ' ,''l'' ';
|
||||||
|
put ' ); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
|
put ' /* configure varlenchk - as we are explicitly shortening the variables */ ';
|
||||||
|
put ' %let optval=%sysfunc(getoption(varlenchk)); ';
|
||||||
|
put ' options varlenchk=NOWARN; ';
|
||||||
|
put ' data _data_(compress=char); ';
|
||||||
|
put ' /* shorten the new vars */ ';
|
||||||
|
put ' length ';
|
||||||
|
put ' %do i=1 %to &numcols; ';
|
||||||
|
put ' &&name&i $&&fmtlen&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ; ';
|
||||||
put ' /* rename on entry */ ';
|
put ' /* rename on entry */ ';
|
||||||
put ' set &ds(rename=( ';
|
put ' set &ds(rename=( ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' &&name&i=&&newname&i ';
|
put ' &&name&i=&&newname&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' )); ';
|
put ' )); ';
|
||||||
|
put ' &stmt_obs; ';
|
||||||
|
put ' ';
|
||||||
|
put ' drop ';
|
||||||
|
put ' %do i=1 %to &numcols; ';
|
||||||
|
put ' &&newname&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' length &&name&i $&&len&i; ';
|
|
||||||
put ' %if &&typelong&i=num %then %do; ';
|
put ' %if &&typelong&i=num %then %do; ';
|
||||||
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
put ' &&name&i=cats(put(&&newname&i,&&fmt&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %else %do; ';
|
put ' %else %do; ';
|
||||||
put ' &&name&i=put(&&newname&i,&&fmt&i); ';
|
put ' &&name&i=put(&&newname&i,&&fmt&i); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' drop &&newname&i; ';
|
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' if _error_ then call symputx(''syscc'',1012); ';
|
put ' if _error_ then do; ';
|
||||||
|
put ' call symputx(''syscc'',1012); ';
|
||||||
|
put ' stop; ';
|
||||||
|
put ' end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %let fmtds=&syslast; ';
|
put ' %let fmtds=&syslast; ';
|
||||||
|
put ' options varlenchk=&optval; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc format; /* credit yabwon for special null removal */ ';
|
put ' proc format; /* credit yabwon for special null removal */ ';
|
||||||
@@ -248,8 +323,8 @@ data _null_;
|
|||||||
put ' attrib _all_ label=''''; ';
|
put ' attrib _all_ label=''''; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' length &&name&i $32767; ';
|
put ' length &&name&i $&&fmtlen&i...; ';
|
||||||
put ' format &&name&i $32767.; ';
|
put ' format &&name&i $&&fmtlen&i...; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
@@ -319,6 +394,7 @@ data _null_;
|
|||||||
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
|
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' file _sjs4; ';
|
put ' file _sjs4; ';
|
||||||
|
put ' length label $350; ';
|
||||||
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
||||||
put ' do i=1 to &numcols; ';
|
put ' do i=1 to &numcols; ';
|
||||||
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
||||||
@@ -370,8 +446,8 @@ data _null_;
|
|||||||
put ' %quote(&user) ';
|
put ' %quote(&user) ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
|
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
||||||
put ' ,showmeta=N ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
@@ -438,14 +514,14 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||||
put ' ,engine=&jsonengine,missing=&missing,showmeta=&showmeta ';
|
put ' ,engine=&jsonengine,missing=&missing,showmeta=&showmeta,maxobs=&maxobs ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' /* To avoid issues with _webout on EBI we use a temporary file */ ';
|
put ' /* To avoid issues with _webout on EBI we use a temporary file */ ';
|
||||||
put ' filename _sjsref temp lrecl=131068; ';
|
put ' filename _sjsref temp lrecl=131068; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* if debug mode, send back first 10 records of each work table also */ ';
|
put ' /* if debug mode, send back first XX records of each work table also */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -469,7 +545,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10 ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
|
put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -479,26 +557,33 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' /* close off json */ ';
|
put ' /* close off json */ ';
|
||||||
put ' data _null_;file _sjsref mod encoding=''utf-8''; ';
|
put ' data _null_;file _sjsref mod encoding=''utf-8''; ';
|
||||||
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
put ' length SYSPROCESSNAME syserrortext syswarningtext autoexec $512; ';
|
||||||
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
|
||||||
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
|
||||||
put ' put ",""_DEBUG"" : ""&_debug"" "; ';
|
put ' put ",""_DEBUG"" : ""&_debug"" "; ';
|
||||||
put ' _METAUSER=quote(trim(symget(''_METAUSER''))); ';
|
put ' _METAUSER=quote(trim(symget(''_METAUSER''))); ';
|
||||||
put ' put ",""_METAUSER"": " _METAUSER; ';
|
put ' put ",""_METAUSER"": " _METAUSER; ';
|
||||||
put ' _METAPERSON=quote(trim(symget(''_METAPERSON''))); ';
|
put ' _METAPERSON=quote(trim(symget(''_METAPERSON''))); ';
|
||||||
put ' put '',"_METAPERSON": '' _METAPERSON; ';
|
put ' put '',"_METAPERSON": '' _METAPERSON; ';
|
||||||
|
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
||||||
put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
|
put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
|
||||||
|
put ' autoexec=quote(urlencode(trim(getoption(''autoexec'')))); ';
|
||||||
|
put ' put '',"AUTOEXEC" : '' autoexec; ';
|
||||||
|
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
||||||
put ' put ",""SYSCC"" : ""&syscc"" "; ';
|
put ' put ",""SYSCC"" : ""&syscc"" "; ';
|
||||||
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
|
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
|
||||||
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); ';
|
put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
|
||||||
put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
|
put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
|
||||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||||
|
put ' put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" "; ';
|
||||||
|
put ' put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" "; ';
|
||||||
|
put ' SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME))); ';
|
||||||
|
put ' put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME; ';
|
||||||
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||||
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
|
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
|
||||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||||
|
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
||||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||||
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); ';
|
put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
|
||||||
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
|
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
|
||||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
|
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
|
||||||
put ' length memsize $32; ';
|
put ' length memsize $32; ';
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
@param [in] action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
@param [in] action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
||||||
@param [in] ds The dataset to send back to the frontend
|
@param [in] ds The dataset to send back to the frontend
|
||||||
@param [out] dslabel= Value to use instead of table name for sending to JSON
|
@param [out] dslabel= Value to use instead of table name for sending to JSON
|
||||||
@param [in] fmt=(Y) Set to N to send back unformatted values
|
@param [in] fmt= (N) Setting Y converts all vars to their formatted values
|
||||||
@param [out] fref= (_webout) The fileref to which to write the JSON
|
@param [out] fref= (_webout) The fileref to which to write the JSON
|
||||||
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL
|
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL
|
||||||
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
@@ -34,17 +34,25 @@
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
|
that should be converted to output JSON
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li ms_webout.sas
|
||||||
|
@li mv_webout.sas
|
||||||
|
|
||||||
@version 9.3
|
@version 9.3
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
|
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
||||||
,showmeta=N
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
@@ -111,14 +119,14 @@
|
|||||||
|
|
||||||
%else %if &action=ARR or &action=OBJ %then %do;
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
,engine=&jsonengine,missing=&missing,showmeta=&showmeta
|
,engine=&jsonengine,missing=&missing,showmeta=&showmeta,maxobs=&maxobs
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
/* To avoid issues with _webout on EBI we use a temporary file */
|
/* To avoid issues with _webout on EBI we use a temporary file */
|
||||||
filename _sjsref temp lrecl=131068;
|
filename _sjsref temp lrecl=131068;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* if debug mode, send back first 10 records of each work table also */
|
/* if debug mode, send back first XX records of each work table also */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -142,7 +150,9 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file _sjsref mod encoding='utf-8';
|
data _null_; file _sjsref mod encoding='utf-8';
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
@@ -152,26 +162,33 @@
|
|||||||
%end;
|
%end;
|
||||||
/* close off json */
|
/* close off json */
|
||||||
data _null_;file _sjsref mod encoding='utf-8';
|
data _null_;file _sjsref mod encoding='utf-8';
|
||||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
length SYSPROCESSNAME syserrortext syswarningtext autoexec $512;
|
||||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
|
||||||
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
|
||||||
put ",""_DEBUG"" : ""&_debug"" ";
|
put ",""_DEBUG"" : ""&_debug"" ";
|
||||||
_METAUSER=quote(trim(symget('_METAUSER')));
|
_METAUSER=quote(trim(symget('_METAUSER')));
|
||||||
put ",""_METAUSER"": " _METAUSER;
|
put ",""_METAUSER"": " _METAUSER;
|
||||||
_METAPERSON=quote(trim(symget('_METAPERSON')));
|
_METAPERSON=quote(trim(symget('_METAPERSON')));
|
||||||
put ',"_METAPERSON": ' _METAPERSON;
|
put ',"_METAPERSON": ' _METAPERSON;
|
||||||
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||||
|
autoexec=quote(urlencode(trim(getoption('autoexec'))));
|
||||||
|
put ',"AUTOEXEC" : ' autoexec;
|
||||||
|
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
||||||
put ",""SYSCC"" : ""&syscc"" ";
|
put ",""SYSCC"" : ""&syscc"" ";
|
||||||
put ",""SYSENCODING"" : ""&sysencoding"" ";
|
put ",""SYSENCODING"" : ""&sysencoding"" ";
|
||||||
syserrortext=quote(cats(symget('SYSERRORTEXT')));
|
syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
|
||||||
put ',"SYSERRORTEXT" : ' syserrortext;
|
put ',"SYSERRORTEXT" : ' syserrortext;
|
||||||
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||||
|
put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
|
||||||
|
put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
|
||||||
|
SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME)));
|
||||||
|
put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME;
|
||||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
||||||
put ",""SYSSITE"" : ""&syssite"" ";
|
put ",""SYSSITE"" : ""&syssite"" ";
|
||||||
|
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||||
sysvlong=quote(trim(symget('sysvlong')));
|
sysvlong=quote(trim(symget('sysvlong')));
|
||||||
put ',"SYSVLONG" : ' sysvlong;
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
syswarningtext=quote(cats(symget('SYSWARNINGTEXT')));
|
syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
|
||||||
put ',"SYSWARNINGTEXT" : ' syswarningtext;
|
put ',"SYSWARNINGTEXT" : ' syswarningtext;
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
||||||
length memsize $32;
|
length memsize $32;
|
||||||
|
|||||||
50
metax/mmx_createmetafolder.sas
Normal file
50
metax/mmx_createmetafolder.sas
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Creates a metadata folder
|
||||||
|
@details Creates a metadata folder using the batch tools
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%mmx_createmetafolder(loc=/some/meta/folder,user=sasdemo,pass=mars345)
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_loc.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
@param loc= the metadata folder to delete
|
||||||
|
@param user= username
|
||||||
|
@param pass= password
|
||||||
|
|
||||||
|
@version 9.4
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mmx_createmetafolder(loc=,user=,pass=);
|
||||||
|
|
||||||
|
%local host port path connx_string msg;
|
||||||
|
%let host=%sysfunc(getoption(metaserver));
|
||||||
|
%let port=%sysfunc(getoption(metaport));
|
||||||
|
%let path=%mf_loc(POF)/tools;
|
||||||
|
|
||||||
|
%let connx_string= -host &host -port &port -user '&user' -password '&pass';
|
||||||
|
/* remove directory */
|
||||||
|
data _null_;
|
||||||
|
infile " &path/sas-make-folder &connx_string ""&loc"" -makeFullPath 2>&1"
|
||||||
|
pipe lrecl=10000;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
data _null_; /* check tree exists */
|
||||||
|
length type uri $256;
|
||||||
|
rc=metadata_pathobj("","&loc","Folder",type,uri);
|
||||||
|
call symputx('foldertype',type,'l');
|
||||||
|
run;
|
||||||
|
%let msg=Location (&loc) was not created!!;
|
||||||
|
%mp_abort(iftrue= (&foldertype ne Tree)
|
||||||
|
,mac=&_program..sas
|
||||||
|
,msg=%superq(msg)
|
||||||
|
)
|
||||||
|
|
||||||
|
%mend mmx_createmetafolder;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
%mmx_deletemetafolder(loc=/some/meta/folder,user=sasdemo,pass=mars345)
|
%mmx_deletemetafolder(loc=/some/meta/folder,user=sasdemo,pass=mars345)
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_loc.sas
|
@li mf_loc.sas
|
||||||
@@ -37,4 +37,4 @@ data _null_;
|
|||||||
putlog _infile_;
|
putlog _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend mmx_deletemetafolder;
|
%mend mmx_deletemetafolder;
|
||||||
|
|||||||
@@ -25,6 +25,21 @@
|
|||||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||||
<link rel="shortcut icon" href="$relpath^favicon.ico" type="image/x-icon" />
|
<link rel="shortcut icon" href="$relpath^favicon.ico" type="image/x-icon" />
|
||||||
$extrastylesheet
|
$extrastylesheet
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script>
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function () {
|
||||||
|
var u = "https://analytics.4gl.io/";
|
||||||
|
_paq.push(['setTrackerUrl', u + 'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '6']);
|
||||||
|
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||||
|
g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -68,4 +83,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "server",
|
"name": "server",
|
||||||
"serverUrl": "",
|
"serverUrl": "https://sas.4gl.io",
|
||||||
"serverType": "SASJS",
|
"serverType": "SASJS",
|
||||||
"httpsAgentOptions": {
|
"httpsAgentOptions": {
|
||||||
"allowInsecureRequests": false
|
"allowInsecureRequests": false
|
||||||
@@ -107,4 +107,4 @@
|
|||||||
"contextName": "SAS Job Execution compute context"
|
"contextName": "SAS Job Execution compute context"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -94,14 +94,14 @@ data _null_;
|
|||||||
file &sasjsref termstr=crlf lrecl=512;
|
file &sasjsref termstr=crlf lrecl=512;
|
||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
||||||
put ' ,engine=DATASTEP ';
|
put ' ,engine=DATASTEP ';
|
||||||
put ' ,missing=NULL ';
|
put ' ,missing=NULL ';
|
||||||
put ' ,showmeta=N ';
|
put ' ,showmeta=N ';
|
||||||
put ' ,maxobs=MAX ';
|
put ' ,maxobs=MAX ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%local tempds colinfo fmtds i numcols stmt_obs; ';
|
put '%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval ';
|
||||||
|
put ' tmpds1 tmpds2 tmpds3 tmpds4; ';
|
||||||
put '%let numcols=0; ';
|
put '%let numcols=0; ';
|
||||||
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
|
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
@@ -139,7 +139,7 @@ data _null_;
|
|||||||
put ' by varnum; ';
|
put ' by varnum; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' /* move meta to mac vars */ ';
|
put ' /* move meta to mac vars */ ';
|
||||||
put ' data _null_; ';
|
put ' data &colinfo; ';
|
||||||
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
||||||
put ' set &colinfo end=last nobs=nobs; ';
|
put ' set &colinfo end=last nobs=nobs; ';
|
||||||
put ' name=upcase(name); ';
|
put ' name=upcase(name); ';
|
||||||
@@ -150,7 +150,6 @@ data _null_;
|
|||||||
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
put ' else fmt=cats(format,formatl,''.''); ';
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
put ' newlen=max(formatl,length); ';
|
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else do; ';
|
put ' else do; ';
|
||||||
put ' typelong=''num''; ';
|
put ' typelong=''num''; ';
|
||||||
@@ -158,23 +157,26 @@ data _null_;
|
|||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
put ' /* needs to be wide, for datetimes etc */ ';
|
|
||||||
put ' newlen=max(length,formatl,24); ';
|
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' /* 32 char unique name */ ';
|
put ' /* 32 char unique name */ ';
|
||||||
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
|
||||||
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
||||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' select count(*) into: lastobs from &ds; ';
|
||||||
|
put ' %if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs)); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if &engine=PROCJSON %then %do; ';
|
put ' %if &engine=PROCJSON %then %do; ';
|
||||||
put ' %if &missing=STRING %then %do; ';
|
put ' %if &missing=STRING %then %do; ';
|
||||||
@@ -211,26 +213,99 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
put ' data _data_; ';
|
put ' /** ';
|
||||||
|
put ' * Extract format definitions ';
|
||||||
|
put ' * First, by getting library locations from dictionary.formats ';
|
||||||
|
put ' * Then, by exporting the width using proc format ';
|
||||||
|
put ' * Cannot use maxw from sashelp.vformat as not always populated ';
|
||||||
|
put ' * Cannot use fmtinfo() as not supported in all flavours ';
|
||||||
|
put ' */ ';
|
||||||
|
put ' %let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' proc sql noprint; ';
|
||||||
|
put ' create table &tmpds1 as ';
|
||||||
|
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
||||||
|
put ' fmtname ';
|
||||||
|
put ' from dictionary.formats ';
|
||||||
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
|
put ' order by 1; ';
|
||||||
|
put ' create table &tmpds2( ';
|
||||||
|
put ' FMTNAME char(32), ';
|
||||||
|
put ' LENGTH num ';
|
||||||
|
put ' ); ';
|
||||||
|
put ' %local catlist cat fmtlist i; ';
|
||||||
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
|
put ' %do i=1 %to %sysfunc(countw(&catlist,%str( ))); ';
|
||||||
|
put ' %let cat=%scan(&catlist,&i,%str( )); ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
|
put ' select &fmtlist; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' create table &tmpds4 as ';
|
||||||
|
put ' select a.*, b.length as maxw ';
|
||||||
|
put ' from &colinfo a ';
|
||||||
|
put ' left join &tmpds2 b ';
|
||||||
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
|
put ' order by a.varnum; ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' set &tmpds4; ';
|
||||||
|
put ' if not missing(maxw); ';
|
||||||
|
put ' call symputx( ';
|
||||||
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
|
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
||||||
|
put ' ,''l'' ';
|
||||||
|
put ' ); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
|
put ' /* configure varlenchk - as we are explicitly shortening the variables */ ';
|
||||||
|
put ' %let optval=%sysfunc(getoption(varlenchk)); ';
|
||||||
|
put ' options varlenchk=NOWARN; ';
|
||||||
|
put ' data _data_(compress=char); ';
|
||||||
|
put ' /* shorten the new vars */ ';
|
||||||
|
put ' length ';
|
||||||
|
put ' %do i=1 %to &numcols; ';
|
||||||
|
put ' &&name&i $&&fmtlen&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ; ';
|
||||||
put ' /* rename on entry */ ';
|
put ' /* rename on entry */ ';
|
||||||
put ' set &ds(rename=( ';
|
put ' set &ds(rename=( ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' &&name&i=&&newname&i ';
|
put ' &&name&i=&&newname&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' )); ';
|
put ' )); ';
|
||||||
|
put ' &stmt_obs; ';
|
||||||
|
put ' ';
|
||||||
|
put ' drop ';
|
||||||
|
put ' %do i=1 %to &numcols; ';
|
||||||
|
put ' &&newname&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' length &&name&i $&&len&i; ';
|
|
||||||
put ' %if &&typelong&i=num %then %do; ';
|
put ' %if &&typelong&i=num %then %do; ';
|
||||||
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
put ' &&name&i=cats(put(&&newname&i,&&fmt&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %else %do; ';
|
put ' %else %do; ';
|
||||||
put ' &&name&i=put(&&newname&i,&&fmt&i); ';
|
put ' &&name&i=put(&&newname&i,&&fmt&i); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' drop &&newname&i; ';
|
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' if _error_ then call symputx(''syscc'',1012); ';
|
put ' if _error_ then do; ';
|
||||||
|
put ' call symputx(''syscc'',1012); ';
|
||||||
|
put ' stop; ';
|
||||||
|
put ' end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %let fmtds=&syslast; ';
|
put ' %let fmtds=&syslast; ';
|
||||||
|
put ' options varlenchk=&optval; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc format; /* credit yabwon for special null removal */ ';
|
put ' proc format; /* credit yabwon for special null removal */ ';
|
||||||
@@ -249,8 +324,8 @@ data _null_;
|
|||||||
put ' attrib _all_ label=''''; ';
|
put ' attrib _all_ label=''''; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' length &&name&i $32767; ';
|
put ' length &&name&i $&&fmtlen&i...; ';
|
||||||
put ' format &&name&i $32767.; ';
|
put ' format &&name&i $&&fmtlen&i...; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
@@ -320,6 +395,7 @@ data _null_;
|
|||||||
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
|
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' file _sjs4; ';
|
put ' file _sjs4; ';
|
||||||
|
put ' length label $350; ';
|
||||||
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
||||||
put ' do i=1 to &numcols; ';
|
put ' do i=1 to &numcols; ';
|
||||||
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
||||||
@@ -372,8 +448,8 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
|
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
|
||||||
put ' ,showmeta=N ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
@@ -432,12 +508,12 @@ data _null_;
|
|||||||
put ' %let missing=NULL; ';
|
put ' %let missing=NULL; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||||
put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta ';
|
put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta,maxobs=&maxobs ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* if debug mode, send back first 10 records of each work table also */ ';
|
put ' /* if debug mode, send back first XX records of each work table also */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -462,7 +538,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10 ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -472,35 +550,34 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' /* close off json */ ';
|
put ' /* close off json */ ';
|
||||||
put ' data _null_;file &fref mod encoding=''utf-8'' termstr=lf lrecl=32767; ';
|
put ' data _null_;file &fref mod encoding=''utf-8'' termstr=lf lrecl=32767; ';
|
||||||
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
put ' length SYSPROCESSNAME syserrortext syswarningtext autoexec $512; ';
|
||||||
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
|
||||||
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
|
||||||
put ' put ",""_DEBUG"" : ""&_debug"" "; ';
|
put ' put ",""_DEBUG"" : ""&_debug"" "; ';
|
||||||
|
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
||||||
put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
|
put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
|
||||||
|
put ' autoexec=quote(urlencode(trim(getoption(''autoexec'')))); ';
|
||||||
|
put ' put '',"AUTOEXEC" : '' autoexec; ';
|
||||||
|
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
||||||
put ' put ",""SYSCC"" : ""&syscc"" "; ';
|
put ' put ",""SYSCC"" : ""&syscc"" "; ';
|
||||||
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
|
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
|
||||||
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); ';
|
put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
|
||||||
put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
|
put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
|
||||||
put ' SYSHOSTINFOLONG=quote(trim(symget(''SYSHOSTINFOLONG''))); ';
|
put ' SYSHOSTINFOLONG=quote(trim(symget(''SYSHOSTINFOLONG''))); ';
|
||||||
put ' put '',"SYSHOSTINFOLONG" : '' SYSHOSTINFOLONG; ';
|
put ' put '',"SYSHOSTINFOLONG" : '' SYSHOSTINFOLONG; ';
|
||||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||||
put ' put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" "; ';
|
put ' put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" "; ';
|
||||||
put ' put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" "; ';
|
put ' put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" "; ';
|
||||||
put ' length SYSPROCESSNAME $512; ';
|
|
||||||
put ' SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME))); ';
|
put ' SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME))); ';
|
||||||
put ' put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME; ';
|
put ' put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME; ';
|
||||||
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||||
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
|
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
|
||||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||||
put ' put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; ';
|
put ' put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; ';
|
||||||
|
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
||||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||||
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); ';
|
put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
|
||||||
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
|
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
|
||||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
|
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
|
||||||
put ' length autoexec $512; ';
|
|
||||||
put ' autoexec=quote(urlencode(trim(getoption(''autoexec'')))); ';
|
|
||||||
put ' put '',"AUTOEXEC" : '' autoexec; ';
|
|
||||||
put ' length memsize $32; ';
|
put ' length memsize $32; ';
|
||||||
put ' memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)"; ';
|
put ' memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)"; ';
|
||||||
put ' memsize=quote(cats(memsize)); ';
|
put ' memsize=quote(cats(memsize)); ';
|
||||||
|
|||||||
@@ -116,14 +116,16 @@ libname &libref JSON fileref=&fref1;
|
|||||||
%if "&group"="0" and "&gid"="0" %then %do;
|
%if "&group"="0" and "&gid"="0" %then %do;
|
||||||
data &outds;
|
data &outds;
|
||||||
length DISPLAYNAME $60 USERNAME:$30 ID 8;
|
length DISPLAYNAME $60 USERNAME:$30 ID 8;
|
||||||
set &libref..root;
|
if nobs=0 then call missing(of _all_);
|
||||||
|
set &libref..root nobs=nobs;
|
||||||
drop ordinal_root;
|
drop ordinal_root;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
data &outds;
|
data &outds;
|
||||||
length DISPLAYNAME $60 USERNAME:$30 ID 8;
|
length DISPLAYNAME $60 USERNAME:$30 ID 8;
|
||||||
set &libref..users;
|
if nobs=0 then call missing(of _all_);
|
||||||
|
set &libref..users nobs=nobs;
|
||||||
drop ordinal_root ordinal_users;
|
drop ordinal_root ordinal_users;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
@param [in] action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
@param [in] action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
||||||
@param [in] ds The dataset to send back to the frontend
|
@param [in] ds The dataset to send back to the frontend
|
||||||
@param [out] dslabel= value to use instead of table name for sending to JSON
|
@param [out] dslabel= value to use instead of table name for sending to JSON
|
||||||
@param [in] fmt= (Y) Set to N to send back unformatted values
|
@param [in] fmt= (N) Setting Y converts all vars to their formatted values
|
||||||
@param [out] fref= (_webout) The fileref to which to write the JSON
|
@param [out] fref= (_webout) The fileref to which to write the JSON
|
||||||
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL
|
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL
|
||||||
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
@@ -31,6 +31,11 @@
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
|
that should be converted to output JSON
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getuser.sas
|
@li mf_getuser.sas
|
||||||
@@ -46,8 +51,8 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
|
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL
|
||||||
,showmeta=N
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
@@ -106,12 +111,12 @@
|
|||||||
%let missing=NULL;
|
%let missing=NULL;
|
||||||
%end;
|
%end;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
,engine=DATASTEP,missing=&missing,showmeta=&showmeta
|
,engine=DATASTEP,missing=&missing,showmeta=&showmeta,maxobs=&maxobs
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* if debug mode, send back first 10 records of each work table also */
|
/* if debug mode, send back first XX records of each work table also */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -136,7 +141,9 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
@@ -146,35 +153,34 @@
|
|||||||
%end;
|
%end;
|
||||||
/* close off json */
|
/* close off json */
|
||||||
data _null_;file &fref mod encoding='utf-8' termstr=lf lrecl=32767;
|
data _null_;file &fref mod encoding='utf-8' termstr=lf lrecl=32767;
|
||||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
length SYSPROCESSNAME syserrortext syswarningtext autoexec $512;
|
||||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
|
||||||
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
|
||||||
put ",""_DEBUG"" : ""&_debug"" ";
|
put ",""_DEBUG"" : ""&_debug"" ";
|
||||||
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||||
|
autoexec=quote(urlencode(trim(getoption('autoexec'))));
|
||||||
|
put ',"AUTOEXEC" : ' autoexec;
|
||||||
|
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
||||||
put ",""SYSCC"" : ""&syscc"" ";
|
put ",""SYSCC"" : ""&syscc"" ";
|
||||||
put ",""SYSENCODING"" : ""&sysencoding"" ";
|
put ",""SYSENCODING"" : ""&sysencoding"" ";
|
||||||
syserrortext=quote(cats(symget('SYSERRORTEXT')));
|
syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
|
||||||
put ',"SYSERRORTEXT" : ' syserrortext;
|
put ',"SYSERRORTEXT" : ' syserrortext;
|
||||||
SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG')));
|
SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG')));
|
||||||
put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG;
|
put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG;
|
||||||
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||||
put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
|
put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
|
||||||
put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
|
put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
|
||||||
length SYSPROCESSNAME $512;
|
|
||||||
SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME)));
|
SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME)));
|
||||||
put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME;
|
put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME;
|
||||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
||||||
put ",""SYSSITE"" : ""&syssite"" ";
|
put ",""SYSSITE"" : ""&syssite"" ";
|
||||||
put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" ";
|
put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" ";
|
||||||
|
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||||
sysvlong=quote(trim(symget('sysvlong')));
|
sysvlong=quote(trim(symget('sysvlong')));
|
||||||
put ',"SYSVLONG" : ' sysvlong;
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
syswarningtext=quote(cats(symget('SYSWARNINGTEXT')));
|
syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
|
||||||
put ',"SYSWARNINGTEXT" : ' syswarningtext;
|
put ',"SYSWARNINGTEXT" : ' syswarningtext;
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
||||||
length autoexec $512;
|
|
||||||
autoexec=quote(urlencode(trim(getoption('autoexec'))));
|
|
||||||
put ',"AUTOEXEC" : ' autoexec;
|
|
||||||
length memsize $32;
|
length memsize $32;
|
||||||
memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)";
|
memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)";
|
||||||
memsize=quote(cats(memsize));
|
memsize=quote(cats(memsize));
|
||||||
|
|||||||
35
tests/base/mf_increment.test.sas
Normal file
35
tests/base/mf_increment.test.sas
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mf_increment macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_increment.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%let var=0;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(
|
||||||
|
"%mf_increment(var)"="1"
|
||||||
|
),
|
||||||
|
desc=Checking basic mf_increment usage 1,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(
|
||||||
|
"%mf_increment(var)"="2"
|
||||||
|
),
|
||||||
|
desc=Checking basic mf_increment usage 2,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(
|
||||||
|
"%mf_increment(var,incr=2)"="4"
|
||||||
|
),
|
||||||
|
desc=Checking incr option,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
43
tests/base/mp_cleancsv.test.sas
Normal file
43
tests/base/mp_cleancsv.test.sas
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_cleancsv.sas macro
|
||||||
|
@details Credit for test 1 goes to
|
||||||
|
[Tom](https://communities.sas.com/t5/user/viewprofilepage/user-id/159) from
|
||||||
|
SAS Communities:
|
||||||
|
https://communities.sas.com/t5/SAS-Programming/Removing-embedded-carriage-returns/m-p/824790#M325761
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_nobs.sas
|
||||||
|
@li mp_cleancsv.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* test 1 - cope with empty rows on CR formatted file */
|
||||||
|
|
||||||
|
filename crlf "%sysfunc(pathname(work))/crlf";
|
||||||
|
filename cr "%sysfunc(pathname(work))/cr";
|
||||||
|
data _null_;
|
||||||
|
file cr termstr=cr ;
|
||||||
|
put 'line 1'///'line 4'/'line 5';
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mp_cleancsv(in=cr,out=crlf)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
/* 5 rows as all converted to OD0A */
|
||||||
|
data test1;
|
||||||
|
infile "%sysfunc(pathname(work))/crlf" lrecl=100 termstr=crlf;
|
||||||
|
input;
|
||||||
|
list;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%put test1=%mf_nobs(test1);
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_nobs(work.test1)=5),
|
||||||
|
desc=Checking blank rows on CR formatted file,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -38,7 +38,7 @@ William,M,15,66.5,112
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
/* valid filter conditions */
|
/* VALID filter conditions */
|
||||||
data work.inds;
|
data work.inds;
|
||||||
infile datalines4 dsd;
|
infile datalines4 dsd;
|
||||||
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
||||||
@@ -51,6 +51,9 @@ AND,OR,2,Weight,>=,77.7
|
|||||||
AND,OR,2,Weight,NE,77.7
|
AND,OR,2,Weight,NE,77.7
|
||||||
AND,AND,1,age,=,.A
|
AND,AND,1,age,=,.A
|
||||||
AND,AND,1,height,<,.B
|
AND,AND,1,height,<,.B
|
||||||
|
AND,AND,1,age,IN,"(.a,.b,.)"
|
||||||
|
AND,AND,1,age,IN,"(.A)"
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
@@ -115,6 +118,28 @@ run;
|
|||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* invalid IN value */
|
||||||
|
data work.inds;
|
||||||
|
infile datalines4 dsd;
|
||||||
|
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
||||||
|
OPERATOR_NM:$10. RAW_VALUE:$4000.;
|
||||||
|
datalines4;
|
||||||
|
AND,OR,2,age,IN,"(.,.a,X)"
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_filtercheck(work.inds,
|
||||||
|
targetds=work.class,
|
||||||
|
outds=work.badrecords,
|
||||||
|
abort=NO
|
||||||
|
)
|
||||||
|
%let syscc=0;
|
||||||
|
%mp_assertdsobs(work.badrecords,
|
||||||
|
desc=Invalid IN value,
|
||||||
|
test=HASOBS,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
/* Code injection - column name */
|
/* Code injection - column name */
|
||||||
data work.inds;
|
data work.inds;
|
||||||
infile datalines4 dsd;
|
infile datalines4 dsd;
|
||||||
@@ -163,7 +188,7 @@ run;
|
|||||||
data work.inds;
|
data work.inds;
|
||||||
infile datalines4 dsd;
|
infile datalines4 dsd;
|
||||||
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
||||||
OPERATOR_NM:$10. RAW_VALUE:8;
|
OPERATOR_NM:$10. RAW_VALUE:8.;
|
||||||
datalines4;
|
datalines4;
|
||||||
AND,AND,1,age,=,0
|
AND,AND,1,age,=,0
|
||||||
;;;;
|
;;;;
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ AND,AND,1,SEX,<=,"'M'"
|
|||||||
AND,OR,2,Name,NOT IN,"('Jane','Alfred')"
|
AND,OR,2,Name,NOT IN,"('Jane','Alfred')"
|
||||||
AND,OR,2,Weight,>=,77.7
|
AND,OR,2,Weight,>=,77.7
|
||||||
AND,OR,2,Weight,NE,77.7
|
AND,OR,2,Weight,NE,77.7
|
||||||
|
AND,AND,3,age,NOT IN,"(.a,.b,.)"
|
||||||
|
AND,AND,3,age,NOT IN,"(.A)"
|
||||||
|
AND,AND,4,Name,=,"'Jeremiah'"
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
|||||||
@@ -236,14 +236,14 @@ data _null_;
|
|||||||
file &adapter;
|
file &adapter;
|
||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
||||||
put ' ,engine=DATASTEP ';
|
put ' ,engine=DATASTEP ';
|
||||||
put ' ,missing=NULL ';
|
put ' ,missing=NULL ';
|
||||||
put ' ,showmeta=N ';
|
put ' ,showmeta=N ';
|
||||||
put ' ,maxobs=MAX ';
|
put ' ,maxobs=MAX ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%local tempds colinfo fmtds i numcols stmt_obs; ';
|
put '%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval ';
|
||||||
|
put ' tmpds1 tmpds2 tmpds3 tmpds4; ';
|
||||||
put '%let numcols=0; ';
|
put '%let numcols=0; ';
|
||||||
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
|
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
@@ -281,7 +281,7 @@ data _null_;
|
|||||||
put ' by varnum; ';
|
put ' by varnum; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' /* move meta to mac vars */ ';
|
put ' /* move meta to mac vars */ ';
|
||||||
put ' data _null_; ';
|
put ' data &colinfo; ';
|
||||||
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
||||||
put ' set &colinfo end=last nobs=nobs; ';
|
put ' set &colinfo end=last nobs=nobs; ';
|
||||||
put ' name=upcase(name); ';
|
put ' name=upcase(name); ';
|
||||||
@@ -292,7 +292,6 @@ data _null_;
|
|||||||
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
put ' else fmt=cats(format,formatl,''.''); ';
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
put ' newlen=max(formatl,length); ';
|
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' else do; ';
|
put ' else do; ';
|
||||||
put ' typelong=''num''; ';
|
put ' typelong=''num''; ';
|
||||||
@@ -300,23 +299,26 @@ data _null_;
|
|||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
put ' /* needs to be wide, for datetimes etc */ ';
|
|
||||||
put ' newlen=max(length,formatl,24); ';
|
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' /* 32 char unique name */ ';
|
put ' /* 32 char unique name */ ';
|
||||||
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
|
||||||
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
||||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
||||||
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
|
put ' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
|
||||||
|
put ' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
|
||||||
|
put ' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+3)*1.5)),''l''); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' select count(*) into: lastobs from &ds; ';
|
||||||
|
put ' %if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs)); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if &engine=PROCJSON %then %do; ';
|
put ' %if &engine=PROCJSON %then %do; ';
|
||||||
put ' %if &missing=STRING %then %do; ';
|
put ' %if &missing=STRING %then %do; ';
|
||||||
@@ -353,26 +355,99 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
put ' data _data_; ';
|
put ' /** ';
|
||||||
|
put ' * Extract format definitions ';
|
||||||
|
put ' * First, by getting library locations from dictionary.formats ';
|
||||||
|
put ' * Then, by exporting the width using proc format ';
|
||||||
|
put ' * Cannot use maxw from sashelp.vformat as not always populated ';
|
||||||
|
put ' * Cannot use fmtinfo() as not supported in all flavours ';
|
||||||
|
put ' */ ';
|
||||||
|
put ' %let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' proc sql noprint; ';
|
||||||
|
put ' create table &tmpds1 as ';
|
||||||
|
put ' select cats(libname,''.'',memname) as fmtcat, ';
|
||||||
|
put ' fmtname ';
|
||||||
|
put ' from dictionary.formats ';
|
||||||
|
put ' where fmttype=''F'' and libname is not null ';
|
||||||
|
put ' and fmtname in (select format from &colinfo where format is not null) ';
|
||||||
|
put ' order by 1; ';
|
||||||
|
put ' create table &tmpds2( ';
|
||||||
|
put ' FMTNAME char(32), ';
|
||||||
|
put ' LENGTH num ';
|
||||||
|
put ' ); ';
|
||||||
|
put ' %local catlist cat fmtlist i; ';
|
||||||
|
put ' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
|
||||||
|
put ' %do i=1 %to %sysfunc(countw(&catlist,%str( ))); ';
|
||||||
|
put ' %let cat=%scan(&catlist,&i,%str( )); ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' select distinct fmtname into: fmtlist separated by '' '' ';
|
||||||
|
put ' from &tmpds1 where fmtcat="&cat"; ';
|
||||||
|
put ' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
|
||||||
|
put ' select &fmtlist; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' create table &tmpds4 as ';
|
||||||
|
put ' select a.*, b.length as maxw ';
|
||||||
|
put ' from &colinfo a ';
|
||||||
|
put ' left join &tmpds2 b ';
|
||||||
|
put ' on cats(a.format)=cats(upcase(b.fmtname)) ';
|
||||||
|
put ' order by a.varnum; ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' set &tmpds4; ';
|
||||||
|
put ' if not missing(maxw); ';
|
||||||
|
put ' call symputx( ';
|
||||||
|
put ' cats(''fmtlen'',_n_), ';
|
||||||
|
put ' /* vars need extra padding due to JSON escaping of special chars */ ';
|
||||||
|
put ' min(32767,ceil((max(length,maxw)+3)*1.5)) ';
|
||||||
|
put ' ,''l'' ';
|
||||||
|
put ' ); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
|
put ' /* configure varlenchk - as we are explicitly shortening the variables */ ';
|
||||||
|
put ' %let optval=%sysfunc(getoption(varlenchk)); ';
|
||||||
|
put ' options varlenchk=NOWARN; ';
|
||||||
|
put ' data _data_(compress=char); ';
|
||||||
|
put ' /* shorten the new vars */ ';
|
||||||
|
put ' length ';
|
||||||
|
put ' %do i=1 %to &numcols; ';
|
||||||
|
put ' &&name&i $&&fmtlen&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ; ';
|
||||||
put ' /* rename on entry */ ';
|
put ' /* rename on entry */ ';
|
||||||
put ' set &ds(rename=( ';
|
put ' set &ds(rename=( ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' &&name&i=&&newname&i ';
|
put ' &&name&i=&&newname&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' )); ';
|
put ' )); ';
|
||||||
|
put ' &stmt_obs; ';
|
||||||
|
put ' ';
|
||||||
|
put ' drop ';
|
||||||
|
put ' %do i=1 %to &numcols; ';
|
||||||
|
put ' &&newname&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' ; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' length &&name&i $&&len&i; ';
|
|
||||||
put ' %if &&typelong&i=num %then %do; ';
|
put ' %if &&typelong&i=num %then %do; ';
|
||||||
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
put ' &&name&i=cats(put(&&newname&i,&&fmt&i)); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %else %do; ';
|
put ' %else %do; ';
|
||||||
put ' &&name&i=put(&&newname&i,&&fmt&i); ';
|
put ' &&name&i=put(&&newname&i,&&fmt&i); ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' drop &&newname&i; ';
|
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' if _error_ then call symputx(''syscc'',1012); ';
|
put ' if _error_ then do; ';
|
||||||
|
put ' call symputx(''syscc'',1012); ';
|
||||||
|
put ' stop; ';
|
||||||
|
put ' end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %let fmtds=&syslast; ';
|
put ' %let fmtds=&syslast; ';
|
||||||
|
put ' options varlenchk=&optval; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc format; /* credit yabwon for special null removal */ ';
|
put ' proc format; /* credit yabwon for special null removal */ ';
|
||||||
@@ -391,8 +466,8 @@ data _null_;
|
|||||||
put ' attrib _all_ label=''''; ';
|
put ' attrib _all_ label=''''; ';
|
||||||
put ' %do i=1 %to &numcols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' length &&name&i $32767; ';
|
put ' length &&name&i $&&fmtlen&i...; ';
|
||||||
put ' format &&name&i $32767.; ';
|
put ' format &&name&i $&&fmtlen&i...; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
@@ -462,6 +537,7 @@ data _null_;
|
|||||||
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
|
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' file _sjs4; ';
|
put ' file _sjs4; ';
|
||||||
|
put ' length label $350; ';
|
||||||
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
||||||
put ' do i=1 to &numcols; ';
|
put ' do i=1 to &numcols; ';
|
||||||
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
||||||
@@ -513,8 +589,8 @@ data _null_;
|
|||||||
put ' %quote(&user) ';
|
put ' %quote(&user) ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL ';
|
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL ';
|
||||||
put ' ,showmeta=N ';
|
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||||
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
||||||
@@ -616,13 +692,13 @@ data _null_;
|
|||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||||
put ' ,jref=&fref,engine=DATASTEP,missing=&missing,showmeta=&showmeta ';
|
put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta,maxobs=&maxobs ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&workobs) > 0 %then %do; ';
|
||||||
put ' /* send back first 10 records of each work table for debugging */ ';
|
put ' /* send back first XX records of each work table for debugging */ ';
|
||||||
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
put ' data;run;%let tempds=%scan(&syslast,2,.); ';
|
||||||
put ' ods output Members=&tempds; ';
|
put ' ods output Members=&tempds; ';
|
||||||
put ' proc datasets library=WORK memtype=data; ';
|
put ' proc datasets library=WORK memtype=data; ';
|
||||||
@@ -645,7 +721,9 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y ';
|
||||||
|
put ' ,maxobs=&workobs ';
|
||||||
|
put ' ) ';
|
||||||
put ' data _null_; file &fref mod;put "}"; ';
|
put ' data _null_; file &fref mod;put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' data _null_; file &fref mod;put "}";run; ';
|
put ' data _null_; file &fref mod;put "}";run; ';
|
||||||
@@ -653,23 +731,31 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put ' /* close off json */ ';
|
put ' /* close off json */ ';
|
||||||
put ' data _null_;file &fref mod; ';
|
put ' data _null_;file &fref mod; ';
|
||||||
|
put ' length SYSPROCESSNAME syserrortext syswarningtext autoexec $512; ';
|
||||||
|
put ' put ",""_DEBUG"" : ""&_debug"" "; ';
|
||||||
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
||||||
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
|
||||||
|
put ' autoexec=quote(urlencode(trim(getoption(''autoexec'')))); ';
|
||||||
|
put ' put '',"AUTOEXEC" : '' autoexec; ';
|
||||||
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
||||||
put ' SYS_JES_JOB_URI=quote(trim(resolve(symget(''SYS_JES_JOB_URI'')))); ';
|
put ' SYS_JES_JOB_URI=quote(trim(resolve(symget(''SYS_JES_JOB_URI'')))); ';
|
||||||
put ' put '',"SYS_JES_JOB_URI" : '' SYS_JES_JOB_URI ; ';
|
put ' put '',"SYS_JES_JOB_URI" : '' SYS_JES_JOB_URI ; ';
|
||||||
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||||
put ' put ",""_DEBUG"" : ""&_debug"" "; ';
|
|
||||||
put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
|
|
||||||
put ' put ",""SYSCC"" : ""&syscc"" "; ';
|
put ' put ",""SYSCC"" : ""&syscc"" "; ';
|
||||||
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); ';
|
put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
|
||||||
put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
|
put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
|
||||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||||
|
put ' put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" "; ';
|
||||||
|
put ' put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" "; ';
|
||||||
|
put ' SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME))); ';
|
||||||
|
put ' put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME; ';
|
||||||
|
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||||
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
|
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
|
||||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||||
|
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
||||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||||
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); ';
|
put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
|
||||||
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
|
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
|
||||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
|
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
|
||||||
put ' length memsize $32; ';
|
put ' length memsize $32; ';
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
@param [in] _webout= fileref for returning the json
|
@param [in] _webout= fileref for returning the json
|
||||||
@param [out] fref=(_mvwtemp) Temp fileref to which to write the output
|
@param [out] fref=(_mvwtemp) Temp fileref to which to write the output
|
||||||
@param [out] dslabel= value to use instead of table name for sending to JSON
|
@param [out] dslabel= value to use instead of table name for sending to JSON
|
||||||
@param [in] fmt=(Y) change to N to strip formats from output
|
@param [in] fmt= (N) Setting Y converts all vars to their formatted values
|
||||||
@param [in] stream=(Y) Change to N if not streaming to _webout
|
@param [in] stream=(Y) Change to N if not streaming to _webout
|
||||||
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL
|
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL
|
||||||
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
@@ -33,17 +33,26 @@
|
|||||||
such as the column formats and types. The metadata is contained inside an
|
such as the column formats and types. The metadata is contained inside an
|
||||||
object with the same name as the table but prefixed with a dollar sign - ie,
|
object with the same name as the table but prefixed with a dollar sign - ie,
|
||||||
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
|
||||||
|
that should be converted to output JSON
|
||||||
|
@param [in] workobs= (0) When set to a positive integer, will create a new
|
||||||
|
output object (WORK) which contains this number of observations from all
|
||||||
|
tables in the WORK library.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
@li mf_getuser.sas
|
@li mf_getuser.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li ms_webout.sas
|
||||||
|
@li mm_webout.sas
|
||||||
|
|
||||||
@version Viya 3.3
|
@version Viya 3.3
|
||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL
|
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=N,stream=Y,missing=NULL
|
||||||
,showmeta=N
|
,showmeta=N,maxobs=MAX,workobs=0
|
||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||||
sasjs_tables SYS_JES_JOB_URI;
|
sasjs_tables SYS_JES_JOB_URI;
|
||||||
@@ -145,13 +154,13 @@
|
|||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=ARR or &action=OBJ %then %do;
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
,jref=&fref,engine=DATASTEP,missing=&missing,showmeta=&showmeta
|
,engine=DATASTEP,missing=&missing,showmeta=&showmeta,maxobs=&maxobs
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&workobs) > 0 %then %do;
|
||||||
/* send back first 10 records of each work table for debugging */
|
/* send back first XX records of each work table for debugging */
|
||||||
data;run;%let tempds=%scan(&syslast,2,.);
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
ods output Members=&tempds;
|
ods output Members=&tempds;
|
||||||
proc datasets library=WORK memtype=data;
|
proc datasets library=WORK memtype=data;
|
||||||
@@ -174,7 +183,9 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y
|
||||||
|
,maxobs=&workobs
|
||||||
|
)
|
||||||
data _null_; file &fref mod;put "}";
|
data _null_; file &fref mod;put "}";
|
||||||
%end;
|
%end;
|
||||||
data _null_; file &fref mod;put "}";run;
|
data _null_; file &fref mod;put "}";run;
|
||||||
@@ -182,23 +193,31 @@
|
|||||||
|
|
||||||
/* close off json */
|
/* close off json */
|
||||||
data _null_;file &fref mod;
|
data _null_;file &fref mod;
|
||||||
|
length SYSPROCESSNAME syserrortext syswarningtext autoexec $512;
|
||||||
|
put ",""_DEBUG"" : ""&_debug"" ";
|
||||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||||
|
autoexec=quote(urlencode(trim(getoption('autoexec'))));
|
||||||
|
put ',"AUTOEXEC" : ' autoexec;
|
||||||
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
||||||
SYS_JES_JOB_URI=quote(trim(resolve(symget('SYS_JES_JOB_URI'))));
|
SYS_JES_JOB_URI=quote(trim(resolve(symget('SYS_JES_JOB_URI'))));
|
||||||
put ',"SYS_JES_JOB_URI" : ' SYS_JES_JOB_URI ;
|
put ',"SYS_JES_JOB_URI" : ' SYS_JES_JOB_URI ;
|
||||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
put ",""_DEBUG"" : ""&_debug"" ";
|
|
||||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
|
||||||
put ",""SYSCC"" : ""&syscc"" ";
|
put ",""SYSCC"" : ""&syscc"" ";
|
||||||
syserrortext=quote(cats(symget('SYSERRORTEXT')));
|
syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
|
||||||
put ',"SYSERRORTEXT" : ' syserrortext;
|
put ',"SYSERRORTEXT" : ' syserrortext;
|
||||||
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||||
|
put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
|
||||||
|
put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
|
||||||
|
SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME)));
|
||||||
|
put ",""SYSPROCESSNAME"" : " SYSPROCESSNAME;
|
||||||
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
||||||
put ",""SYSSITE"" : ""&syssite"" ";
|
put ",""SYSSITE"" : ""&syssite"" ";
|
||||||
|
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||||
sysvlong=quote(trim(symget('sysvlong')));
|
sysvlong=quote(trim(symget('sysvlong')));
|
||||||
put ',"SYSVLONG" : ' sysvlong;
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
syswarningtext=quote(cats(symget('SYSWARNINGTEXT')));
|
syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
|
||||||
put ',"SYSWARNINGTEXT" : ' syswarningtext;
|
put ',"SYSWARNINGTEXT" : ' syswarningtext;
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
||||||
length memsize $32;
|
length memsize $32;
|
||||||
|
|||||||
Reference in New Issue
Block a user