@sasjs/utils 2.48.2 → 2.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fs/generateCompileProgram.d.ts +1 -0
- package/fs/generateCompileProgram.js +154 -0
- package/fs/generateCompileProgram.js.map +1 -0
- package/fs/hash.d.ts +22 -0
- package/fs/hash.js +225 -0
- package/fs/hash.js.map +1 -0
- package/fs/index.d.ts +3 -0
- package/fs/index.js +13 -0
- package/fs/index.js.map +1 -0
- package/fs/internal/helper.d.ts +4 -0
- package/fs/internal/helper.js +125 -0
- package/fs/internal/helper.js.map +1 -0
- package/fs/sync.d.ts +6 -0
- package/fs/sync.js +208 -0
- package/fs/sync.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/macros/mf_abort.sas +27 -0
- package/macros/mf_dedup.sas +53 -0
- package/macros/mf_deletefile.sas +31 -0
- package/macros/mf_existds.sas +30 -0
- package/macros/mf_existfeature.sas +59 -0
- package/macros/mf_existfileref.sas +33 -0
- package/macros/mf_existfunction.sas +37 -0
- package/macros/mf_existvar.sas +39 -0
- package/macros/mf_existvarlist.sas +56 -0
- package/macros/mf_fmtdttm.sas +42 -0
- package/macros/mf_getapploc.sas +78 -0
- package/macros/mf_getattrc.sas +34 -0
- package/macros/mf_getattrn.sas +34 -0
- package/macros/mf_getengine.sas +54 -0
- package/macros/mf_getfilesize.sas +64 -0
- package/macros/mf_getfmtlist.sas +61 -0
- package/macros/mf_getfmtname.sas +44 -0
- package/macros/mf_getkeyvalue.sas +32 -0
- package/macros/mf_getplatform.sas +75 -0
- package/macros/mf_getquotedstr.sas +57 -0
- package/macros/mf_getschema.sas +43 -0
- package/macros/mf_getuniquefileref.sas +60 -0
- package/macros/mf_getuniquelibref.sas +57 -0
- package/macros/mf_getuniquename.sas +22 -0
- package/macros/mf_getuser.sas +44 -0
- package/macros/mf_getvalue.sas +36 -0
- package/macros/mf_getvarcount.sas +49 -0
- package/macros/mf_getvarformat.sas +72 -0
- package/macros/mf_getvarlen.sas +56 -0
- package/macros/mf_getvarlist.sas +74 -0
- package/macros/mf_getvarnum.sas +58 -0
- package/macros/mf_getvartype.sas +52 -0
- package/macros/mf_getxengine.sas +43 -0
- package/macros/mf_increment.sas +29 -0
- package/macros/mf_isblank.sas +27 -0
- package/macros/mf_isdir.sas +34 -0
- package/macros/mf_isint.sas +36 -0
- package/macros/mf_islibds.sas +40 -0
- package/macros/mf_loc.sas +29 -0
- package/macros/mf_mkdir.sas +67 -0
- package/macros/mf_mval.sas +19 -0
- package/macros/mf_nobs.sas +26 -0
- package/macros/mf_trimstr.sas +50 -0
- package/macros/mf_uid.sas +21 -0
- package/macros/mf_verifymacvars.sas +72 -0
- package/macros/mf_wordsinstr1andstr2.sas +53 -0
- package/macros/mf_wordsinstr1butnotstr2.sas +54 -0
- package/macros/mf_writefile.sas +67 -0
- package/macros/mp_abort.sas +301 -0
- package/macros/mp_appendfile.sas +57 -0
- package/macros/mp_applyformats.sas +181 -0
- package/macros/mp_assert.sas +56 -0
- package/macros/mp_assertcols.sas +145 -0
- package/macros/mp_assertcolvals.sas +168 -0
- package/macros/mp_assertdsobs.sas +121 -0
- package/macros/mp_assertscope.sas +147 -0
- package/macros/mp_base64copy.sas +117 -0
- package/macros/mp_binarycopy.sas +79 -0
- package/macros/mp_chop.sas +194 -0
- package/macros/mp_cleancsv.sas +78 -0
- package/macros/mp_cntlout.sas +85 -0
- package/macros/mp_copyfolder.sas +84 -0
- package/macros/mp_coretable.sas +73 -0
- package/macros/mp_createconstraints.sas +70 -0
- package/macros/mp_createwebservice.sas +32 -0
- package/macros/mp_csv2ds.sas +140 -0
- package/macros/mp_deleteconstraints.sas +52 -0
- package/macros/mp_deletefolder.sas +70 -0
- package/macros/mp_dictionary.sas +52 -0
- package/macros/mp_dirlist.sas +263 -0
- package/macros/mp_distinctfmtvalues.sas +50 -0
- package/macros/mp_dropmembers.sas +46 -0
- package/macros/mp_ds2cards.sas +291 -0
- package/macros/mp_ds2csv.sas +212 -0
- package/macros/mp_ds2ddl.sas +30 -0
- package/macros/mp_ds2fmtds.sas +105 -0
- package/macros/mp_ds2inserts.sas +180 -0
- package/macros/mp_ds2md.sas +103 -0
- package/macros/mp_ds2squeeze.sas +120 -0
- package/macros/mp_dsmeta.sas +110 -0
- package/macros/mp_filtercheck.sas +251 -0
- package/macros/mp_filtergenerate.sas +105 -0
- package/macros/mp_filterstore.sas +254 -0
- package/macros/mp_filtervalidate.sas +105 -0
- package/macros/mp_getcols.sas +67 -0
- package/macros/mp_getconstraints.sas +115 -0
- package/macros/mp_getdbml.sas +335 -0
- package/macros/mp_getddl.sas +400 -0
- package/macros/mp_getformats.sas +124 -0
- package/macros/mp_getmaxvarlengths.sas +130 -0
- package/macros/mp_getpk.sas +281 -0
- package/macros/mp_gsubfile.sas +58 -0
- package/macros/mp_guesspk.sas +332 -0
- package/macros/mp_hashdataset.sas +91 -0
- package/macros/mp_hashdirectory.sas +162 -0
- package/macros/mp_include.sas +106 -0
- package/macros/mp_init.sas +76 -0
- package/macros/mp_jsonout.sas +406 -0
- package/macros/mp_lib2cards.sas +78 -0
- package/macros/mp_lib2inserts.sas +77 -0
- package/macros/mp_loadformat.sas +303 -0
- package/macros/mp_lockanytable.sas +243 -0
- package/macros/mp_lockfilecheck.sas +103 -0
- package/macros/mp_makedata.sas +107 -0
- package/macros/mp_md5.sas +58 -0
- package/macros/mp_perflog.sas +43 -0
- package/macros/mp_prevobs.sas +88 -0
- package/macros/mp_recursivejoin.sas +90 -0
- package/macros/mp_replace.sas +151 -0
- package/macros/mp_reseterror.sas +27 -0
- package/macros/mp_resetoption.sas +39 -0
- package/macros/mp_retainedkey.sas +247 -0
- package/macros/mp_runddl.sas +49 -0
- package/macros/mp_searchcols.sas +103 -0
- package/macros/mp_searchdata.sas +131 -0
- package/macros/mp_setkeyvalue.sas +55 -0
- package/macros/mp_sortinplace.sas +122 -0
- package/macros/mp_stackdiffs.sas +592 -0
- package/macros/mp_storediffs.sas +230 -0
- package/macros/mp_stprequests.sas +74 -0
- package/macros/mp_streamfile.sas +212 -0
- package/macros/mp_testjob.sas +92 -0
- package/macros/mp_testservice.sas +39 -0
- package/macros/mp_testwritespeedlibrary.sas +59 -0
- package/macros/mp_tree.sas +71 -0
- package/macros/mp_unzip.sas +90 -0
- package/macros/mp_updatevarlength.sas +93 -0
- package/macros/mp_validatecol.sas +97 -0
- package/macros/mp_wait4file.sas +35 -0
- package/macros/mp_webin.sas +59 -0
- package/macros/mp_zip.sas +85 -0
- package/package.json +5 -2
- package/scripts/copySASjsCore.ts +36 -0
- package/types/hash.d.ts +9 -0
- package/types/hash.js +3 -0
- package/types/hash.js.map +1 -0
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/types/index.js.map +1 -1
- package/utils/index.d.ts +1 -1
- package/utils/index.js +2 -1
- package/utils/index.js.map +1 -1
- package/utils/utils.d.ts +1 -0
- package/utils/utils.js +7 -1
- package/utils/utils.js.map +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the appLoc from the _program variable
|
|
4
|
+
@details When working with SASjs apps, web services / tests / jobs are always
|
|
5
|
+
deployed to a root (app) location in the SAS logical folder tree.
|
|
6
|
+
|
|
7
|
+
When building apps for use in other environments, you do not necessarily know
|
|
8
|
+
where the backend services will be deployed. Therefore a function like this
|
|
9
|
+
is handy in order to dynamically figure out the appLoc, and enable other
|
|
10
|
+
services to be connected by a relative reference.
|
|
11
|
+
|
|
12
|
+
SASjs apps always have the same immediate substructure (one or more of the
|
|
13
|
+
following):
|
|
14
|
+
|
|
15
|
+
@li /data
|
|
16
|
+
@li /jobs
|
|
17
|
+
@li /services
|
|
18
|
+
@li /tests
|
|
19
|
+
@li /tests/jobs
|
|
20
|
+
@li /tests/services
|
|
21
|
+
@li /tests/macros
|
|
22
|
+
|
|
23
|
+
This function works by testing for the existence of any of the above in the
|
|
24
|
+
automatic _program variable, and returning the part to the left of it.
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
|
|
28
|
+
%put %mf_getapploc(&_program)
|
|
29
|
+
|
|
30
|
+
%put %mf_getapploc(/some/location/services/admin/myservice);
|
|
31
|
+
%put %mf_getapploc(/some/location/jobs/extract/somejob/);
|
|
32
|
+
%put %mf_getapploc(/some/location/tests/jobs/somejob/);
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@author Allan Bowe
|
|
36
|
+
**/
|
|
37
|
+
|
|
38
|
+
%macro mf_getapploc(pgm);
|
|
39
|
+
%if "&pgm"="" %then %do;
|
|
40
|
+
%if %symexist(_program) %then %let pgm=&_program;
|
|
41
|
+
%else %do;
|
|
42
|
+
%put &sysmacroname: No value provided and no _program variable available;
|
|
43
|
+
%return;
|
|
44
|
+
%end;
|
|
45
|
+
%end;
|
|
46
|
+
%local root;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* First check we are not in the tests/macros folder (which has no subfolders)
|
|
50
|
+
* or specifically in the testsetup or testteardown services
|
|
51
|
+
*/
|
|
52
|
+
%if %index(&pgm,/tests/macros/)
|
|
53
|
+
or %index(&pgm,/tests/testsetup)
|
|
54
|
+
or %index(&pgm,/tests/testteardown)
|
|
55
|
+
%then %do;
|
|
56
|
+
%let root=%substr(&pgm,1,%index(&pgm,/tests)-1);
|
|
57
|
+
&root
|
|
58
|
+
%return;
|
|
59
|
+
%end;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Next, move up two levels to avoid matches on subfolder or service name
|
|
63
|
+
*/
|
|
64
|
+
%let root=%substr(&pgm,1,%length(&pgm)-%length(%scan(&pgm,-1,/))-1);
|
|
65
|
+
%let root=%substr(&root,1,%length(&root)-%length(%scan(&root,-1,/))-1);
|
|
66
|
+
|
|
67
|
+
%if %index(&root,/tests/) %then %do;
|
|
68
|
+
%let root=%substr(&root,1,%index(&root,/tests/)-1);
|
|
69
|
+
%end;
|
|
70
|
+
%else %if %index(&root,/services) %then %do;
|
|
71
|
+
%let root=%substr(&root,1,%index(&root,/services)-1);
|
|
72
|
+
%end;
|
|
73
|
+
%else %if %index(&root,/jobs) %then %do;
|
|
74
|
+
%let root=%substr(&root,1,%index(&root,/jobs)-1);
|
|
75
|
+
%end;
|
|
76
|
+
%else %put &sysmacroname: Could not find an app location from &pgm;
|
|
77
|
+
&root
|
|
78
|
+
%mend mf_getapploc ;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns a character attribute of a dataset.
|
|
4
|
+
@details Can be used in open code, eg as follows:
|
|
5
|
+
|
|
6
|
+
%put Dataset label = %mf_getattrc(sashelp.class,LABEL);
|
|
7
|
+
%put Member Type = %mf_getattrc(sashelp.class,MTYPE);
|
|
8
|
+
|
|
9
|
+
@param libds library.dataset
|
|
10
|
+
@param attr full list in [documentation](
|
|
11
|
+
https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000147794.htm)
|
|
12
|
+
@return output returns result of the attrc value supplied, or -1 and log
|
|
13
|
+
message if err.
|
|
14
|
+
|
|
15
|
+
@version 9.2
|
|
16
|
+
@author Allan Bowe
|
|
17
|
+
**/
|
|
18
|
+
|
|
19
|
+
%macro mf_getattrc(
|
|
20
|
+
libds
|
|
21
|
+
,attr
|
|
22
|
+
)/*/STORE SOURCE*/;
|
|
23
|
+
%local dsid rc;
|
|
24
|
+
%let dsid=%sysfunc(open(&libds,is));
|
|
25
|
+
%if &dsid = 0 %then %do;
|
|
26
|
+
%put %str(WARN)ING: Cannot open %trim(&libds), system message below;
|
|
27
|
+
%put %sysfunc(sysmsg());
|
|
28
|
+
-1
|
|
29
|
+
%end;
|
|
30
|
+
%else %do;
|
|
31
|
+
%sysfunc(attrc(&dsid,&attr))
|
|
32
|
+
%let rc=%sysfunc(close(&dsid));
|
|
33
|
+
%end;
|
|
34
|
+
%mend mf_getattrc;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns a numeric attribute of a dataset.
|
|
4
|
+
@details Can be used in open code, eg as follows:
|
|
5
|
+
|
|
6
|
+
%put Number of observations=%mf_getattrn(sashelp.class,NLOBS);
|
|
7
|
+
%put Number of variables = %mf_getattrn(sashelp.class,NVARS);
|
|
8
|
+
|
|
9
|
+
@param libds library.dataset
|
|
10
|
+
@param attr Common values are NLOBS and NVARS, full list in [documentation](
|
|
11
|
+
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212040.htm)
|
|
12
|
+
@return output returns result of the attrn value supplied, or -1 and log
|
|
13
|
+
message if err.
|
|
14
|
+
|
|
15
|
+
@version 9.2
|
|
16
|
+
@author Allan Bowe
|
|
17
|
+
**/
|
|
18
|
+
|
|
19
|
+
%macro mf_getattrn(
|
|
20
|
+
libds
|
|
21
|
+
,attr
|
|
22
|
+
)/*/STORE SOURCE*/;
|
|
23
|
+
%local dsid rc;
|
|
24
|
+
%let dsid=%sysfunc(open(&libds,is));
|
|
25
|
+
%if &dsid = 0 %then %do;
|
|
26
|
+
%put %str(WARN)ING: Cannot open %trim(&libds), system message below;
|
|
27
|
+
%put %sysfunc(sysmsg());
|
|
28
|
+
-1
|
|
29
|
+
%end;
|
|
30
|
+
%else %do;
|
|
31
|
+
%sysfunc(attrn(&dsid,&attr))
|
|
32
|
+
%let rc=%sysfunc(close(&dsid));
|
|
33
|
+
%end;
|
|
34
|
+
%mend mf_getattrn;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the engine type of a SAS library
|
|
4
|
+
@details Usage:
|
|
5
|
+
|
|
6
|
+
%put %mf_getengine(SASHELP);
|
|
7
|
+
|
|
8
|
+
returns:
|
|
9
|
+
> V9
|
|
10
|
+
|
|
11
|
+
A note is also written to the log. The credit for this macro goes to the
|
|
12
|
+
contributors of Chris Hemedingers blog [post](
|
|
13
|
+
http://blogs.sas.com/content/sasdummy/2013/06/04/find-a-sas-library-engine/)
|
|
14
|
+
|
|
15
|
+
@param [in] libref Library reference (also accepts a 2 level libds ref).
|
|
16
|
+
|
|
17
|
+
@return output returns the library engine (uppercase) for the FIRST library
|
|
18
|
+
encountered.
|
|
19
|
+
|
|
20
|
+
@warning will only return the FIRST library engine - for concatenated
|
|
21
|
+
libraries, with different engines, inconsistent results may be encountered.
|
|
22
|
+
|
|
23
|
+
@version 9.2
|
|
24
|
+
@author Allan Bowe
|
|
25
|
+
|
|
26
|
+
<h4> Related Macros </h4>
|
|
27
|
+
@li mf_getxengine.sas
|
|
28
|
+
|
|
29
|
+
**/
|
|
30
|
+
/** @cond */
|
|
31
|
+
|
|
32
|
+
%macro mf_getengine(libref
|
|
33
|
+
)/*/STORE SOURCE*/;
|
|
34
|
+
%local dsid engnum rc engine;
|
|
35
|
+
|
|
36
|
+
/* in case the parameter is a libref.tablename, pull off just the libref */
|
|
37
|
+
%let libref = %upcase(%scan(&libref, 1, %str(.)));
|
|
38
|
+
|
|
39
|
+
%let dsid=%sysfunc(
|
|
40
|
+
open(sashelp.vlibnam(where=(libname="%upcase(&libref)")),i)
|
|
41
|
+
);
|
|
42
|
+
%if (&dsid ^= 0) %then %do;
|
|
43
|
+
%let engnum=%sysfunc(varnum(&dsid,ENGINE));
|
|
44
|
+
%let rc=%sysfunc(fetch(&dsid));
|
|
45
|
+
%let engine=%sysfunc(getvarc(&dsid,&engnum));
|
|
46
|
+
%put &libref. ENGINE is &engine.;
|
|
47
|
+
%let rc= %sysfunc(close(&dsid));
|
|
48
|
+
%end;
|
|
49
|
+
|
|
50
|
+
%upcase(&engine)
|
|
51
|
+
|
|
52
|
+
%mend mf_getengine;
|
|
53
|
+
|
|
54
|
+
/** @endcond */
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the size of a file in bytes.
|
|
4
|
+
@details Provide full path/filename.extension to the file, eg:
|
|
5
|
+
|
|
6
|
+
%put %mf_getfilesize(fpath=C:\temp\myfile.txt);
|
|
7
|
+
|
|
8
|
+
or, provide a libds value as follows:
|
|
9
|
+
|
|
10
|
+
data x;do x=1 to 100000;y=x;output;end;run;
|
|
11
|
+
%put %mf_getfilesize(libds=work.x,format=yes);
|
|
12
|
+
|
|
13
|
+
Which gives:
|
|
14
|
+
|
|
15
|
+
> 2mb
|
|
16
|
+
|
|
17
|
+
@param [in] fpath= Full path and filename. Provide this OR the libds value.
|
|
18
|
+
@param [in] libds= (0) Library.dataset value (assumes library is BASE engine)
|
|
19
|
+
@param [in] format= (NO) Set to yes to apply sizekmg. format
|
|
20
|
+
|
|
21
|
+
@returns bytes
|
|
22
|
+
|
|
23
|
+
@version 9.2
|
|
24
|
+
@author Allan Bowe
|
|
25
|
+
**/
|
|
26
|
+
|
|
27
|
+
%macro mf_getfilesize(fpath=,libds=0,format=NO
|
|
28
|
+
)/*/STORE SOURCE*/;
|
|
29
|
+
|
|
30
|
+
%local rc fid fref bytes dsid lib vnum;
|
|
31
|
+
|
|
32
|
+
%if &libds ne 0 %then %do;
|
|
33
|
+
%let libds=%upcase(&libds);
|
|
34
|
+
%if %index(&libds,.)=0 %then %let lib=WORK;
|
|
35
|
+
%else %let lib=%scan(&libds,1,.);
|
|
36
|
+
%let dsid=%sysfunc(open(
|
|
37
|
+
sashelp.vtable(where=(libname="&lib" and memname="%scan(&libds,-1,.)")
|
|
38
|
+
keep=libname memname filesize
|
|
39
|
+
)
|
|
40
|
+
));
|
|
41
|
+
%if (&dsid ^= 0) %then %do;
|
|
42
|
+
%let vnum=%sysfunc(varnum(&dsid,FILESIZE));
|
|
43
|
+
%let rc=%sysfunc(fetch(&dsid));
|
|
44
|
+
%let bytes=%sysfunc(getvarn(&dsid,&vnum));
|
|
45
|
+
%let rc= %sysfunc(close(&dsid));
|
|
46
|
+
%end;
|
|
47
|
+
%else %put &sysmacroname: &libds could not be opened! %sysfunc(sysmsg());
|
|
48
|
+
%end;
|
|
49
|
+
%else %do;
|
|
50
|
+
%let rc=%sysfunc(filename(fref,&fpath));
|
|
51
|
+
%let fid=%sysfunc(fopen(&fref));
|
|
52
|
+
%let bytes=%sysfunc(finfo(&fid,File Size (bytes)));
|
|
53
|
+
%let rc=%sysfunc(fclose(&fid));
|
|
54
|
+
%let rc=%sysfunc(filename(fref));
|
|
55
|
+
%end;
|
|
56
|
+
|
|
57
|
+
%if &format=NO %then %do;
|
|
58
|
+
&bytes
|
|
59
|
+
%end;
|
|
60
|
+
%else %do;
|
|
61
|
+
%sysfunc(INPUTN(&bytes, best.),sizekmg.)
|
|
62
|
+
%end;
|
|
63
|
+
|
|
64
|
+
%mend mf_getfilesize ;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns a distinct list of formats from a table
|
|
4
|
+
@details Reads the dataset header and returns a distinct list of formats
|
|
5
|
+
applied.
|
|
6
|
+
|
|
7
|
+
%put NOTE- %mf_getfmtlist(sashelp.prdsale);
|
|
8
|
+
%put NOTE- %mf_getfmtlist(sashelp.shoes);
|
|
9
|
+
%put NOTE- %mf_getfmtlist(sashelp.demographics);
|
|
10
|
+
|
|
11
|
+
returns:
|
|
12
|
+
|
|
13
|
+
> DOLLAR $CHAR W MONNAME
|
|
14
|
+
> $CHAR BEST DOLLAR
|
|
15
|
+
> BEST Z $CHAR COMMA PERCENTN
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@param [in] libds Two part library.dataset reference.
|
|
19
|
+
|
|
20
|
+
<h4> SAS Macros </h4>
|
|
21
|
+
@li mf_getfmtname.sas
|
|
22
|
+
|
|
23
|
+
@version 9.2
|
|
24
|
+
@author Allan Bowe
|
|
25
|
+
|
|
26
|
+
**/
|
|
27
|
+
|
|
28
|
+
%macro mf_getfmtlist(libds
|
|
29
|
+
)/*/STORE SOURCE*/;
|
|
30
|
+
/* declare local vars */
|
|
31
|
+
%local out dsid nvars x rc fmt;
|
|
32
|
+
|
|
33
|
+
/* open dataset in macro */
|
|
34
|
+
%let dsid=%sysfunc(open(&libds));
|
|
35
|
+
|
|
36
|
+
/* continue if dataset exists */
|
|
37
|
+
%if &dsid %then %do;
|
|
38
|
+
/* loop each variable in the dataset */
|
|
39
|
+
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
|
40
|
+
%do x=1 %to &nvars;
|
|
41
|
+
/* grab format and check it exists */
|
|
42
|
+
%let fmt=%sysfunc(varfmt(&dsid,&x));
|
|
43
|
+
%if %quote(&fmt) ne %quote() %then %let fmt=%mf_getfmtname(&fmt);
|
|
44
|
+
%else %do;
|
|
45
|
+
/* assign default format depending on variable type */
|
|
46
|
+
%if %sysfunc(vartype(&dsid, &x))=C %then %let fmt=$CHAR;
|
|
47
|
+
%else %let fmt=BEST;
|
|
48
|
+
%end;
|
|
49
|
+
/* concatenate unique list of formats */
|
|
50
|
+
%if %sysfunc(indexw(&out,&fmt,%str( )))=0 %then %let out=&out &fmt;
|
|
51
|
+
%end;
|
|
52
|
+
%let rc=%sysfunc(close(&dsid));
|
|
53
|
+
%end;
|
|
54
|
+
%else %do;
|
|
55
|
+
%put &sysmacroname: Unable to open &libds (rc=&dsid);
|
|
56
|
+
%put &sysmacroname: SYSMSG= %sysfunc(sysmsg());
|
|
57
|
+
%let rc=%sysfunc(close(&dsid));
|
|
58
|
+
%end;
|
|
59
|
+
/* send them out without spaces or quote markers */
|
|
60
|
+
%do;%unquote(&out)%end;
|
|
61
|
+
%mend mf_getfmtlist;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Extracts a format name from a fully defined format
|
|
4
|
+
@details Converts formats in like $thi3. and th13.2 $THI and TH.
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
%put %mf_getfmtname(8.);
|
|
8
|
+
%put %mf_getfmtname($4.);
|
|
9
|
+
%put %mf_getfmtname(comma14.10);
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
|
|
13
|
+
> W
|
|
14
|
+
> $CHAR
|
|
15
|
+
> COMMA
|
|
16
|
+
|
|
17
|
+
Note that system defaults are inferred from the values provided.
|
|
18
|
+
|
|
19
|
+
@param [in] fmt The fully defined format. If left blank, nothing is returned.
|
|
20
|
+
|
|
21
|
+
@returns The name (without width or decimal) of the format.
|
|
22
|
+
|
|
23
|
+
@version 9.2
|
|
24
|
+
@author Allan Bowe
|
|
25
|
+
|
|
26
|
+
**/
|
|
27
|
+
|
|
28
|
+
%macro mf_getfmtname(fmt
|
|
29
|
+
)/*/STORE SOURCE*/ /minoperator mindelimiter=' ';
|
|
30
|
+
|
|
31
|
+
%local out dsid nvars x rc fmt;
|
|
32
|
+
|
|
33
|
+
/* extract actual format name from the format definition */
|
|
34
|
+
%let fmt=%scan(&fmt,1,.);
|
|
35
|
+
%do %while(%substr(&fmt,%length(&fmt),1) in 1 2 3 4 5 6 7 8 9 0);
|
|
36
|
+
%if %length(&fmt)=1 %then %let fmt=W;
|
|
37
|
+
%else %let fmt=%substr(&fmt,1,%length(&fmt)-1);
|
|
38
|
+
%end;
|
|
39
|
+
|
|
40
|
+
%if &fmt=$ %then %let fmt=$CHAR;
|
|
41
|
+
|
|
42
|
+
/* send them out without spaces or quote markers */
|
|
43
|
+
%do;%unquote(%upcase(&fmt))%end;
|
|
44
|
+
%mend mf_getfmtname;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief retrieves a key value pair from a control dataset
|
|
4
|
+
@details By default, control dataset is work.mp_setkeyvalue. Usage:
|
|
5
|
+
|
|
6
|
+
%mp_setkeyvalue(someindex,22,type=N)
|
|
7
|
+
%put %mf_getkeyvalue(someindex)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@param key Provide a key on which to perform the lookup
|
|
11
|
+
@param libds= define the target table which holds the parameters
|
|
12
|
+
|
|
13
|
+
@version 9.2
|
|
14
|
+
@author Allan Bowe
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
%macro mf_getkeyvalue(key,libds=work.mp_setkeyvalue
|
|
18
|
+
)/*/STORE SOURCE*/;
|
|
19
|
+
%local ds dsid key valc valn type rc;
|
|
20
|
+
%let dsid=%sysfunc(open(&libds(where=(key="&key"))));
|
|
21
|
+
%syscall set(dsid);
|
|
22
|
+
%let rc = %sysfunc(fetch(&dsid));
|
|
23
|
+
%let rc = %sysfunc(close(&dsid));
|
|
24
|
+
|
|
25
|
+
%if &type=N %then %do;
|
|
26
|
+
&valn
|
|
27
|
+
%end;
|
|
28
|
+
%else %if &type=C %then %do;
|
|
29
|
+
&valc
|
|
30
|
+
%end;
|
|
31
|
+
%else %put %str(ERR)OR: Unable to find key &key in ds &libds;
|
|
32
|
+
%mend mf_getkeyvalue;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file mf_getplatform.sas
|
|
3
|
+
@brief Returns platform specific variables
|
|
4
|
+
@details Enables platform specific variables to be returned
|
|
5
|
+
|
|
6
|
+
%put %mf_getplatform();
|
|
7
|
+
|
|
8
|
+
returns one of:
|
|
9
|
+
|
|
10
|
+
@li SASMETA
|
|
11
|
+
@li SASVIYA
|
|
12
|
+
@li SASJS
|
|
13
|
+
@li BASESAS
|
|
14
|
+
|
|
15
|
+
@param switch the param for which to return a platform specific variable
|
|
16
|
+
|
|
17
|
+
<h4> SAS Macros </h4>
|
|
18
|
+
@li mf_mval.sas
|
|
19
|
+
@li mf_trimstr.sas
|
|
20
|
+
|
|
21
|
+
@version 9.4 / 3.4
|
|
22
|
+
@author Allan Bowe
|
|
23
|
+
**/
|
|
24
|
+
|
|
25
|
+
%macro mf_getplatform(switch
|
|
26
|
+
)/*/STORE SOURCE*/;
|
|
27
|
+
%local a b c;
|
|
28
|
+
%if &switch.NONE=NONE %then %do;
|
|
29
|
+
%if %symexist(sasjsprocessmode) %then %do;
|
|
30
|
+
%if &sasjsprocessmode=Stored Program %then %do;
|
|
31
|
+
SASJS
|
|
32
|
+
%return;
|
|
33
|
+
%end;
|
|
34
|
+
%end;
|
|
35
|
+
%if %symexist(sysprocessmode) %then %do;
|
|
36
|
+
%if "&sysprocessmode"="SAS Object Server"
|
|
37
|
+
or "&sysprocessmode"= "SAS Compute Server" %then %do;
|
|
38
|
+
SASVIYA
|
|
39
|
+
%end;
|
|
40
|
+
%else %if "&sysprocessmode"="SAS Stored Process Server"
|
|
41
|
+
or "&sysprocessmode"="SAS Workspace Server"
|
|
42
|
+
%then %do;
|
|
43
|
+
SASMETA
|
|
44
|
+
%return;
|
|
45
|
+
%end;
|
|
46
|
+
%else %do;
|
|
47
|
+
BASESAS
|
|
48
|
+
%return;
|
|
49
|
+
%end;
|
|
50
|
+
%end;
|
|
51
|
+
%else %if %symexist(_metaport) or %symexist(_metauser) %then %do;
|
|
52
|
+
SASMETA
|
|
53
|
+
%return;
|
|
54
|
+
%end;
|
|
55
|
+
%else %do;
|
|
56
|
+
BASESAS
|
|
57
|
+
%return;
|
|
58
|
+
%end;
|
|
59
|
+
%end;
|
|
60
|
+
%else %if &switch=SASSTUDIO %then %do;
|
|
61
|
+
/* return the version of SAS Studio else 0 */
|
|
62
|
+
%if %mf_mval(_CLIENTAPP)=%str(SAS Studio) %then %do;
|
|
63
|
+
%let a=%mf_mval(_CLIENTVERSION);
|
|
64
|
+
%let b=%scan(&a,1,.);
|
|
65
|
+
%if %eval(&b >2) %then %do;
|
|
66
|
+
&b
|
|
67
|
+
%end;
|
|
68
|
+
%else 0;
|
|
69
|
+
%end;
|
|
70
|
+
%else 0;
|
|
71
|
+
%end;
|
|
72
|
+
%else %if &switch=VIYARESTAPI %then %do;
|
|
73
|
+
%mf_trimstr(%sysfunc(getoption(servicesbaseurl)),/)
|
|
74
|
+
%end;
|
|
75
|
+
%mend mf_getplatform;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Adds custom quotes / delimiters to a delimited string
|
|
4
|
+
@details Can be used in open code, eg as follows:
|
|
5
|
+
|
|
6
|
+
%put %mf_getquotedstr(blah blah blah);
|
|
7
|
+
|
|
8
|
+
which returns:
|
|
9
|
+
> 'blah','blah','blah'
|
|
10
|
+
|
|
11
|
+
Alternatively:
|
|
12
|
+
|
|
13
|
+
%put %mf_getquotedstr(these words are double quoted,quote=D)
|
|
14
|
+
|
|
15
|
+
for:
|
|
16
|
+
> "these","words","are","double","quoted"
|
|
17
|
+
|
|
18
|
+
@param [in] in_str The unquoted, spaced delimited string to transform
|
|
19
|
+
@param [in] dlm= (,) The delimeter to be applied to the output (default comma)
|
|
20
|
+
@param [in] indlm= ( ) The delimeter used for the input (default is space)
|
|
21
|
+
@param [in] quote= (S) The quote mark to apply (S=Single, D=Double, N=None).
|
|
22
|
+
If any other value than uppercase S or D is supplied, then that value will
|
|
23
|
+
be used as the quoting character.
|
|
24
|
+
@return output returns a string with the newly quoted / delimited output.
|
|
25
|
+
|
|
26
|
+
@version 9.2
|
|
27
|
+
@author Allan Bowe
|
|
28
|
+
**/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
%macro mf_getquotedstr(IN_STR
|
|
32
|
+
,DLM=%str(,)
|
|
33
|
+
,QUOTE=S
|
|
34
|
+
,indlm=%str( )
|
|
35
|
+
)/*/STORE SOURCE*/;
|
|
36
|
+
/* credit Rowland Hale - byte34 is double quote, 39 is single quote */
|
|
37
|
+
%if "e=S %then %let quote=%qsysfunc(byte(39));
|
|
38
|
+
%else %if "e=D %then %let quote=%qsysfunc(byte(34));
|
|
39
|
+
%else %if "e=N %then %let quote=;
|
|
40
|
+
%local i item buffer;
|
|
41
|
+
%let i=1;
|
|
42
|
+
%do %while (%qscan(&IN_STR,&i,%str(&indlm)) ne %str() ) ;
|
|
43
|
+
%let item=%qscan(&IN_STR,&i,%str(&indlm));
|
|
44
|
+
%if %bquote("E) ne %then %let item="E%qtrim(&item)"E;
|
|
45
|
+
%else %let item=%qtrim(&item);
|
|
46
|
+
|
|
47
|
+
%if (&i = 1) %then %let buffer =%qtrim(&item);
|
|
48
|
+
%else %let buffer =&buffer&DLM%qtrim(&item);
|
|
49
|
+
|
|
50
|
+
%let i = %eval(&i+1);
|
|
51
|
+
%end;
|
|
52
|
+
|
|
53
|
+
%let buffer=%sysfunc(coalescec(%qtrim(&buffer),"E"E));
|
|
54
|
+
|
|
55
|
+
&buffer
|
|
56
|
+
|
|
57
|
+
%mend mf_getquotedstr;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file mf_getschema.sas
|
|
3
|
+
@brief Returns the database schema of a SAS library
|
|
4
|
+
@details Usage:
|
|
5
|
+
|
|
6
|
+
%put %mf_getschema(MYDB);
|
|
7
|
+
|
|
8
|
+
returns:
|
|
9
|
+
> dbo
|
|
10
|
+
|
|
11
|
+
@param libref Library reference (also accepts a 2 level libds ref).
|
|
12
|
+
|
|
13
|
+
@return output returns the library schema for the FIRST library encountered
|
|
14
|
+
|
|
15
|
+
@warning will only return the FIRST library schema - for concatenated
|
|
16
|
+
libraries, with different schemas, inconsistent results may be encountered.
|
|
17
|
+
|
|
18
|
+
@version 9.2
|
|
19
|
+
@author Allan Bowe
|
|
20
|
+
@cond
|
|
21
|
+
**/
|
|
22
|
+
|
|
23
|
+
%macro mf_getschema(libref
|
|
24
|
+
)/*/STORE SOURCE*/;
|
|
25
|
+
%local dsid vnum rc schema;
|
|
26
|
+
/* in case the parameter is a libref.tablename, pull off just the libref */
|
|
27
|
+
%let libref = %upcase(%scan(&libref, 1, %str(.)));
|
|
28
|
+
%let dsid=%sysfunc(open(sashelp.vlibnam(where=(
|
|
29
|
+
libname="%upcase(&libref)" and sysname='Schema/Owner'
|
|
30
|
+
)),i));
|
|
31
|
+
%if (&dsid ^= 0) %then %do;
|
|
32
|
+
%let vnum=%sysfunc(varnum(&dsid,SYSVALUE));
|
|
33
|
+
%let rc=%sysfunc(fetch(&dsid));
|
|
34
|
+
%let schema=%sysfunc(getvarc(&dsid,&vnum));
|
|
35
|
+
%put &libref. schema is &schema.;
|
|
36
|
+
%let rc= %sysfunc(close(&dsid));
|
|
37
|
+
%end;
|
|
38
|
+
|
|
39
|
+
&schema
|
|
40
|
+
|
|
41
|
+
%mend mf_getschema;
|
|
42
|
+
|
|
43
|
+
/** @endcond */
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Assigns and returns an unused fileref
|
|
4
|
+
@details Using the native approach for assigning filerefs fails as some
|
|
5
|
+
procedures (such as proc http) do not recognise the temporary names (starting
|
|
6
|
+
with a hash), returning a message such as:
|
|
7
|
+
|
|
8
|
+
> ERROR 22-322: Expecting a name.
|
|
9
|
+
|
|
10
|
+
This macro works by attempting a random fileref (with a prefix), seeing if it
|
|
11
|
+
is already assigned, and if not - returning the fileref.
|
|
12
|
+
|
|
13
|
+
If your process can accept filerefs with the hash (#) prefix, then set
|
|
14
|
+
`prefix=0` to revert to the native approach - which is significantly faster
|
|
15
|
+
when there are a lot of filerefs in a session.
|
|
16
|
+
|
|
17
|
+
Use as follows:
|
|
18
|
+
|
|
19
|
+
%let fileref1=%mf_getuniquefileref();
|
|
20
|
+
%let fileref2=%mf_getuniquefileref(prefix=0);
|
|
21
|
+
%put &fileref1 &fileref2;
|
|
22
|
+
|
|
23
|
+
which returns filerefs similar to:
|
|
24
|
+
|
|
25
|
+
> _7432233 #LN00070
|
|
26
|
+
|
|
27
|
+
@param [in] prefix= (_) first part of fileref. Remember that filerefs can only
|
|
28
|
+
be 8 characters, so a 7 letter prefix would mean `maxtries` should be 10.
|
|
29
|
+
if using zero (0) as the prefix, a native assignment is used.
|
|
30
|
+
@param [in] maxtries= (1000) the last part of the libref. Must be an integer.
|
|
31
|
+
@param [in] lrecl= (32767) Provide a default lrecl with which to initialise
|
|
32
|
+
the generated fileref.
|
|
33
|
+
|
|
34
|
+
@version 9.2
|
|
35
|
+
@author Allan Bowe
|
|
36
|
+
**/
|
|
37
|
+
|
|
38
|
+
%macro mf_getuniquefileref(prefix=_,maxtries=1000,lrecl=32767);
|
|
39
|
+
%local rc fname;
|
|
40
|
+
%if &prefix=0 %then %do;
|
|
41
|
+
%let rc=%sysfunc(filename(fname,,temp,lrecl=&lrecl));
|
|
42
|
+
%if &rc %then %put %sysfunc(sysmsg());
|
|
43
|
+
&fname
|
|
44
|
+
%end;
|
|
45
|
+
%else %do;
|
|
46
|
+
%local x len;
|
|
47
|
+
%let len=%eval(8-%length(&prefix));
|
|
48
|
+
%let x=0;
|
|
49
|
+
%do x=0 %to &maxtries;
|
|
50
|
+
%let fname=&prefix%substr(%sysfunc(ranuni(0)),3,&len);
|
|
51
|
+
%if %sysfunc(fileref(&fname)) > 0 %then %do;
|
|
52
|
+
%let rc=%sysfunc(filename(fname,,temp,lrecl=&lrecl));
|
|
53
|
+
%if &rc %then %put %sysfunc(sysmsg());
|
|
54
|
+
&fname
|
|
55
|
+
%return;
|
|
56
|
+
%end;
|
|
57
|
+
%end;
|
|
58
|
+
%put unable to find available fileref after &maxtries attempts;
|
|
59
|
+
%end;
|
|
60
|
+
%mend mf_getuniquefileref;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns an unused libref
|
|
4
|
+
@details Use as follows:
|
|
5
|
+
|
|
6
|
+
libname mclib0 (work);
|
|
7
|
+
libname mclib1 (work);
|
|
8
|
+
libname mclib2 (work);
|
|
9
|
+
|
|
10
|
+
%let libref=%mf_getuniquelibref();
|
|
11
|
+
%put &=libref;
|
|
12
|
+
|
|
13
|
+
which returns:
|
|
14
|
+
|
|
15
|
+
> mclib3
|
|
16
|
+
|
|
17
|
+
A blank value is returned if no usable libname is determined.
|
|
18
|
+
|
|
19
|
+
@param [in] prefix= (mclib) first part of the returned libref. As librefs can
|
|
20
|
+
be as long as 8 characters, a maximum length of 7 characters is premitted
|
|
21
|
+
for this prefix.
|
|
22
|
+
@param [in] maxtries= Deprecated parameter. Remains here to ensure a
|
|
23
|
+
non-breaking change. Will be removed in v5.
|
|
24
|
+
|
|
25
|
+
@version 9.2
|
|
26
|
+
@author Allan Bowe
|
|
27
|
+
**/
|
|
28
|
+
|
|
29
|
+
%macro mf_getuniquelibref(prefix=mclib,maxtries=1000);
|
|
30
|
+
%local x;
|
|
31
|
+
|
|
32
|
+
%if ( %length(&prefix) gt 7 ) %then %do;
|
|
33
|
+
%put %str(ERR)OR: The prefix parameter cannot exceed 7 characters.;
|
|
34
|
+
0
|
|
35
|
+
%return;
|
|
36
|
+
%end;
|
|
37
|
+
%else %if (%sysfunc(NVALID(&prefix,v7))=0) %then %do;
|
|
38
|
+
%put %str(ERR)OR: Invalid prefix (&prefix);
|
|
39
|
+
0
|
|
40
|
+
%return;
|
|
41
|
+
%end;
|
|
42
|
+
|
|
43
|
+
/* Set maxtries equal to '10 to the power of [# unused characters] - 1' */
|
|
44
|
+
%let maxtries=%eval(10**(8-%length(&prefix))-1);
|
|
45
|
+
|
|
46
|
+
%do x = 0 %to &maxtries;
|
|
47
|
+
%if %sysfunc(libref(&prefix&x)) ne 0 %then %do;
|
|
48
|
+
&prefix&x
|
|
49
|
+
%return;
|
|
50
|
+
%end;
|
|
51
|
+
%let x = %eval(&x + 1);
|
|
52
|
+
%end;
|
|
53
|
+
|
|
54
|
+
%put %str(ERR)OR: No usable libref in range &prefix.0-&maxtries;
|
|
55
|
+
%put %str(ERR)OR- Try reducing the prefix or deleting some libraries!;
|
|
56
|
+
0
|
|
57
|
+
%mend mf_getuniquelibref;
|