@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,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file mf_getuniquename.sas
|
|
3
|
+
@brief Returns a shortened (32 char) GUID as a valid SAS name
|
|
4
|
+
@details Use as follows:
|
|
5
|
+
|
|
6
|
+
%let myds=%mf_getuniquename();
|
|
7
|
+
%put &=myds;
|
|
8
|
+
|
|
9
|
+
which returns:
|
|
10
|
+
|
|
11
|
+
> MCc59c750610321d4c8bf75faadbcd22
|
|
12
|
+
|
|
13
|
+
@param prefix= set a prefix for the new name
|
|
14
|
+
|
|
15
|
+
@version 9.3
|
|
16
|
+
@author Allan Bowe
|
|
17
|
+
**/
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
%macro mf_getuniquename(prefix=MC);
|
|
21
|
+
&prefix.%substr(%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32-%length(&prefix))
|
|
22
|
+
%mend mf_getuniquename;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns a userid according to session context
|
|
4
|
+
@details In a workspace session, a user is generally represented by <code>
|
|
5
|
+
&sysuserid</code> or <code>SYS_COMPUTE_SESSION_OWNER</code> if it exists.
|
|
6
|
+
In a Stored Process session, <code>&sysuserid</code>
|
|
7
|
+
resolves to a system account (default=sassrv) and instead there are several
|
|
8
|
+
metadata username variables to choose from (_metauser, _metaperson
|
|
9
|
+
,_username, _secureusername). The OS account is represented by
|
|
10
|
+
<code> _secureusername</code> whilst the metadata account is under <code>
|
|
11
|
+
_metaperson</code>.
|
|
12
|
+
|
|
13
|
+
%let user= %mf_getUser();
|
|
14
|
+
%put &user;
|
|
15
|
+
|
|
16
|
+
@param type - do not use, may be deprecated in a future release
|
|
17
|
+
|
|
18
|
+
@return SYSUSERID (if workspace server)
|
|
19
|
+
@return _METAPERSON (if stored process server)
|
|
20
|
+
@return SYS_COMPUTE_SESSION_OWNER (if Viya compute session)
|
|
21
|
+
|
|
22
|
+
@version 9.2
|
|
23
|
+
@author Allan Bowe
|
|
24
|
+
**/
|
|
25
|
+
|
|
26
|
+
%macro mf_getuser(
|
|
27
|
+
)/*/STORE SOURCE*/;
|
|
28
|
+
%local user;
|
|
29
|
+
|
|
30
|
+
%if %symexist(_sasjs_username) %then %let user=&_sasjs_username;
|
|
31
|
+
%else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do;
|
|
32
|
+
%let user=&SYS_COMPUTE_SESSION_OWNER;
|
|
33
|
+
%end;
|
|
34
|
+
%else %if %symexist(_metaperson) %then %do;
|
|
35
|
+
%if %length(&_metaperson)=0 %then %let user=&sysuserid;
|
|
36
|
+
/* sometimes SAS will add @domain extension - remove for consistency */
|
|
37
|
+
/* but be sure to quote in case of usernames with commas */
|
|
38
|
+
%else %let user=%unquote(%scan(%quote(&_metaperson),1,@));
|
|
39
|
+
%end;
|
|
40
|
+
%else %let user=&sysuserid;
|
|
41
|
+
|
|
42
|
+
%quote(&user)
|
|
43
|
+
|
|
44
|
+
%mend mf_getuser;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Retrieves a value from a dataset. If no filter supplied, then first
|
|
4
|
+
record is used.
|
|
5
|
+
@details Be sure to <code>%quote()</code> your where clause. Example usage:
|
|
6
|
+
|
|
7
|
+
%put %mf_getvalue(sashelp.class,name,filter=%quote(age=15));
|
|
8
|
+
%put %mf_getvalue(sashelp.class,name);
|
|
9
|
+
|
|
10
|
+
<h4> SAS Macros </h4>
|
|
11
|
+
@li mf_getattrn.sas
|
|
12
|
+
|
|
13
|
+
<h4> Related Macros </h4>
|
|
14
|
+
@li mp_setkeyvalue.sas
|
|
15
|
+
|
|
16
|
+
@param libds dataset to query
|
|
17
|
+
@param variable the variable which contains the value to return.
|
|
18
|
+
@param filter contents of where clause
|
|
19
|
+
|
|
20
|
+
@version 9.2
|
|
21
|
+
@author Allan Bowe
|
|
22
|
+
**/
|
|
23
|
+
|
|
24
|
+
%macro mf_getvalue(libds,variable,filter=1
|
|
25
|
+
)/*/STORE SOURCE*/;
|
|
26
|
+
%if %mf_getattrn(&libds,NLOBS)>0 %then %do;
|
|
27
|
+
%local dsid rc &variable;
|
|
28
|
+
%let dsid=%sysfunc(open(&libds(where=(&filter))));
|
|
29
|
+
%syscall set(dsid);
|
|
30
|
+
%let rc = %sysfunc(fetch(&dsid));
|
|
31
|
+
%let rc = %sysfunc(close(&dsid));
|
|
32
|
+
|
|
33
|
+
%trim(&&&variable)
|
|
34
|
+
|
|
35
|
+
%end;
|
|
36
|
+
%mend mf_getvalue;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns number of variables in a dataset
|
|
4
|
+
@details Useful to identify those renagade datasets that have no columns!
|
|
5
|
+
Can also be used to count for numeric, or character columns
|
|
6
|
+
|
|
7
|
+
%put Number of Variables=%mf_getvarcount(sashelp.class);
|
|
8
|
+
%put Character Variables=%mf_getvarcount(sashelp.class,typefilter=C);
|
|
9
|
+
%put Numeric Variables = %mf_getvarcount(sashelp.class,typefilter=N);
|
|
10
|
+
|
|
11
|
+
returns:
|
|
12
|
+
> Number of Variables=4
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@param [in] libds Two part dataset (or view) reference.
|
|
16
|
+
@param [in] typefilter= (A) Filter for certain types of column. Valid values:
|
|
17
|
+
@li A Count All columns
|
|
18
|
+
@li C Count Character columns only
|
|
19
|
+
@li N Count Numeric columns only
|
|
20
|
+
|
|
21
|
+
@version 9.2
|
|
22
|
+
@author Allan Bowe
|
|
23
|
+
|
|
24
|
+
**/
|
|
25
|
+
|
|
26
|
+
%macro mf_getvarcount(libds,typefilter=A
|
|
27
|
+
)/*/STORE SOURCE*/;
|
|
28
|
+
%local dsid nvars rc outcnt x;
|
|
29
|
+
%let dsid=%sysfunc(open(&libds));
|
|
30
|
+
%let nvars=.;
|
|
31
|
+
%let outcnt=0;
|
|
32
|
+
%let typefilter=%upcase(&typefilter);
|
|
33
|
+
%if &dsid %then %do;
|
|
34
|
+
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
|
35
|
+
%if &typefilter=A %then %let outcnt=&nvars;
|
|
36
|
+
%else %if &nvars>0 %then %do x=1 %to &nvars;
|
|
37
|
+
/* increment based on variable type */
|
|
38
|
+
%if %sysfunc(vartype(&dsid,&x))=&typefilter %then %do;
|
|
39
|
+
%let outcnt=%eval(&outcnt+1);
|
|
40
|
+
%end;
|
|
41
|
+
%end;
|
|
42
|
+
%let rc=%sysfunc(close(&dsid));
|
|
43
|
+
%end;
|
|
44
|
+
%else %do;
|
|
45
|
+
%put unable to open &libds (rc=&dsid);
|
|
46
|
+
%let rc=%sysfunc(close(&dsid));
|
|
47
|
+
%end;
|
|
48
|
+
&outcnt
|
|
49
|
+
%mend mf_getvarcount;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the format of a variable
|
|
4
|
+
@details Uses varfmt function to identify the format of a particular variable.
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
data test;
|
|
8
|
+
format str1 $1. num1 datetime19.;
|
|
9
|
+
str2='hello mum!'; num2=666;
|
|
10
|
+
stop;
|
|
11
|
+
run;
|
|
12
|
+
%put %mf_getVarFormat(test,str1);
|
|
13
|
+
%put %mf_getVarFormat(work.test,num1);
|
|
14
|
+
%put %mf_getVarFormat(test,str2,force=1);
|
|
15
|
+
%put %mf_getVarFormat(work.test,num2,force=1);
|
|
16
|
+
%put %mf_getVarFormat(test,renegade);
|
|
17
|
+
|
|
18
|
+
returns:
|
|
19
|
+
|
|
20
|
+
$1.
|
|
21
|
+
DATETIME19.
|
|
22
|
+
$10.
|
|
23
|
+
8.
|
|
24
|
+
NOTE: Variable renegade does not exist in test
|
|
25
|
+
|
|
26
|
+
@param [in] libds Two part dataset (or view) reference.
|
|
27
|
+
@param [in] var Variable name for which a format should be returned
|
|
28
|
+
@param [in] force=(0) Set to 1 to supply a default if the variable has no format
|
|
29
|
+
@returns outputs format
|
|
30
|
+
|
|
31
|
+
@author Allan Bowe
|
|
32
|
+
@version 9.2
|
|
33
|
+
**/
|
|
34
|
+
|
|
35
|
+
%macro mf_getVarFormat(libds /* two level ds name */
|
|
36
|
+
, var /* variable name from which to return the format */
|
|
37
|
+
, force=0
|
|
38
|
+
)/*/STORE SOURCE*/;
|
|
39
|
+
%local dsid vnum vformat rc vlen vtype;
|
|
40
|
+
/* Open dataset */
|
|
41
|
+
%let dsid = %sysfunc(open(&libds));
|
|
42
|
+
%if &dsid > 0 %then %do;
|
|
43
|
+
/* Get variable number */
|
|
44
|
+
%let vnum = %sysfunc(varnum(&dsid, &var));
|
|
45
|
+
/* Get variable format */
|
|
46
|
+
%if(&vnum > 0) %then %let vformat=%sysfunc(varfmt(&dsid, &vnum));
|
|
47
|
+
%else %do;
|
|
48
|
+
%put NOTE: Variable &var does not exist in &libds;
|
|
49
|
+
%let rc = %sysfunc(close(&dsid));
|
|
50
|
+
%return;
|
|
51
|
+
%end;
|
|
52
|
+
%end;
|
|
53
|
+
%else %do;
|
|
54
|
+
%put &sysmacroname: dataset &libds not opened! (rc=&dsid);
|
|
55
|
+
%put &sysmacroname: %sysfunc(sysmsg());
|
|
56
|
+
%return;
|
|
57
|
+
%end;
|
|
58
|
+
|
|
59
|
+
/* supply a default if no format available */
|
|
60
|
+
%if %length(&vformat)<2 & &force=1 %then %do;
|
|
61
|
+
%let vlen = %sysfunc(varlen(&dsid, &vnum));
|
|
62
|
+
%let vtype = %sysfunc(vartype(&dsid, &vnum.));
|
|
63
|
+
%if &vtype=C %then %let vformat=$&vlen..;
|
|
64
|
+
%else %let vformat=best.;
|
|
65
|
+
%end;
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
/* Close dataset */
|
|
69
|
+
%let rc = %sysfunc(close(&dsid));
|
|
70
|
+
/* Return variable format */
|
|
71
|
+
&vformat
|
|
72
|
+
%mend mf_getVarFormat;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the length of a variable
|
|
4
|
+
@details Uses varlen function to identify the length of a particular variable.
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
data test;
|
|
8
|
+
format str $1. num datetime19.;
|
|
9
|
+
stop;
|
|
10
|
+
run;
|
|
11
|
+
%put %mf_getVarLen(test,str);
|
|
12
|
+
%put %mf_getVarLen(work.test,num);
|
|
13
|
+
%put %mf_getVarLen(test,renegade);
|
|
14
|
+
|
|
15
|
+
returns:
|
|
16
|
+
|
|
17
|
+
1
|
|
18
|
+
8
|
|
19
|
+
NOTE: Variable renegade does not exist in test
|
|
20
|
+
|
|
21
|
+
@param libds Two part dataset (or view) reference.
|
|
22
|
+
@param var Variable name for which a length should be returned
|
|
23
|
+
@returns outputs length
|
|
24
|
+
|
|
25
|
+
@author Allan Bowe
|
|
26
|
+
@version 9.2
|
|
27
|
+
|
|
28
|
+
**/
|
|
29
|
+
|
|
30
|
+
%macro mf_getVarLen(libds /* two level ds name */
|
|
31
|
+
, var /* variable name from which to return the length */
|
|
32
|
+
)/*/STORE SOURCE*/;
|
|
33
|
+
%local dsid vnum vlen rc;
|
|
34
|
+
/* Open dataset */
|
|
35
|
+
%let dsid = %sysfunc(open(&libds));
|
|
36
|
+
%if &dsid > 0 %then %do;
|
|
37
|
+
/* Get variable number */
|
|
38
|
+
%let vnum = %sysfunc(varnum(&dsid, &var));
|
|
39
|
+
/* Get variable format */
|
|
40
|
+
%if(&vnum > 0) %then %let vlen = %sysfunc(varlen(&dsid, &vnum));
|
|
41
|
+
%else %do;
|
|
42
|
+
%put NOTE: Variable &var does not exist in &libds;
|
|
43
|
+
%let vlen = %str( );
|
|
44
|
+
%end;
|
|
45
|
+
%end;
|
|
46
|
+
%else %do;
|
|
47
|
+
%put &sysmacroname: dataset &libds not opened! (rc=&dsid);
|
|
48
|
+
%put &sysmacroname: %sysfunc(sysmsg());
|
|
49
|
+
%return;
|
|
50
|
+
%end;
|
|
51
|
+
|
|
52
|
+
/* Close dataset */
|
|
53
|
+
%let rc = %sysfunc(close(&dsid));
|
|
54
|
+
/* Return variable format */
|
|
55
|
+
&vlen
|
|
56
|
+
%mend mf_getVarLen;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns dataset variable list direct from header
|
|
4
|
+
@details WAY faster than dictionary tables or sas views, and can
|
|
5
|
+
also be called in macro logic (is pure macro). Can be used in open code,
|
|
6
|
+
eg as follows:
|
|
7
|
+
|
|
8
|
+
%put List of Variables=%mf_getvarlist(sashelp.class);
|
|
9
|
+
|
|
10
|
+
returns:
|
|
11
|
+
> List of Variables=Name Sex Age Height Weight
|
|
12
|
+
|
|
13
|
+
For a seperated list of column values:
|
|
14
|
+
|
|
15
|
+
%put %mf_getvarlist(sashelp.class,dlm=%str(,),quote=double);
|
|
16
|
+
|
|
17
|
+
returns:
|
|
18
|
+
> "Name","Sex","Age","Height","Weight"
|
|
19
|
+
|
|
20
|
+
@param [in] libds Two part dataset (or view) reference.
|
|
21
|
+
@param [in] dlm= ( ) Provide a delimiter (eg comma or space) to separate the
|
|
22
|
+
variables
|
|
23
|
+
@param [in] quote= (none) use either DOUBLE or SINGLE to quote the results
|
|
24
|
+
@param [in] typefilter= (A) Filter for certain types of column. Valid values:
|
|
25
|
+
@li A Return All columns
|
|
26
|
+
@li C Return Character columns
|
|
27
|
+
@li N Return Numeric columns
|
|
28
|
+
|
|
29
|
+
@version 9.2
|
|
30
|
+
@author Allan Bowe
|
|
31
|
+
|
|
32
|
+
**/
|
|
33
|
+
|
|
34
|
+
%macro mf_getvarlist(libds
|
|
35
|
+
,dlm=%str( )
|
|
36
|
+
,quote=no
|
|
37
|
+
,typefilter=A
|
|
38
|
+
)/*/STORE SOURCE*/;
|
|
39
|
+
/* declare local vars */
|
|
40
|
+
%local outvar dsid nvars x rc dlm q var vtype;
|
|
41
|
+
|
|
42
|
+
/* credit Rowland Hale - byte34 is double quote, 39 is single quote */
|
|
43
|
+
%if %upcase("e)=DOUBLE %then %let q=%qsysfunc(byte(34));
|
|
44
|
+
%else %if %upcase("e)=SINGLE %then %let q=%qsysfunc(byte(39));
|
|
45
|
+
/* open dataset in macro */
|
|
46
|
+
%let dsid=%sysfunc(open(&libds));
|
|
47
|
+
|
|
48
|
+
%if &dsid %then %do;
|
|
49
|
+
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
|
50
|
+
%if &nvars>0 %then %do;
|
|
51
|
+
/* add variables with supplied delimeter */
|
|
52
|
+
%do x=1 %to &nvars;
|
|
53
|
+
/* get variable type */
|
|
54
|
+
%let vtype=%sysfunc(vartype(&dsid,&x));
|
|
55
|
+
%if &vtype=&typefilter or &typefilter=A %then %do;
|
|
56
|
+
%let var=&q.%sysfunc(varname(&dsid,&x))&q.;
|
|
57
|
+
%if &var=&q&q %then %do;
|
|
58
|
+
%put &sysmacroname: Empty column found in &libds!;
|
|
59
|
+
%let var=&q. &q.;
|
|
60
|
+
%end;
|
|
61
|
+
%if %quote(&outvar)=%quote() %then %let outvar=&var;
|
|
62
|
+
%else %let outvar=&outvar.&dlm.&var.;
|
|
63
|
+
%end;
|
|
64
|
+
%end;
|
|
65
|
+
%end;
|
|
66
|
+
%let rc=%sysfunc(close(&dsid));
|
|
67
|
+
%end;
|
|
68
|
+
%else %do;
|
|
69
|
+
%put &sysmacroname: Unable to open &libds (rc=&dsid);
|
|
70
|
+
%put &sysmacroname: SYSMSG= %sysfunc(sysmsg());
|
|
71
|
+
%let rc=%sysfunc(close(&dsid));
|
|
72
|
+
%end;
|
|
73
|
+
%do;%unquote(&outvar)%end;
|
|
74
|
+
%mend mf_getvarlist;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the position of a variable in dataset (varnum attribute).
|
|
4
|
+
@details Uses varnum function to determine position.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
|
|
8
|
+
data work.test;
|
|
9
|
+
format str $1. num datetime19.;
|
|
10
|
+
stop;
|
|
11
|
+
run;
|
|
12
|
+
%put %mf_getVarNum(work.test,str);
|
|
13
|
+
%put %mf_getVarNum(work.test,num);
|
|
14
|
+
%put %mf_getVarNum(work.test,renegade);
|
|
15
|
+
|
|
16
|
+
returns:
|
|
17
|
+
|
|
18
|
+
> 1
|
|
19
|
+
|
|
20
|
+
> 2
|
|
21
|
+
|
|
22
|
+
> NOTE: Variable renegade does not exist in test
|
|
23
|
+
|
|
24
|
+
@param libds Two part dataset (or view) reference.
|
|
25
|
+
@param var Variable name for which a position should be returned
|
|
26
|
+
|
|
27
|
+
@author Allan Bowe
|
|
28
|
+
@version 9.2
|
|
29
|
+
|
|
30
|
+
**/
|
|
31
|
+
|
|
32
|
+
%macro mf_getVarNum(libds /* two level ds name */
|
|
33
|
+
, var /* variable name from which to return the format */
|
|
34
|
+
)/*/STORE SOURCE*/;
|
|
35
|
+
%local dsid vnum rc;
|
|
36
|
+
/* Open dataset */
|
|
37
|
+
%let dsid = %sysfunc(open(&libds));
|
|
38
|
+
%if &dsid > 0 %then %do;
|
|
39
|
+
/* Get variable number */
|
|
40
|
+
%let vnum = %sysfunc(varnum(&dsid, &var));
|
|
41
|
+
%if(&vnum <= 0) %then %do;
|
|
42
|
+
%put NOTE: Variable &var does not exist in &libds;
|
|
43
|
+
%let vnum = %str( );
|
|
44
|
+
%end;
|
|
45
|
+
%end;
|
|
46
|
+
%else %do;
|
|
47
|
+
%put &sysmacroname: dataset &libds not opened! (rc=&dsid);
|
|
48
|
+
%put &sysmacroname: %sysfunc(sysmsg());
|
|
49
|
+
%return;
|
|
50
|
+
%end;
|
|
51
|
+
|
|
52
|
+
/* Close dataset */
|
|
53
|
+
%let rc = %sysfunc(close(&dsid));
|
|
54
|
+
|
|
55
|
+
/* Return variable number */
|
|
56
|
+
&vnum.
|
|
57
|
+
|
|
58
|
+
%mend mf_getVarNum;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns variable type - Character (C) or Numeric (N)
|
|
4
|
+
@details
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
data test;
|
|
8
|
+
length str $1. num 8.;
|
|
9
|
+
stop;
|
|
10
|
+
run;
|
|
11
|
+
%put %mf_getvartype(test,str);
|
|
12
|
+
%put %mf_getvartype(work.test,num);
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@param libds Two part dataset (or view) reference.
|
|
17
|
+
@param var the variable name to be checked
|
|
18
|
+
@return output returns C or N depending on variable type. If variable
|
|
19
|
+
does not exist then a blank is returned and a note is written to the log.
|
|
20
|
+
|
|
21
|
+
@version 9.2
|
|
22
|
+
@author Allan Bowe
|
|
23
|
+
|
|
24
|
+
**/
|
|
25
|
+
|
|
26
|
+
%macro mf_getvartype(libds /* two level name */
|
|
27
|
+
, var /* variable name from which to return the type */
|
|
28
|
+
)/*/STORE SOURCE*/;
|
|
29
|
+
%local dsid vnum vtype rc;
|
|
30
|
+
/* Open dataset */
|
|
31
|
+
%let dsid = %sysfunc(open(&libds));
|
|
32
|
+
%if &dsid. > 0 %then %do;
|
|
33
|
+
/* Get variable number */
|
|
34
|
+
%let vnum = %sysfunc(varnum(&dsid, &var));
|
|
35
|
+
/* Get variable type (C/N) */
|
|
36
|
+
%if(&vnum. > 0) %then %let vtype = %sysfunc(vartype(&dsid, &vnum.));
|
|
37
|
+
%else %do;
|
|
38
|
+
%put NOTE: Variable &var does not exist in &libds;
|
|
39
|
+
%let vtype = %str( );
|
|
40
|
+
%end;
|
|
41
|
+
%end;
|
|
42
|
+
%else %do;
|
|
43
|
+
%put &sysmacroname: dataset &libds not opened! (rc=&dsid);
|
|
44
|
+
%put &sysmacroname: %sysfunc(sysmsg());
|
|
45
|
+
%return;
|
|
46
|
+
%end;
|
|
47
|
+
|
|
48
|
+
/* Close dataset */
|
|
49
|
+
%let rc = %sysfunc(close(&dsid));
|
|
50
|
+
/* Return variable type */
|
|
51
|
+
&vtype
|
|
52
|
+
%mend mf_getvartype;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns the engine type of a SAS fileref
|
|
4
|
+
@details Queries sashelp.vextfl to get the xengine value.
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
filename feng temp;
|
|
8
|
+
%put %mf_getxengine(feng);
|
|
9
|
+
|
|
10
|
+
returns:
|
|
11
|
+
> TEMP
|
|
12
|
+
|
|
13
|
+
@param fref The fileref to check
|
|
14
|
+
|
|
15
|
+
@returns The XENGINE value in sashelp.vextfl or 0 if not found.
|
|
16
|
+
|
|
17
|
+
@version 9.2
|
|
18
|
+
@author Allan Bowe
|
|
19
|
+
|
|
20
|
+
<h4> Related Macros </h4>
|
|
21
|
+
@li mf_getengine.sas
|
|
22
|
+
|
|
23
|
+
**/
|
|
24
|
+
|
|
25
|
+
%macro mf_getxengine(fref
|
|
26
|
+
)/*/STORE SOURCE*/;
|
|
27
|
+
%local dsid engnum rc engine;
|
|
28
|
+
|
|
29
|
+
%let dsid=%sysfunc(
|
|
30
|
+
open(sashelp.vextfl(where=(fileref="%upcase(&fref)")),i)
|
|
31
|
+
);
|
|
32
|
+
%if (&dsid ^= 0) %then %do;
|
|
33
|
+
%let engnum=%sysfunc(varnum(&dsid,XENGINE));
|
|
34
|
+
%let rc=%sysfunc(fetch(&dsid));
|
|
35
|
+
%let engine=%sysfunc(getvarc(&dsid,&engnum));
|
|
36
|
+
%* put &fref. ENGINE is &engine.;
|
|
37
|
+
%let rc= %sysfunc(close(&dsid));
|
|
38
|
+
%end;
|
|
39
|
+
%else %let engine=0;
|
|
40
|
+
|
|
41
|
+
&engine
|
|
42
|
+
|
|
43
|
+
%mend mf_getxengine;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Increments a macro variable
|
|
4
|
+
@details Useful outside of do-loops - will increment a macro variable every
|
|
5
|
+
time it is called.
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
|
|
9
|
+
%let cnt=1;
|
|
10
|
+
%put We have run %mf_increment(cnt) lines;
|
|
11
|
+
%put Now we have run %mf_increment(cnt) lines;
|
|
12
|
+
%put There are %mf_increment(cnt) lines in total;
|
|
13
|
+
|
|
14
|
+
@param [in] MACRO_NAME the name of the macro variable to increment
|
|
15
|
+
@param [in] ITER= The amount to add or subtract to the macro
|
|
16
|
+
|
|
17
|
+
<h4> Related Files </h4>
|
|
18
|
+
@li mf_increment.test.sas
|
|
19
|
+
|
|
20
|
+
**/
|
|
21
|
+
|
|
22
|
+
%macro mf_increment(macro_name,incr=1);
|
|
23
|
+
|
|
24
|
+
/* iterate the value */
|
|
25
|
+
%let ¯o_name=%eval(&&¯o_name+&incr);
|
|
26
|
+
/* return the value */
|
|
27
|
+
&&¯o_name
|
|
28
|
+
|
|
29
|
+
%mend mf_increment;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file mf_isblank.sas
|
|
3
|
+
@brief Checks whether a macro variable is empty (blank)
|
|
4
|
+
@details Simply performs:
|
|
5
|
+
|
|
6
|
+
%sysevalf(%superq(param)=,boolean)
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
|
|
10
|
+
%put mf_isblank(&var);
|
|
11
|
+
|
|
12
|
+
inspiration:
|
|
13
|
+
https://support.sas.com/resources/papers/proceedings09/022-2009.pdf
|
|
14
|
+
|
|
15
|
+
@param param VALUE to be checked
|
|
16
|
+
|
|
17
|
+
@return output returns 1 (if blank) else 0
|
|
18
|
+
|
|
19
|
+
@version 9.2
|
|
20
|
+
**/
|
|
21
|
+
|
|
22
|
+
%macro mf_isblank(param
|
|
23
|
+
)/*/STORE SOURCE*/;
|
|
24
|
+
|
|
25
|
+
%sysevalf(%superq(param)=,boolean)
|
|
26
|
+
|
|
27
|
+
%mend mf_isblank;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks whether a path is a valid directory
|
|
4
|
+
@details
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
%let isdir=%mf_isdir(/tmp);
|
|
8
|
+
|
|
9
|
+
With thanks and full credit to Andrea Defronzo -
|
|
10
|
+
https://www.linkedin.com/in/andrea-defronzo-b1a47460/
|
|
11
|
+
|
|
12
|
+
@param path full path of the file/directory to be checked
|
|
13
|
+
|
|
14
|
+
@return output returns 1 if path is a directory, 0 if it is not
|
|
15
|
+
|
|
16
|
+
@version 9.2
|
|
17
|
+
**/
|
|
18
|
+
|
|
19
|
+
%macro mf_isdir(path
|
|
20
|
+
)/*/STORE SOURCE*/;
|
|
21
|
+
%local rc did is_directory fref_t;
|
|
22
|
+
|
|
23
|
+
%let is_directory = 0;
|
|
24
|
+
%let rc = %sysfunc(filename(fref_t, %superq(path)));
|
|
25
|
+
%let did = %sysfunc(dopen(&fref_t.));
|
|
26
|
+
%if &did. ^= 0 %then %do;
|
|
27
|
+
%let is_directory = 1;
|
|
28
|
+
%let rc = %sysfunc(dclose(&did.));
|
|
29
|
+
%end;
|
|
30
|
+
%let rc = %sysfunc(filename(fref_t));
|
|
31
|
+
|
|
32
|
+
&is_directory
|
|
33
|
+
|
|
34
|
+
%mend mf_isdir;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Returns 1 if the variable contains only digits 0-9, else 0
|
|
4
|
+
@details Note that numerics containing any punctuation (including decimals
|
|
5
|
+
or exponents) will be flagged zero.
|
|
6
|
+
|
|
7
|
+
If you'd like support for this, then do raise an issue (or even better, a
|
|
8
|
+
pull request!)
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
|
|
12
|
+
%put %mf_isint(1) returns 1;
|
|
13
|
+
%put %mf_isint(1.1) returns 0;
|
|
14
|
+
%put %mf_isint(%str(1,1)) returns 0;
|
|
15
|
+
|
|
16
|
+
@param [in] arg input value to check
|
|
17
|
+
|
|
18
|
+
@version 9.2
|
|
19
|
+
**/
|
|
20
|
+
|
|
21
|
+
%macro mf_isint(arg
|
|
22
|
+
)/*/STORE SOURCE*/;
|
|
23
|
+
|
|
24
|
+
/* blank val is not an integer */
|
|
25
|
+
%if "&arg"="" %then %do;0%return;%end;
|
|
26
|
+
|
|
27
|
+
/* remove minus sign if exists */
|
|
28
|
+
%local val;
|
|
29
|
+
%if "%substr(%str(&arg),1,1)"="-" %then %let val=%substr(%str(&arg),2);
|
|
30
|
+
%else %let val=&arg;
|
|
31
|
+
|
|
32
|
+
/* check remaining chars */
|
|
33
|
+
%if %sysfunc(findc(%str(&val),,kd)) %then %do;0%end;
|
|
34
|
+
%else %do;1%end;
|
|
35
|
+
|
|
36
|
+
%mend mf_isint;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Checks whether a string follows correct library.dataset format
|
|
4
|
+
@details Many macros in the core library accept a library.dataset parameter
|
|
5
|
+
referred to as 'libds'. This macro validates the structure of that parameter,
|
|
6
|
+
eg:
|
|
7
|
+
|
|
8
|
+
@li 8 character libref?
|
|
9
|
+
@li 32 character dataset?
|
|
10
|
+
@li contains a period?
|
|
11
|
+
|
|
12
|
+
It does NOT check whether the dataset exists, or if the library is assigned.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
|
|
16
|
+
%put %mf_islibds(work.something)=1;
|
|
17
|
+
%put %mf_islibds(nolib)=0;
|
|
18
|
+
%put %mf_islibds(badlibref.ds)=0;
|
|
19
|
+
%put %mf_islibds(w.t.f)=0;
|
|
20
|
+
|
|
21
|
+
@param [in] libds The string to be checked
|
|
22
|
+
|
|
23
|
+
@return output Returns 1 if libds is valid, 0 if it is not
|
|
24
|
+
|
|
25
|
+
<h4> Related Macros </h4>
|
|
26
|
+
@li mf_islibds.test.sas
|
|
27
|
+
@li mp_validatecol.sas
|
|
28
|
+
|
|
29
|
+
@version 9.2
|
|
30
|
+
**/
|
|
31
|
+
|
|
32
|
+
%macro mf_islibds(libds
|
|
33
|
+
)/*/STORE SOURCE*/;
|
|
34
|
+
|
|
35
|
+
%local regex;
|
|
36
|
+
%let regex=%sysfunc(prxparse(%str(/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i)));
|
|
37
|
+
|
|
38
|
+
%sysfunc(prxmatch(®ex,&libds))
|
|
39
|
+
|
|
40
|
+
%mend mf_islibds;
|