1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-21 10:11:19 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Allan Bowe
4c333ae7b3 feat: mp_prevobs.sas macro 2020-12-23 00:33:59 +00:00
b3a8b4323e fix: adding new mp_ds2csv macro 2020-12-16 17:11:31 +01:00
0592206f2d patch: doxy formatting 2020-12-03 22:44:08 +01:00
bedc2a443a fix: @cond on new line to prevent parsing issues in sasjs cli 2020-12-02 08:09:51 +01:00
6f86ed62a2 chore: doxy formatting 2020-11-29 22:03:20 +01:00
def0cc8476 fix: adding outds and parameters to mv_jobexecute 2020-11-29 21:55:21 +01:00
3a9029557e chore: doxygen updates 2020-11-29 21:06:39 +01:00
35 changed files with 645 additions and 235 deletions

341
all.sas
View File

@@ -39,7 +39,8 @@ options noquotelenmax;
@version 9.2
@author Allan Bowe
**/ /** @cond */
@cond
**/
%macro mf_abort(mac=mf_abort.sas, type=, msg=, iftrue=%str(1=1)
)/*/STORE SOURCE*/;
@@ -204,7 +205,8 @@ options noquotelenmax;
@version 8
@author Allan Bowe
**/ /** @cond */
**/
/** @cond */
%macro mf_existfeature(feature
)/*/STORE SOURCE*/;
@@ -239,7 +241,8 @@ options noquotelenmax;
@param var (positional) - variable name
@version 9.2
@author Allan Bowe
**/ /** @cond */
**/
/** @cond */
%macro mf_existvar(libds /* 2 part dataset name */
, var /* variable name */
@@ -275,6 +278,7 @@ options noquotelenmax;
@version 9.2
@author Allan Bowe
@cond
**/
%macro mf_existvarlist(libds, varlist
@@ -314,7 +318,9 @@ options noquotelenmax;
0
%put Vars not found: &found;
%end;
%mend;/**
%mend;
/** @endcond *//**
@file
@brief Returns a character attribute of a dataset.
@details Can be used in open code, eg as follows:
@@ -404,7 +410,8 @@ options noquotelenmax;
@version 9.2
@author Allan Bowe
**/ /** @cond */
**/
/** @cond */
%macro mf_getengine(libref
)/*/STORE SOURCE*/;
@@ -629,6 +636,7 @@ options noquotelenmax;
@version 9.2
@author Allan Bowe
@cond
**/
%macro mf_getschema(libref
@@ -650,6 +658,8 @@ options noquotelenmax;
&schema
%mend;
/** @endcond */
/**
@file
@brief Assigns and returns an unused fileref
@@ -1538,6 +1548,7 @@ Usage:
@version 9.4M3
@author Allan Bowe
@cond
**/
%macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1)
@@ -1671,7 +1682,7 @@ Usage:
%end;
%mend;
/**
/** @endcond *//**
@file
@brief Copy any file using binary input / output streams
@details Reads in a file byte by byte and writes it back out. Is an
@@ -1735,6 +1746,7 @@ Usage:
applying CRLF line endings and converting embedded cr and crlf to lf.
usage:
fileref mycsv "/path/your/csv";
%mp_cleancsv(in=mycsv,out=/path/new.csv)
@@ -1744,6 +1756,7 @@ Usage:
@version 9.2
@author Allan Bowe
@cond
**/
%macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x);
@@ -1792,7 +1805,8 @@ Usage:
else put inchar $char1.;
end;
run;
%mend;/**
%mend;
/** @endcond *//**
@file mp_createconstraints.sas
@brief Creates constraints
@details Takes the output from mp_getconstraints.sas as input
@@ -2631,6 +2645,63 @@ quit;
%put NOTE-;%put NOTE-;
%put NOTE- %sysfunc(dequote(&cards_file.));
%put NOTE-;%put NOTE-;
%mend;/**
@file
@brief Export a dataset to a CSV file
@details Export to a file or a fileref
Usage:
%mp_ds2csv(sashelp.class,outref="%sysfunc(pathname(work))/file.csv")
@param ds The dataset to be exported
@param outfile= The output filename - should be quoted.
@param outref= The output fileref (takes precedence if provided)
@param outencoding= The output encoding to use (unquoted)
@version 9.2
@author Allan Bowe (credit mjsq)
**/
%macro mp_ds2csv(ds, outref=0, outfile=, outencoding=0
)/*/STORE SOURCE*/;
%if not %sysfunc(exist(&ds)) %then %do;
%put WARNING: &ds does not exist;
%return;
%end;
%if %index(&ds,.)=0 %then %let ds=WORK.&ds;
%if &outencoding=0 %then %let outencoding=;
%else %let outencoding=encoding="&outencoding";
%local outloc;
%if &outref=0 %then %let outloc=&outfile;
%else %let outloc=&outref;
/* credit to mjsq - https://stackoverflow.com/a/55642267 */
/* first get headers */
data _null_;
file &outloc dlm=',' dsd &outencoding lrecl=32767;
length header $ 2000;
dsid=open("&ds.","i");
num=attrn(dsid,"nvars");
do i=1 to num;
header = trim(left(coalescec(varlabel(dsid,i),varname(dsid,i))));
put header @;
end;
rc=close(dsid);
run;
/* next, export data */
data _null_;
set &ds.;
file &outloc mod dlm=',' dsd &outencoding lrecl=32767;
put (_all_) (+0);
run;
%mend;/**
@file mp_getconstraints.sas
@brief Get constraint details at column level
@@ -2708,6 +2779,8 @@ create table &outds as
You may need to adjust the rendered DBML to suit your needs.
![dbml for sas](https://i.imgur.com/8T1tIZp.gif)
<h4> SAS Macros </h4>
@li mf_getquotedstr.sas
@@ -3993,6 +4066,93 @@ select distinct lowcase(memname)
,dttm=%sysfunc(datetime());
quit;
%mend;/**
@file
@brief Enables previous observations to be re-instated
@details Remembers the last X observations by storing them in a hash table.
Is a convenience over the use of lag() or retain, when an entire observation
needs to be restored.
This macro will also restore automatic variables (such as _n_ and _error_).
Example Usage:
data example;
set sashelp.class;
calc_var=_n_*3;
* initialise hash and save from PDV ;
%mp_prevobs(INIT,history=2)
if _n_ =10 then do;
* fetch previous but 1 record;
%mp_prevobs(FETCH,-2)
put _n_= name= age= calc_var=;
* fetch previous record;
%mp_prevobs(FETCH,-1)
put _n_= name= age= calc_var=;
* reinstate current record ;
%mp_prevobs(FETCH,0)
put _n_= name= age= calc_var=;
end;
run;
Result:
<img src="https://imgur.com/PSjHoET.png" alt="mp_prevobs sas" width="400"/>
Credit is made to `data _null_` for authoring this very helpful paper:
https://www.lexjansen.com/pharmasug/2008/cc/CC08.pdf
@param action Either FETCH a current or previous record, or INITialise.
@param record The relative (to current) position of the previous observation
to return.
@param history= The number of records to retain in the hash table. Default=5
@param prefix= the prefix to give to the variables used to store the hash name
and index. Default=mp_prevobs
@version 9.2
@author Allan Bowe
**/
%macro mp_prevobs(action,record,history=5,prefix=mp_prevobs
)/*/STORE SOURCE*/;
%let action=%upcase(&action);
%let prefix=%upcase(&prefix);
%let record=%eval((&record+0) * -1);
%if &action=INIT %then %do;
if _n_ eq 1 then do;
attrib &prefix._VAR length=$64;
dcl hash &prefix._HASH(ordered:'Y');
&prefix._KEY=0;
&prefix._HASH.defineKey("&prefix._KEY");
do while(1);
call vnext(&prefix._VAR);
if &prefix._VAR='' then leave;
if &prefix._VAR eq "&prefix._VAR" then continue;
else if &prefix._VAR eq "&prefix._KEY" then continue;
&prefix._HASH.defineData(&prefix._VAR);
end;
&prefix._HASH.defineDone();
end;
/* this part has to happen before FETCHing */
&prefix._KEY+1;
&prefix._rc=&prefix._HASH.add();
if &prefix._rc then putlog 'adding' &prefix._rc=;
%if &history>0 %then %do;
if &prefix._key>&history+1 then
&prefix._HASH.remove(key: &prefix._KEY - &history - 1);
if &prefix._rc then putlog 'removing' &prefix._rc=;
%end;
%end;
%else %if &action=FETCH %then %do;
if &record > &prefix._key then putlog "Not enough records in &Prefix._hash yet";
else &prefix._rc=&prefix._HASH.find(key: &prefix._KEY - &record);
if &prefix._rc then putlog &prefix._rc= " when fetching " &prefix._KEY=
"with record &record and " _n_=;
%end;
%mend;/**
@file
@brief Returns all children from a hierarchy table for a specified parent
@@ -4594,6 +4754,64 @@ proc sql
%mp_binarycopy(inloc="&inloc",outref=_webout)
%end;
%mend;/**
@file mp_testwritespeedlibrary.sas
@brief Tests the write speed of a new table in a SAS library
@details Will create a new table of a certain size in an
existing SAS library. The table will have one column,
and will be subsequently deleted.
%mp_testwritespeedlibrary(
lib=work
,size=0.5
,outds=work.results
)
@param lib= (WORK) The library in which to create the table
@param size= (0.1) The size in GB of the table to create
@param outds= (WORK.RESULTS) The output dataset to be created.
<h4> Dependencies </h4>
@li mf_getuniquename.sas
@li mf_existds.sas
@version 9.4
@author Allan Bowe
**/
%macro mp_testwritespeedlibrary(lib=WORK
,outds=work.results
,size=0.1
)/*/STORE SOURCE*/;
%local ds start;
/* find an unused, unique name for the new table */
%let ds=%mf_getuniquename();
%do %until(%mf_existds(&lib..&ds)=0);
%let ds=%mf_getuniquename();
%end;
%let start=%sysfunc(datetime());
data &lib..&ds(compress=no keep=x);
header=128*1024;
size=(1073741824/8 * &size) - header;
do x=1 to size;
output;
end;
run;
proc sql;
drop table &lib..&ds;
data &outds;
lib="&lib";
start_dttm=put(&start,datetime19.);
end_dttm=put(datetime(),datetime19.);
duration_seconds=end_dttm-start_dttm;
run;
%mend;/**
@file
@brief Recursively scans a directory tree to get all subfolders and content
@@ -10329,8 +10547,7 @@ run;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -10467,7 +10684,8 @@ options noquotelenmax;
%mend;/**
@file mv_createwebservice.sas
@brief Creates a JobExecution web service if it doesn't already exist
@details Code is passed in as one or more filerefs.
@details
Code is passed in as one or more filerefs.
%* Step 1 - compile macros ;
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
@@ -10520,8 +10738,7 @@ options noquotelenmax;
a shared context - see https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
**/
@@ -11143,8 +11360,7 @@ run;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -11293,8 +11509,7 @@ libname &libref1a clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -11438,8 +11653,7 @@ libname &libref1a clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -11567,8 +11781,7 @@ libname &libref1 clear;
@brief deprecated - replaced by mv_tokenrefresh.sas
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mv_tokenrefresh.sas
@@ -11599,8 +11812,7 @@ libname &libref1 clear;
@brief deprecated - replaced by mv_registerclient.sas
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mv_registerclient.sas
@@ -11648,8 +11860,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -11735,8 +11946,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -11869,8 +12079,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -11974,8 +12183,7 @@ filename &fname1 clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -12045,8 +12253,7 @@ libname &libref1 clear;
@brief deprecated - replaced by mv_tokenauth.sas
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mv_tokenauth.sas
@@ -12095,8 +12302,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -12214,8 +12420,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -12299,6 +12504,12 @@ libname &libref1 clear;
,name=somejob
)
Example with parameters:
%mv_jobexecute(path=/Public/folder
,name=somejob
,paramstring=%str("macvarname":"macvarvalue","answer":42)
)
@param access_token_var= The global macro variable to contain the access token
@param grant_type= valid values:
@@ -12310,10 +12521,14 @@ libname &libref1 clear;
@param path= The SAS Drive path to the job being executed
@param name= The name of the job to execute
@param params= A macro quoted string to append to the URL
@param paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"`
or "name":"value","name2":42`. This will need to be wrapped in `%str()`.
@param contextName= Context name with which to run the job.
Default = `SAS Job Execution compute context`
@param outds= The output dataset containing links (Default=work.mv_jobexecute)
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
@@ -12322,6 +12537,7 @@ libname &libref1 clear;
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mv_getfoldermembers.sas
**/
@@ -12331,6 +12547,8 @@ libname &libref1 clear;
,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN
,grant_type=sas_services
,paramstring=0
,outds=work.mv_jobexecute
);
%local oauth_bearer;
%if &grant_type=detect %then %do;
@@ -12392,11 +12610,16 @@ run;
data _null_;
file &fname0;
put '{"jobDefinitionUri": "'@@;
put "&joburi"@@;
put '","arguments":{"_contextName":"'@@;
put "&contextName"@@;
put '"}}';
length joburi contextname $128 paramstring $32765;
joburi=quote(trim(symget('joburi')));
contextname=quote(trim(symget('contextname')));
paramstring=symget('paramstring');
put '{"jobDefinitionUri":' joburi ;
put ' ,"arguments":{"_contextName":' contextname;
if paramstring ne "0" then do;
put ' ,' paramstring;
end;
put '}}';
run;
proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
@@ -12408,18 +12631,27 @@ proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
%end;
;
run;
/*data _null_;infile &fname1;input;putlog _infile_;run;*/
%mp_abort(iftrue=(
&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201
)
,mac=&sysmacroname
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
%do;
data _null_;infile &fname0;input;putlog _infile_;run;
data _null_;infile &fname1;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
)
%end;
%local libref;
%let libref=%mf_getuniquelibref();
libname &libref JSON fileref=&fname1;
data &outds;
set &libref..links;
run;
/* clear refs */
filename &fname0 clear;
filename &fname1 clear;
libname &libref;
%mend;/**
@file mv_registerclient.sas
@@ -12475,8 +12707,7 @@ filename &fname1 clear;
for debugging. Default= _null_.
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -12699,8 +12930,7 @@ libname &libref clear;
@param base_uri= The Viya API server location
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -12842,8 +13072,7 @@ filename &fref2 clear;
@param refresh_token_var= The global macro variable containing the refresh token
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas
@@ -12965,7 +13194,7 @@ filename &fref1 clear;
@li mf_getuser.sas
@version Viya 3.3
@author Allan Bowe
@author Allan Bowe, source: https://github.com/sasjs/core
**/
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y);

View File

@@ -21,7 +21,8 @@
@version 9.2
@author Allan Bowe
**/ /** @cond */
@cond
**/
%macro mf_abort(mac=mf_abort.sas, type=, msg=, iftrue=%str(1=1)
)/*/STORE SOURCE*/;

View File

@@ -19,7 +19,8 @@
@version 8
@author Allan Bowe
**/ /** @cond */
**/
/** @cond */
%macro mf_existfeature(feature
)/*/STORE SOURCE*/;

View File

@@ -11,7 +11,8 @@
@param var (positional) - variable name
@version 9.2
@author Allan Bowe
**/ /** @cond */
**/
/** @cond */
%macro mf_existvar(libds /* 2 part dataset name */
, var /* variable name */

View File

@@ -14,6 +14,7 @@
@version 9.2
@author Allan Bowe
@cond
**/
%macro mf_existvarlist(libds, varlist
@@ -54,3 +55,5 @@
%put Vars not found: &found;
%end;
%mend;
/** @endcond */

View File

@@ -22,7 +22,8 @@
@version 9.2
@author Allan Bowe
**/ /** @cond */
**/
/** @cond */
%macro mf_getengine(libref
)/*/STORE SOURCE*/;

View File

@@ -17,6 +17,7 @@
@version 9.2
@author Allan Bowe
@cond
**/
%macro mf_getschema(libref
@@ -38,3 +39,5 @@
&schema
%mend;
/** @endcond */

View File

@@ -18,6 +18,7 @@
@version 9.4M3
@author Allan Bowe
@cond
**/
%macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1)
@@ -151,3 +152,4 @@
%end;
%mend;
/** @endcond */

View File

@@ -8,6 +8,7 @@
applying CRLF line endings and converting embedded cr and crlf to lf.
usage:
fileref mycsv "/path/your/csv";
%mp_cleancsv(in=mycsv,out=/path/new.csv)
@@ -17,6 +18,7 @@
@version 9.2
@author Allan Bowe
@cond
**/
%macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x);
@@ -66,3 +68,4 @@
end;
run;
%mend;
/** @endcond */

58
base/mp_ds2csv.sas Normal file
View File

@@ -0,0 +1,58 @@
/**
@file
@brief Export a dataset to a CSV file
@details Export to a file or a fileref
Usage:
%mp_ds2csv(sashelp.class,outref="%sysfunc(pathname(work))/file.csv")
@param ds The dataset to be exported
@param outfile= The output filename - should be quoted.
@param outref= The output fileref (takes precedence if provided)
@param outencoding= The output encoding to use (unquoted)
@version 9.2
@author Allan Bowe (credit mjsq)
**/
%macro mp_ds2csv(ds, outref=0, outfile=, outencoding=0
)/*/STORE SOURCE*/;
%if not %sysfunc(exist(&ds)) %then %do;
%put WARNING: &ds does not exist;
%return;
%end;
%if %index(&ds,.)=0 %then %let ds=WORK.&ds;
%if &outencoding=0 %then %let outencoding=;
%else %let outencoding=encoding="&outencoding";
%local outloc;
%if &outref=0 %then %let outloc=&outfile;
%else %let outloc=&outref;
/* credit to mjsq - https://stackoverflow.com/a/55642267 */
/* first get headers */
data _null_;
file &outloc dlm=',' dsd &outencoding lrecl=32767;
length header $ 2000;
dsid=open("&ds.","i");
num=attrn(dsid,"nvars");
do i=1 to num;
header = trim(left(coalescec(varlabel(dsid,i),varname(dsid,i))));
put header @;
end;
rc=close(dsid);
run;
/* next, export data */
data _null_;
set &ds.;
file &outloc mod dlm=',' dsd &outencoding lrecl=32767;
put (_all_) (+0);
run;
%mend;

View File

@@ -16,6 +16,8 @@
You may need to adjust the rendered DBML to suit your needs.
![dbml for sas](https://i.imgur.com/8T1tIZp.gif)
<h4> SAS Macros </h4>
@li mf_getquotedstr.sas

88
base/mp_prevobs.sas Normal file
View File

@@ -0,0 +1,88 @@
/**
@file
@brief Enables previous observations to be re-instated
@details Remembers the last X observations by storing them in a hash table.
Is a convenience over the use of lag() or retain, when an entire observation
needs to be restored.
This macro will also restore automatic variables (such as _n_ and _error_).
Example Usage:
data example;
set sashelp.class;
calc_var=_n_*3;
* initialise hash and save from PDV ;
%mp_prevobs(INIT,history=2)
if _n_ =10 then do;
* fetch previous but 1 record;
%mp_prevobs(FETCH,-2)
put _n_= name= age= calc_var=;
* fetch previous record;
%mp_prevobs(FETCH,-1)
put _n_= name= age= calc_var=;
* reinstate current record ;
%mp_prevobs(FETCH,0)
put _n_= name= age= calc_var=;
end;
run;
Result:
<img src="https://imgur.com/PSjHoET.png" alt="mp_prevobs sas" width="400"/>
Credit is made to `data _null_` for authoring this very helpful paper:
https://www.lexjansen.com/pharmasug/2008/cc/CC08.pdf
@param action Either FETCH a current or previous record, or INITialise.
@param record The relative (to current) position of the previous observation
to return.
@param history= The number of records to retain in the hash table. Default=5
@param prefix= the prefix to give to the variables used to store the hash name
and index. Default=mp_prevobs
@version 9.2
@author Allan Bowe
**/
%macro mp_prevobs(action,record,history=5,prefix=mp_prevobs
)/*/STORE SOURCE*/;
%let action=%upcase(&action);
%let prefix=%upcase(&prefix);
%let record=%eval((&record+0) * -1);
%if &action=INIT %then %do;
if _n_ eq 1 then do;
attrib &prefix._VAR length=$64;
dcl hash &prefix._HASH(ordered:'Y');
&prefix._KEY=0;
&prefix._HASH.defineKey("&prefix._KEY");
do while(1);
call vnext(&prefix._VAR);
if &prefix._VAR='' then leave;
if &prefix._VAR eq "&prefix._VAR" then continue;
else if &prefix._VAR eq "&prefix._KEY" then continue;
&prefix._HASH.defineData(&prefix._VAR);
end;
&prefix._HASH.defineDone();
end;
/* this part has to happen before FETCHing */
&prefix._KEY+1;
&prefix._rc=&prefix._HASH.add();
if &prefix._rc then putlog 'adding' &prefix._rc=;
%if &history>0 %then %do;
if &prefix._key>&history+1 then
&prefix._HASH.remove(key: &prefix._KEY - &history - 1);
if &prefix._rc then putlog 'removing' &prefix._rc=;
%end;
%end;
%else %if &action=FETCH %then %do;
if &record > &prefix._key then putlog "Not enough records in &Prefix._hash yet";
else &prefix._rc=&prefix._HASH.find(key: &prefix._KEY - &record);
if &prefix._rc then putlog &prefix._rc= " when fetching " &prefix._KEY=
"with record &record and " _n_=;
%end;
%mend;

View File

@@ -24,7 +24,7 @@ LAYOUT_FILE = ./doxy/DoxygenLayout.xml
MAX_INITIALIZER_LINES = 0
PROJECT_NAME = Macro Core
PROJECT_LOGO = doxy/Macro_core_website_1.png
PROJECT_BRIEF = placeholder
PROJECT_BRIEF = "Production Ready Macros for SAS Application Developers"
RECURSIVE = YES
REPEAT_BRIEF = NO
SHOW_NAMESPACES = NO

View File

@@ -33,11 +33,11 @@ cd core.github.io
rm -r *
mv $BUILD_FOLDER/out/doxy/* .
echo 'core.sasjs.io' > CNAME
git add *
git add .
git commit -m "build.sh build on $(date +%F:%H:%M:%S)"
git push
npx sitemap-generator-cli https://core.sasjs.io
git add *
git add .
git commit -m "adding sitemap"
git push

View File

@@ -1,6 +1,6 @@
<!-- HTML header for doxygen 1.8.17-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<!-- HTML header for doxygen 1.8.17-->
<html xmlns="https://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
@@ -41,7 +41,9 @@ $extrastylesheet
https://github.com/sasjs/core
</a>
</div><!--END PROJECT_BRIEF-->
</div>
<meta name="Description" content="$projectbrief">
<!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->

View File

@@ -13,6 +13,11 @@
* Not metadata aware
* No X command
* Prefixes: _mf_, _mp_
Macros starting `mf_` are macro _functions_ and can be used in assignment
statements. Those starting `mp_` are macro _procedures_, which generate
SAS statements, and must therefore be applied accordingly.
*/
/*! \dir meta

View File

@@ -15,8 +15,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -1,7 +1,8 @@
/**
@file mv_createwebservice.sas
@brief Creates a JobExecution web service if it doesn't already exist
@details Code is passed in as one or more filerefs.
@details
Code is passed in as one or more filerefs.
%* Step 1 - compile macros ;
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
@@ -54,8 +55,7 @@
a shared context - see https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
**/

View File

@@ -20,8 +20,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -19,8 +19,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -16,8 +16,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -3,8 +3,7 @@
@brief deprecated - replaced by mv_tokenrefresh.sas
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mv_tokenrefresh.sas

View File

@@ -3,8 +3,7 @@
@brief deprecated - replaced by mv_registerclient.sas
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mv_registerclient.sas

View File

@@ -29,8 +29,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -15,8 +15,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -30,8 +30,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -29,8 +29,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -3,8 +3,7 @@
@brief deprecated - replaced by mv_tokenauth.sas
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mv_tokenauth.sas

View File

@@ -20,8 +20,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -47,8 +47,7 @@
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -16,6 +16,12 @@
,name=somejob
)
Example with parameters:
%mv_jobexecute(path=/Public/folder
,name=somejob
,paramstring=%str("macvarname":"macvarvalue","answer":42)
)
@param access_token_var= The global macro variable to contain the access token
@param grant_type= valid values:
@@ -27,10 +33,14 @@
@param path= The SAS Drive path to the job being executed
@param name= The name of the job to execute
@param params= A macro quoted string to append to the URL
@param paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"`
or "name":"value","name2":42`. This will need to be wrapped in `%str()`.
@param contextName= Context name with which to run the job.
Default = `SAS Job Execution compute context`
@param outds= The output dataset containing links (Default=work.mv_jobexecute)
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
@@ -39,6 +49,7 @@
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mv_getfoldermembers.sas
**/
@@ -48,6 +59,8 @@
,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN
,grant_type=sas_services
,paramstring=0
,outds=work.mv_jobexecute
);
%local oauth_bearer;
%if &grant_type=detect %then %do;
@@ -109,11 +122,16 @@ run;
data _null_;
file &fname0;
put '{"jobDefinitionUri": "'@@;
put "&joburi"@@;
put '","arguments":{"_contextName":"'@@;
put "&contextName"@@;
put '"}}';
length joburi contextname $128 paramstring $32765;
joburi=quote(trim(symget('joburi')));
contextname=quote(trim(symget('contextname')));
paramstring=symget('paramstring');
put '{"jobDefinitionUri":' joburi ;
put ' ,"arguments":{"_contextName":' contextname;
if paramstring ne "0" then do;
put ' ,' paramstring;
end;
put '}}';
run;
proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
@@ -125,17 +143,26 @@ proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
%end;
;
run;
/*data _null_;infile &fname1;input;putlog _infile_;run;*/
%mp_abort(iftrue=(
&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201
)
,mac=&sysmacroname
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
%do;
data _null_;infile &fname0;input;putlog _infile_;run;
data _null_;infile &fname1;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
)
%end;
%local libref;
%let libref=%mf_getuniquelibref();
libname &libref JSON fileref=&fname1;
data &outds;
set &libref..links;
run;
/* clear refs */
filename &fname0 clear;
filename &fname1 clear;
libname &libref;
%mend;

View File

@@ -52,8 +52,7 @@
for debugging. Default= _null_.
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -41,8 +41,7 @@
@param base_uri= The Viya API server location
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -40,8 +40,7 @@
@param refresh_token_var= The global macro variable containing the refresh token
@version VIYA V.03.04
@author Allan Bowe
@source https://github.com/sasjs/core
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
@li mp_abort.sas

View File

@@ -32,7 +32,7 @@
@li mf_getuser.sas
@version Viya 3.3
@author Allan Bowe
@author Allan Bowe, source: https://github.com/sasjs/core
**/
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y);