@sasjs/utils 2.49.0 → 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/internal/helper.js +19 -24
- package/fs/internal/helper.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 +4 -1
- package/scripts/copySASjsCore.ts +36 -0
- package/utils/index.d.ts +1 -2
- package/utils/index.js +2 -3
- 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
- package/utils/getNodeModulePath.d.ts +0 -2
- package/utils/getNodeModulePath.js +0 -83
- package/utils/getNodeModulePath.js.map +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Append (concatenate) two or more files.
|
|
4
|
+
@details Will append one more more `appendrefs` (filerefs) to a `baseref`.
|
|
5
|
+
Uses a binary mechanism, so will work with any file type. For that reason -
|
|
6
|
+
use with care! And supply your own trailing carriage returns in each file..
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
|
|
10
|
+
filename tmp1 temp;
|
|
11
|
+
filename tmp2 temp;
|
|
12
|
+
filename tmp3 temp;
|
|
13
|
+
data _null_; file tmp1; put 'base file';
|
|
14
|
+
data _null_; file tmp2; put 'append1';
|
|
15
|
+
data _null_; file tmp3; put 'append2';
|
|
16
|
+
run;
|
|
17
|
+
%mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@param [in] baseref= Fileref of the base file (should exist)
|
|
21
|
+
@param [in] appendrefs= One or more filerefs to be appended to the base
|
|
22
|
+
fileref. Space separated.
|
|
23
|
+
|
|
24
|
+
@version 9.2
|
|
25
|
+
@author Allan Bowe, source: https://github.com/sasjs/core
|
|
26
|
+
|
|
27
|
+
<h4> SAS Macros </h4>
|
|
28
|
+
@li mp_abort.sas
|
|
29
|
+
@li mp_binarycopy.sas
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
**/
|
|
33
|
+
|
|
34
|
+
%macro mp_appendfile(
|
|
35
|
+
baseref=0,
|
|
36
|
+
appendrefs=0
|
|
37
|
+
)/*/STORE SOURCE*/;
|
|
38
|
+
|
|
39
|
+
%mp_abort(iftrue= (&baseref=0)
|
|
40
|
+
,mac=&sysmacroname
|
|
41
|
+
,msg=%str(Baseref NOT specified!)
|
|
42
|
+
)
|
|
43
|
+
%mp_abort(iftrue= (&appendrefs=0)
|
|
44
|
+
,mac=&sysmacroname
|
|
45
|
+
,msg=%str(Appendrefs NOT specified!)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
%local i;
|
|
49
|
+
%do i=1 %to %sysfunc(countw(&appendrefs));
|
|
50
|
+
%mp_abort(iftrue= (&syscc>0)
|
|
51
|
+
,mac=&sysmacroname
|
|
52
|
+
,msg=%str(syscc=&syscc)
|
|
53
|
+
)
|
|
54
|
+
%mp_binarycopy(inref=%scan(&appendrefs,&i), outref=&baseref, mode=APPEND)
|
|
55
|
+
%end;
|
|
56
|
+
|
|
57
|
+
%mend mp_appendfile;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Apply a set of formats to a table
|
|
4
|
+
@details Applies a set of formats to the metadata of one or more SAS datasets.
|
|
5
|
+
Can be used to migrate formats from one table to another. The input table
|
|
6
|
+
must contain the following columns:
|
|
7
|
+
|
|
8
|
+
@li lib - the libref of the table to be updated
|
|
9
|
+
@li ds - the dataset to be updated
|
|
10
|
+
@li var - the variable to be updated
|
|
11
|
+
@li fmt - the format to apply. Missing or default ($CHAR, 8.) formats are
|
|
12
|
+
ignored.
|
|
13
|
+
|
|
14
|
+
The macro will abort in the following scenarios:
|
|
15
|
+
|
|
16
|
+
@li Libref not assigned
|
|
17
|
+
@li Dataset does not exist
|
|
18
|
+
@li Input table contains null or invalid values
|
|
19
|
+
|
|
20
|
+
Example usage:
|
|
21
|
+
|
|
22
|
+
data work.example;
|
|
23
|
+
set sashelp.prdsale;
|
|
24
|
+
format _all_ clear;
|
|
25
|
+
run;
|
|
26
|
+
|
|
27
|
+
%mp_getcols(sashelp.prdsale,outds=work.cols)
|
|
28
|
+
|
|
29
|
+
data work.cols2;
|
|
30
|
+
set work.cols;
|
|
31
|
+
lib='WORK';
|
|
32
|
+
ds='EXAMPLE';
|
|
33
|
+
var=name;
|
|
34
|
+
fmt=format;
|
|
35
|
+
keep lib ds var fmt;
|
|
36
|
+
run;
|
|
37
|
+
|
|
38
|
+
%mp_applyformats(work.cols2)
|
|
39
|
+
|
|
40
|
+
@param [in] inds The input dataset containing the formats to apply (and where
|
|
41
|
+
to apply them). Example structure:
|
|
42
|
+
|LIB:$8.|DS:$32.|VAR:$32.|FMT:$49.|
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
|`WORK `|`EXAMPLE `|`ACTUAL `|`DOLLAR12.2 `|
|
|
45
|
+
|`WORK `|`EXAMPLE `|`COUNTRY `|`$CHAR10. `|
|
|
46
|
+
|`WORK `|`EXAMPLE `|`DIVISION `|`$CHAR10. `|
|
|
47
|
+
|`WORK `|`EXAMPLE `|`MONTH `|`MONNAME3. `|
|
|
48
|
+
|`WORK `|`EXAMPLE `|`PREDICT `|`DOLLAR12.2 `|
|
|
49
|
+
|`WORK `|`EXAMPLE `|`PRODTYPE `|`$CHAR10. `|
|
|
50
|
+
|`WORK `|`EXAMPLE `|`PRODUCT `|`$CHAR10. `|
|
|
51
|
+
|`WORK `|`EXAMPLE `|`QUARTER `|`8. `|
|
|
52
|
+
|`WORK `|`EXAMPLE `|`REGION `|`$CHAR10. `|
|
|
53
|
+
|`WORK `|`EXAMPLE `|`YEAR `|`8. `|
|
|
54
|
+
|
|
55
|
+
@param [out] errds= (0) Provide a libds reference here to export the
|
|
56
|
+
error messages to a table. In this case, they will not be printed to the
|
|
57
|
+
log.
|
|
58
|
+
|
|
59
|
+
<h4> SAS Macros </h4>
|
|
60
|
+
@li mf_getengine.sas
|
|
61
|
+
@li mf_getuniquefileref.sas
|
|
62
|
+
@li mf_getuniquename.sas
|
|
63
|
+
@li mf_nobs.sas
|
|
64
|
+
@li mp_validatecol.sas
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
<h4> Related Macros </h4>
|
|
68
|
+
@li mp_getformats.sas
|
|
69
|
+
|
|
70
|
+
@version 9.2
|
|
71
|
+
@author Allan Bowe
|
|
72
|
+
|
|
73
|
+
**/
|
|
74
|
+
|
|
75
|
+
%macro mp_applyformats(inds,errds=0
|
|
76
|
+
)/*/STORE SOURCE*/;
|
|
77
|
+
%local outds liblist i engine lib msg ;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Validations
|
|
81
|
+
*/
|
|
82
|
+
proc sort data=&inds;
|
|
83
|
+
by lib ds var fmt;
|
|
84
|
+
run;
|
|
85
|
+
|
|
86
|
+
%if &errds=0 %then %let outds=%mf_getuniquename(prefix=mp_applyformats);
|
|
87
|
+
%else %let outds=&errds;
|
|
88
|
+
|
|
89
|
+
data &outds;
|
|
90
|
+
set &inds;
|
|
91
|
+
where fmt not in ('','.', '$', '$CHAR.','8.');
|
|
92
|
+
length msg $128;
|
|
93
|
+
by lib ds var fmt;
|
|
94
|
+
if libref(lib) ne 0 then do;
|
|
95
|
+
msg=catx(' ','libref',lib,'is not assigned!');
|
|
96
|
+
%if &errds=0 %then %do;
|
|
97
|
+
putlog "%str(ERR)OR: " msg;
|
|
98
|
+
%end;
|
|
99
|
+
output;
|
|
100
|
+
return;
|
|
101
|
+
end;
|
|
102
|
+
if exist(cats(lib,'.',ds)) ne 1 then do;
|
|
103
|
+
msg=catx(' ','libds',lib,'.',ds,'does not exist!');
|
|
104
|
+
%if &errds=0 %then %do;
|
|
105
|
+
putlog "%str(ERR)OR: " msg;
|
|
106
|
+
%end;
|
|
107
|
+
output;
|
|
108
|
+
return;
|
|
109
|
+
end;
|
|
110
|
+
%mp_validatecol(fmt,FORMAT,is_fmt)
|
|
111
|
+
if is_fmt=0 then do;
|
|
112
|
+
msg=catx(' ','format',fmt,'on libds',lib,'.',ds,'.',var,'is not valid!');
|
|
113
|
+
%if &errds=0 %then %do;
|
|
114
|
+
putlog "%str(ERR)OR: " msg;
|
|
115
|
+
%end;
|
|
116
|
+
output;
|
|
117
|
+
return;
|
|
118
|
+
end;
|
|
119
|
+
|
|
120
|
+
if first.ds then do;
|
|
121
|
+
retain dsid;
|
|
122
|
+
dsid=open(cats(lib,'.',ds));
|
|
123
|
+
if dsid=0 then do;
|
|
124
|
+
msg=catx(' ','libds',lib,'.',ds,' could not be opened!');
|
|
125
|
+
%if &errds=0 %then %do;
|
|
126
|
+
putlog "%str(ERR)OR: " msg;
|
|
127
|
+
%end;
|
|
128
|
+
output;
|
|
129
|
+
return;
|
|
130
|
+
end;
|
|
131
|
+
if varnum(dsid,var)<1 then do;
|
|
132
|
+
msg=catx(' ','Variable',lib,'.',ds,'.',var,' was not found!');
|
|
133
|
+
%if &errds=0 %then %do;
|
|
134
|
+
putlog "%str(ERR)OR: " msg;
|
|
135
|
+
%end;
|
|
136
|
+
output;
|
|
137
|
+
end;
|
|
138
|
+
end;
|
|
139
|
+
if last.ds then rc=close(dsid);
|
|
140
|
+
run;
|
|
141
|
+
|
|
142
|
+
proc sql noprint;
|
|
143
|
+
select distinct lib into: liblist separated by ' ' from &inds;
|
|
144
|
+
%put &=liblist;
|
|
145
|
+
%if %length(&liblist)>0 %then %do i=1 %to %sysfunc(countw(&liblist));
|
|
146
|
+
%let lib=%scan(&liblist,1);
|
|
147
|
+
%let engine=%mf_getengine(&lib);
|
|
148
|
+
%if &engine ne V9 and &engine ne BASE %then %do;
|
|
149
|
+
%let msg=&lib has &engine engine - formats cannot be applied;
|
|
150
|
+
insert into &outds set lib="&lib",ds="_all_",var="_all", msg="&msg" ;
|
|
151
|
+
%if &errds=0 %then %put %str(ERR)OR: &msg;
|
|
152
|
+
%end;
|
|
153
|
+
%end;
|
|
154
|
+
quit;
|
|
155
|
+
|
|
156
|
+
%if %mf_nobs(&outds)>0 %then %return;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Validations complete - now apply the actual formats!
|
|
160
|
+
*/
|
|
161
|
+
%let fref=%mf_getuniquefileref();
|
|
162
|
+
data _null_;
|
|
163
|
+
set &inds;
|
|
164
|
+
by lib ds var fmt;
|
|
165
|
+
where fmt not in ('','.', '$', '$CHAR.','8.');
|
|
166
|
+
file &fref;
|
|
167
|
+
if first.lib then put 'proc datasets nolist lib=' lib ';';
|
|
168
|
+
if first.ds then put ' modify ' ds ';';
|
|
169
|
+
put ' format ' var fmt ';';
|
|
170
|
+
if last.ds then put ' run;';
|
|
171
|
+
if last.lib then put 'quit;';
|
|
172
|
+
run;
|
|
173
|
+
|
|
174
|
+
%inc &fref/source2;
|
|
175
|
+
|
|
176
|
+
%if &errds=0 %then %do;
|
|
177
|
+
proc sql;
|
|
178
|
+
drop table &outds;
|
|
179
|
+
%end;
|
|
180
|
+
|
|
181
|
+
%mend mp_applyformats;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Generic assertion
|
|
4
|
+
@details Useful in the context of writing sasjs tests. The results of the
|
|
5
|
+
test are _appended_ to the &outds. table.
|
|
6
|
+
|
|
7
|
+
Example usage:
|
|
8
|
+
|
|
9
|
+
%mp_assert(iftrue=(1=1),
|
|
10
|
+
desc=Obviously true
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
%mp_assert(iftrue=(1=0),
|
|
14
|
+
desc=Will fail
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
@param [in] iftrue= (1=1) A condition where, if true, the test is a PASS.
|
|
18
|
+
Else, the test is a fail.
|
|
19
|
+
|
|
20
|
+
@param [in] desc= (Testing observations) The user provided test description
|
|
21
|
+
@param [out] outds= (work.test_results) The output dataset to contain the
|
|
22
|
+
results. If it does not exist, it will be created, with the following format:
|
|
23
|
+
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|
24
|
+
|---|---|---|
|
|
25
|
+
|User Provided description|PASS|Column &inds contained ALL columns|
|
|
26
|
+
|
|
27
|
+
@version 9.2
|
|
28
|
+
@author Allan Bowe
|
|
29
|
+
|
|
30
|
+
**/
|
|
31
|
+
|
|
32
|
+
%macro mp_assert(iftrue=(1=1),
|
|
33
|
+
desc=0,
|
|
34
|
+
outds=work.test_results
|
|
35
|
+
)/*/STORE SOURCE*/;
|
|
36
|
+
|
|
37
|
+
data ;
|
|
38
|
+
length test_description $256 test_result $4 test_comments $256;
|
|
39
|
+
test_description=symget('desc');
|
|
40
|
+
test_comments="&sysmacroname: Test result of "!!symget('iftrue');
|
|
41
|
+
%if %eval(%unquote(&iftrue)) %then %do;
|
|
42
|
+
test_result='PASS';
|
|
43
|
+
%end;
|
|
44
|
+
%else %do;
|
|
45
|
+
test_result='FAIL';
|
|
46
|
+
%end;
|
|
47
|
+
run;
|
|
48
|
+
|
|
49
|
+
%local ds ;
|
|
50
|
+
%let ds=&syslast;
|
|
51
|
+
proc append base=&outds data=&ds;
|
|
52
|
+
run;
|
|
53
|
+
proc sql;
|
|
54
|
+
drop table &ds;
|
|
55
|
+
|
|
56
|
+
%mend mp_assert;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Asserts the existence (or not) of columns
|
|
4
|
+
@details Useful in the context of writing sasjs tests. The results of the
|
|
5
|
+
test are _appended_ to the &outds. table.
|
|
6
|
+
|
|
7
|
+
Example usage:
|
|
8
|
+
|
|
9
|
+
%mp_assertcols(sashelp.class,
|
|
10
|
+
cols=name age sex,
|
|
11
|
+
test=ALL,
|
|
12
|
+
desc=check all columns exist
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
%mp_assertcols(sashelp.class,
|
|
16
|
+
cols=a b c,
|
|
17
|
+
test=NONE
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
%mp_assertcols(sashelp.class,
|
|
21
|
+
cols=age depth,
|
|
22
|
+
test=ANY
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
<h4> SAS Macros </h4>
|
|
26
|
+
@li mf_existds.sas
|
|
27
|
+
@li mf_existvarlist.sas
|
|
28
|
+
@li mf_getvarlist.sas
|
|
29
|
+
@li mf_wordsinstr1butnotstr2.sas
|
|
30
|
+
@li mp_abort.sas
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@param [in] inds The input library.dataset to test for values
|
|
34
|
+
@param [in] cols= The list of columns to check for
|
|
35
|
+
@param [in] desc= (Testing observations) The user provided test description
|
|
36
|
+
@param [in] test= (ALL) The test to apply. Valid values are:
|
|
37
|
+
@li ALL - Test is a PASS if ALL columns exist in &inds
|
|
38
|
+
@li ANY - Test is a PASS if ANY of the columns exist in &inds
|
|
39
|
+
@li NONE - Test is a PASS if NONE of the columns exist in &inds
|
|
40
|
+
@param [out] outds= (work.test_results) The output dataset to contain the
|
|
41
|
+
results. If it does not exist, it will be created, with the following format:
|
|
42
|
+
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|
43
|
+
|---|---|---|
|
|
44
|
+
|User Provided description|PASS|Column &inds contained ALL columns|
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
<h4> Related Macros </h4>
|
|
48
|
+
@li mp_assertdsobs.sas
|
|
49
|
+
@li mp_assertcolvals.sas
|
|
50
|
+
@li mp_assertdsobs.sas
|
|
51
|
+
|
|
52
|
+
@version 9.2
|
|
53
|
+
@author Allan Bowe
|
|
54
|
+
|
|
55
|
+
**/
|
|
56
|
+
|
|
57
|
+
%macro mp_assertcols(inds,
|
|
58
|
+
cols=0,
|
|
59
|
+
test=ALL,
|
|
60
|
+
desc=0,
|
|
61
|
+
outds=work.test_results
|
|
62
|
+
)/*/STORE SOURCE*/;
|
|
63
|
+
|
|
64
|
+
%mp_abort(iftrue= (&syscc ne 0)
|
|
65
|
+
,mac=&sysmacroname
|
|
66
|
+
,msg=%str(syscc=&syscc - on macro entry)
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
%local lib ds ;
|
|
70
|
+
%let lib=%scan(&inds,1,%str(.));
|
|
71
|
+
%let ds=%scan(&inds,2,%str(.));
|
|
72
|
+
%let cols=%upcase(&cols);
|
|
73
|
+
|
|
74
|
+
%mp_abort(iftrue= (%mf_existds(&lib..&ds)=0)
|
|
75
|
+
,mac=&sysmacroname
|
|
76
|
+
,msg=%str(&lib..&ds not found!)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
%mp_abort(iftrue= (&cols=0)
|
|
80
|
+
,mac=&sysmacroname
|
|
81
|
+
,msg=%str(No cols provided)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
%let test=%upcase(&test);
|
|
86
|
+
|
|
87
|
+
%if &test ne ANY and &test ne ALL and &test ne NONE %then %do;
|
|
88
|
+
%mp_abort(
|
|
89
|
+
mac=&sysmacroname,
|
|
90
|
+
msg=%str(Invalid test - &test)
|
|
91
|
+
)
|
|
92
|
+
%end;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* now do the actual test!
|
|
96
|
+
*/
|
|
97
|
+
%local result;
|
|
98
|
+
%if %mf_existVarList(&inds,&cols)=1 %then %let result=ALL;
|
|
99
|
+
%else %do;
|
|
100
|
+
%local targetcols compare;
|
|
101
|
+
%let targetcols=%upcase(%mf_getvarlist(&inds));
|
|
102
|
+
%let compare=%mf_wordsinstr1butnotstr2(
|
|
103
|
+
Str1=&cols,
|
|
104
|
+
Str2=&targetcols
|
|
105
|
+
);
|
|
106
|
+
%if %cmpres(&compare)=%cmpres(&cols) %then %let result=NONE;
|
|
107
|
+
%else %let result=SOME;
|
|
108
|
+
%end;
|
|
109
|
+
|
|
110
|
+
data;
|
|
111
|
+
length test_description $256 test_result $4 test_comments $256;
|
|
112
|
+
test_description=symget('desc');
|
|
113
|
+
if test_description='0'
|
|
114
|
+
then test_description="Testing &inds for existence of &test of: &cols";
|
|
115
|
+
|
|
116
|
+
test_result='FAIL';
|
|
117
|
+
test_comments="&sysmacroname: &inds has &result columns ";
|
|
118
|
+
%if &test=ALL %then %do;
|
|
119
|
+
%if &result=ALL %then %do;
|
|
120
|
+
test_result='PASS';
|
|
121
|
+
%end;
|
|
122
|
+
%end;
|
|
123
|
+
%else %if &test=ANY %then %do;
|
|
124
|
+
%if &result=SOME %then %do;
|
|
125
|
+
test_result='PASS';
|
|
126
|
+
%end;
|
|
127
|
+
%end;
|
|
128
|
+
%else %if &test=NONE %then %do;
|
|
129
|
+
%if &result=NONE %then %do;
|
|
130
|
+
test_result='PASS';
|
|
131
|
+
%end;
|
|
132
|
+
%end;
|
|
133
|
+
%else %do;
|
|
134
|
+
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
|
135
|
+
%end;
|
|
136
|
+
run;
|
|
137
|
+
|
|
138
|
+
%local ds;
|
|
139
|
+
%let ds=&syslast;
|
|
140
|
+
proc append base=&outds data=&ds;
|
|
141
|
+
run;
|
|
142
|
+
proc sql;
|
|
143
|
+
drop table &ds;
|
|
144
|
+
|
|
145
|
+
%mend mp_assertcols;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Asserts the values in a column
|
|
4
|
+
@details Useful in the context of writing sasjs tests. The results of the
|
|
5
|
+
test are _appended_ to the &outds. table.
|
|
6
|
+
|
|
7
|
+
Example usage:
|
|
8
|
+
|
|
9
|
+
data work.checkds;
|
|
10
|
+
do checkval='Jane','James','Jill';
|
|
11
|
+
output;
|
|
12
|
+
end;
|
|
13
|
+
run;
|
|
14
|
+
%mp_assertcolvals(sashelp.class.name,
|
|
15
|
+
checkvals=work.checkds.checkval,
|
|
16
|
+
desc=At least one value has a match,
|
|
17
|
+
test=ANYVAL
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
data work.check;
|
|
21
|
+
do val='M','F';
|
|
22
|
+
output;
|
|
23
|
+
end;
|
|
24
|
+
run;
|
|
25
|
+
%mp_assertcolvals(sashelp.class.sex,
|
|
26
|
+
checkvals=work.check.val,
|
|
27
|
+
desc=All values have a match,
|
|
28
|
+
test=ALLVALS
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
<h4> SAS Macros </h4>
|
|
32
|
+
@li mf_existds.sas
|
|
33
|
+
@li mf_getuniquename.sas
|
|
34
|
+
@li mf_nobs.sas
|
|
35
|
+
@li mp_abort.sas
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@param [in] indscol The input library.dataset.column to test for values
|
|
39
|
+
@param [in] checkvals= A library.dataset.column value containing a UNIQUE
|
|
40
|
+
list of values to be compared against the source (indscol).
|
|
41
|
+
@param [in] desc= (Testing observations) The user provided test description
|
|
42
|
+
@param [in] test= (ALLVALS) The test to apply. Valid values are:
|
|
43
|
+
@li ALLVALS - Test is a PASS if ALL values have a match in checkvals
|
|
44
|
+
@li ANYVAL - Test is a PASS if at least 1 value has a match in checkvals
|
|
45
|
+
@param [out] outds= (work.test_results) The output dataset to contain the
|
|
46
|
+
results. If it does not exist, it will be created, with the following format:
|
|
47
|
+
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|
48
|
+
|---|---|---|
|
|
49
|
+
|User Provided description|PASS|Column &indscol contained ALL target vals|
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<h4> Related Macros </h4>
|
|
53
|
+
@li mp_assertdsobs.sas
|
|
54
|
+
|
|
55
|
+
@version 9.2
|
|
56
|
+
@author Allan Bowe
|
|
57
|
+
|
|
58
|
+
**/
|
|
59
|
+
|
|
60
|
+
%macro mp_assertcolvals(indscol,
|
|
61
|
+
checkvals=0,
|
|
62
|
+
test=ALLVALS,
|
|
63
|
+
desc=mp_assertcolvals - no desc provided,
|
|
64
|
+
outds=work.test_results
|
|
65
|
+
)/*/STORE SOURCE*/;
|
|
66
|
+
|
|
67
|
+
%mp_abort(iftrue= (&syscc ne 0)
|
|
68
|
+
,mac=&sysmacroname
|
|
69
|
+
,msg=%str(syscc=&syscc - on macro entry)
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
%local lib ds col clib cds ccol nobs;
|
|
73
|
+
%let lib=%scan(&indscol,1,%str(.));
|
|
74
|
+
%let ds=%scan(&indscol,2,%str(.));
|
|
75
|
+
%let col=%scan(&indscol,3,%str(.));
|
|
76
|
+
%mp_abort(iftrue= (%mf_existds(&lib..&ds)=0)
|
|
77
|
+
,mac=&sysmacroname
|
|
78
|
+
,msg=%str(&lib..&ds not found!)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
%mp_abort(iftrue= (&checkvals=0)
|
|
82
|
+
,mac=&sysmacroname
|
|
83
|
+
,msg=%str(Set CHECKVALS to a library.dataset.column containing check vals)
|
|
84
|
+
)
|
|
85
|
+
%let clib=%scan(&checkvals,1,%str(.));
|
|
86
|
+
%let cds=%scan(&checkvals,2,%str(.));
|
|
87
|
+
%let ccol=%scan(&checkvals,3,%str(.));
|
|
88
|
+
%mp_abort(iftrue= (%mf_existds(&clib..&cds)=0)
|
|
89
|
+
,mac=&sysmacroname
|
|
90
|
+
,msg=%str(&clib..&cds not found!)
|
|
91
|
+
)
|
|
92
|
+
%let nobs=%mf_nobs(&clib..&cds);
|
|
93
|
+
%mp_abort(iftrue= (&nobs=0)
|
|
94
|
+
,mac=&sysmacroname
|
|
95
|
+
,msg=%str(&clib..&cds is empty!)
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
%let test=%upcase(&test);
|
|
99
|
+
|
|
100
|
+
%if &test ne ALLVALS and &test ne ANYVAL %then %do;
|
|
101
|
+
%mp_abort(
|
|
102
|
+
mac=&sysmacroname,
|
|
103
|
+
msg=%str(Invalid test - &test)
|
|
104
|
+
)
|
|
105
|
+
%end;
|
|
106
|
+
|
|
107
|
+
%local result orig;
|
|
108
|
+
%let result=-1;
|
|
109
|
+
%let orig=-1;
|
|
110
|
+
proc sql noprint;
|
|
111
|
+
select count(*) into: result
|
|
112
|
+
from &lib..&ds
|
|
113
|
+
where &col not in (
|
|
114
|
+
select &ccol from &clib..&cds
|
|
115
|
+
);
|
|
116
|
+
select count(*) into: orig from &lib..&ds;
|
|
117
|
+
quit;
|
|
118
|
+
|
|
119
|
+
%local notfound tmp1 tmp2;
|
|
120
|
+
%let tmp1=%mf_getuniquename();
|
|
121
|
+
%let tmp2=%mf_getuniquename();
|
|
122
|
+
|
|
123
|
+
/* this is a bit convoluted - but using sql outobs=10 throws warnings */
|
|
124
|
+
proc sql noprint;
|
|
125
|
+
create view &tmp1 as
|
|
126
|
+
select distinct &col
|
|
127
|
+
from &lib..&ds
|
|
128
|
+
where &col not in (
|
|
129
|
+
select &ccol from &clib..&cds
|
|
130
|
+
);
|
|
131
|
+
data &tmp2;
|
|
132
|
+
set &tmp1;
|
|
133
|
+
if _n_>10 then stop;
|
|
134
|
+
run;
|
|
135
|
+
proc sql;
|
|
136
|
+
select distinct &col into: notfound separated by ' ' from &tmp2;
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
%mp_abort(iftrue= (&syscc ne 0)
|
|
140
|
+
,mac=&sysmacroname
|
|
141
|
+
,msg=%str(syscc=&syscc after macro query)
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
data;
|
|
145
|
+
length test_description $256 test_result $4 test_comments $256;
|
|
146
|
+
test_description=symget('desc');
|
|
147
|
+
test_result='FAIL';
|
|
148
|
+
test_comments="&sysmacroname: &lib..&ds..&col has &result values "
|
|
149
|
+
!!"not in &clib..&cds..&ccol.. First 10 vals:"!!symget('notfound');
|
|
150
|
+
%if &test=ANYVAL %then %do;
|
|
151
|
+
if &result < &orig then test_result='PASS';
|
|
152
|
+
%end;
|
|
153
|
+
%else %if &test=ALLVALS %then %do;
|
|
154
|
+
if &result=0 then test_result='PASS';
|
|
155
|
+
%end;
|
|
156
|
+
%else %do;
|
|
157
|
+
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
|
158
|
+
%end;
|
|
159
|
+
run;
|
|
160
|
+
|
|
161
|
+
%local ds;
|
|
162
|
+
%let ds=&syslast;
|
|
163
|
+
proc append base=&outds data=&ds;
|
|
164
|
+
run;
|
|
165
|
+
proc sql;
|
|
166
|
+
drop table &ds;
|
|
167
|
+
|
|
168
|
+
%mend mp_assertcolvals;
|