@sasjs/utils 3.5.0 → 3.5.2
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/.all-contributorsrc +12 -1
- package/.github/workflows/run-tests-windows.yml +1 -1
- package/.github/workflows/run-tests.yml +1 -1
- package/README.md +15 -12
- package/file/file.d.ts +1 -1
- package/file/file.js +4 -2
- package/file/file.js.map +1 -1
- package/macros/mf_abort.sas +7 -2
- package/macros/mf_deletefile.sas +1 -1
- package/macros/mf_existds.sas +1 -1
- package/macros/mf_existfileref.sas +2 -2
- package/macros/mf_existfunction.sas +1 -1
- package/macros/mf_existvar.sas +8 -4
- package/macros/mf_existvarlist.sas +2 -2
- package/macros/mf_getapploc.sas +1 -0
- package/macros/mf_getattrc.sas +2 -2
- package/macros/mf_getattrn.sas +2 -2
- package/macros/mf_getfmtlist.sas +3 -4
- package/macros/mf_getgitbranch.sas +37 -0
- package/macros/mf_getkeyvalue.sas +3 -2
- package/macros/mf_getplatform.sas +1 -1
- package/macros/mf_getschema.sas +1 -1
- package/macros/mf_getuniquelibref.sas +1 -1
- package/macros/mf_getuniquename.sas +1 -1
- package/macros/mf_getuser.sas +0 -2
- package/macros/mf_getvalue.sas +3 -3
- package/macros/mf_getvarformat.sas +2 -1
- package/macros/mf_getvarlen.sas +2 -2
- package/macros/mf_getvarnum.sas +2 -2
- package/macros/mf_getvartype.sas +2 -2
- package/macros/mf_getxengine.sas +1 -1
- package/macros/mf_increment.sas +2 -2
- package/macros/mf_isblank.sas +2 -2
- package/macros/mf_isdir.sas +1 -1
- package/macros/mf_loc.sas +6 -1
- package/macros/mf_mkdir.sas +1 -1
- package/macros/mf_mval.sas +2 -0
- package/macros/mf_nobs.sas +1 -1
- package/macros/mf_readfile.sas +63 -0
- package/macros/mf_trimstr.sas +2 -2
- package/macros/mf_wordsinstr1andstr2.sas +2 -2
- package/macros/mf_wordsinstr1butnotstr2.sas +2 -2
- package/macros/mf_writefile.sas +2 -2
- package/macros/mp_abort.sas +50 -13
- package/macros/mp_aligndecimal.sas +95 -0
- package/macros/mp_appendfile.sas +2 -2
- package/macros/mp_applyformats.sas +5 -5
- package/macros/mp_assert.sas +1 -1
- package/macros/mp_assertcols.sas +3 -3
- package/macros/mp_assertcolvals.sas +9 -5
- package/macros/mp_base64copy.sas +2 -2
- package/macros/mp_binarycopy.sas +7 -6
- package/macros/mp_chop.sas +4 -3
- package/macros/mp_cleancsv.sas +5 -4
- package/macros/mp_cntlout.sas +16 -7
- package/macros/mp_copyfolder.sas +2 -2
- package/macros/mp_createconstraints.sas +3 -3
- package/macros/mp_createwebservice.sas +1 -1
- package/macros/mp_csv2ds.sas +6 -5
- package/macros/mp_deleteconstraints.sas +5 -3
- package/macros/mp_deletefolder.sas +1 -1
- package/macros/mp_dictionary.sas +1 -1
- package/macros/mp_dirlist.sas +1 -1
- package/macros/mp_distinctfmtvalues.sas +5 -5
- package/macros/mp_ds2csv.sas +10 -1
- package/macros/mp_ds2ddl.sas +14 -2
- package/macros/mp_ds2md.sas +1 -0
- package/macros/mp_dsmeta.sas +2 -2
- package/macros/mp_filtercheck.sas +105 -16
- package/macros/mp_filtergenerate.sas +2 -2
- package/macros/mp_filterstore.sas +4 -3
- package/macros/mp_getcols.sas +3 -2
- package/macros/mp_getdbml.sas +4 -4
- package/macros/mp_getddl.sas +15 -10
- package/macros/mp_getformats.sas +13 -3
- package/macros/mp_gitlog.sas +104 -0
- package/macros/mp_gitstatus.sas +1 -1
- package/macros/mp_gsubfile.sas +6 -6
- package/macros/mp_guesspk.sas +1 -1
- package/macros/mp_hashdataset.sas +1 -1
- package/macros/mp_init.sas +1 -0
- package/macros/mp_lib2cards.sas +7 -7
- package/macros/mp_loadformat.sas +127 -47
- package/macros/mp_lockanytable.sas +31 -24
- package/macros/mp_md5.sas +3 -4
- package/macros/mp_perflog.sas +3 -3
- package/macros/mp_prevobs.sas +5 -5
- package/macros/mp_recursivejoin.sas +7 -6
- package/macros/mp_replace.sas +5 -4
- package/macros/mp_runddl.sas +3 -3
- package/macros/mp_searchcols.sas +7 -6
- package/macros/mp_stackdiffs.sas +1 -0
- package/macros/mp_storediffs.sas +8 -8
- package/macros/mp_stprequests.sas +4 -3
- package/macros/mp_stripdiffs.sas +255 -0
- package/macros/mp_testjob.sas +2 -2
- package/macros/mp_testwritespeedlibrary.sas +3 -3
- package/macros/mp_tree.sas +2 -2
- package/macros/mp_unzip.sas +5 -4
- package/macros/mp_updatevarlength.sas +3 -3
- package/macros/mp_validatecol.sas +3 -3
- package/macros/mp_wait4file.sas +1 -1
- package/macros/mp_webin.sas +1 -1
- package/macros/mp_zip.sas +5 -5
- package/package.json +5 -6
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Reads the first line of a file using pure macro
|
|
4
|
+
@details Reads the first line of a file and returns it. Future versions may
|
|
5
|
+
read each line into a macro variable array.
|
|
6
|
+
|
|
7
|
+
Generally, reading data into macro variables is not great as certain
|
|
8
|
+
nonprintable characters (such as CR, LF) may be dropped in the conversion.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
|
|
12
|
+
%mf_writefile(&sasjswork/myfile.txt,l1=some content,l2=more content)
|
|
13
|
+
|
|
14
|
+
%put %mf_readfile(&sasjswork/myfile.txt);
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@param [in] fpath Full path to file to be read
|
|
18
|
+
|
|
19
|
+
<h4> Related Macros </h4>
|
|
20
|
+
@li mf_deletefile.sas
|
|
21
|
+
@li mf_writefile.sas
|
|
22
|
+
@li mf_readfile.test.sas
|
|
23
|
+
|
|
24
|
+
@version 9.2
|
|
25
|
+
@author Allan Bowe
|
|
26
|
+
**/
|
|
27
|
+
/** @cond */
|
|
28
|
+
|
|
29
|
+
%macro mf_readfile(fpath
|
|
30
|
+
)/*/STORE SOURCE*/;
|
|
31
|
+
%local fref rc fid fcontent;
|
|
32
|
+
|
|
33
|
+
/* check file exists */
|
|
34
|
+
%if %sysfunc(filename(fref,&fpath)) ne 0 %then %do;
|
|
35
|
+
%put &=fref &=fpath;
|
|
36
|
+
%put %str(ERR)OR: %sysfunc(sysmsg());
|
|
37
|
+
%return;
|
|
38
|
+
%end;
|
|
39
|
+
|
|
40
|
+
%let fid=%sysfunc(fopen(&fref,I));
|
|
41
|
+
|
|
42
|
+
%if &fid=0 %then %do;
|
|
43
|
+
%put %str(ERR)OR: %sysfunc(sysmsg());
|
|
44
|
+
%return;
|
|
45
|
+
%end;
|
|
46
|
+
|
|
47
|
+
%if %sysfunc(fread(&fid)) = 0 %then %do;
|
|
48
|
+
%let rc=%sysfunc(fget(&fid,fcontent,65534));
|
|
49
|
+
&fcontent
|
|
50
|
+
%end;
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
%do %while(%sysfunc(fread(&fid)) = 0);
|
|
54
|
+
%let rc=%sysfunc(fget(&fid,fcontent,65534));
|
|
55
|
+
&fcontent
|
|
56
|
+
%end;
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
%let rc=%sysfunc(fclose(&fid));
|
|
60
|
+
%let rc=%sysfunc(filename(&fref));
|
|
61
|
+
|
|
62
|
+
%mend mf_readfile;
|
|
63
|
+
/** @endcond */
|
package/macros/mf_trimstr.sas
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
<h4> SAS Macros </h4>
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
@param basestr The string to be modified
|
|
15
|
-
@param trimstr The string to be removed from the end of `basestr`, if it
|
|
14
|
+
@param [in] basestr The string to be modified
|
|
15
|
+
@param [in] trimstr The string to be removed from the end of `basestr`, if it
|
|
16
16
|
exists
|
|
17
17
|
|
|
18
18
|
@return output returns result with the value of `trimstr` removed from the end
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
returns:
|
|
14
14
|
> blah blaaah brah
|
|
15
15
|
|
|
16
|
-
@param str1= string containing words to extract
|
|
17
|
-
@param str2= used to compare with the extract string
|
|
16
|
+
@param [in] str1= () string containing words to extract
|
|
17
|
+
@param [in] str2= () used to compare with the extract string
|
|
18
18
|
|
|
19
19
|
@warning CASE SENSITIVE!
|
|
20
20
|
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
returns:
|
|
17
17
|
> sss bram boo
|
|
18
18
|
|
|
19
|
-
@param [in] str1=
|
|
20
|
-
@param [in] str2=
|
|
19
|
+
@param [in] str1= () String containing words to extract
|
|
20
|
+
@param [in] str2= () Used to compare with the extract string
|
|
21
21
|
|
|
22
22
|
@version 9.2
|
|
23
23
|
@author Allan Bowe
|
package/macros/mf_writefile.sas
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
@param [in] mode= (O) Available options are A or O as follows:
|
|
22
22
|
@li A APPEND mode, writes new records after the current end of the file.
|
|
23
23
|
@li O OUTPUT mode, writes new records from the beginning of the file.
|
|
24
|
-
@param [in] l1= First line
|
|
25
|
-
@param [in] l2= Second line (etc through to l10)
|
|
24
|
+
@param [in] l1= () First line
|
|
25
|
+
@param [in] l2= () Second line (etc through to l10)
|
|
26
26
|
|
|
27
27
|
<h4> Related Macros </h4>
|
|
28
28
|
@li mf_writefile.test.sas
|
package/macros/mp_abort.sas
CHANGED
|
@@ -27,14 +27,15 @@
|
|
|
27
27
|
currently investigating approaches to deal with this.
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
@param mac= (mp_abort.sas) To contain the name of the calling macro. Do
|
|
31
|
-
use &sysmacroname as this will always resolve to MP_ABORT.
|
|
32
|
-
@param msg= message to be returned
|
|
33
|
-
@param iftrue= (1=1)
|
|
34
|
-
@param errds= (work.mp_abort_errds) There is no clean way to end a
|
|
35
|
-
within a %include called within a macro. Furthermore, there is no
|
|
36
|
-
test if a macro is called within a %include. To handle this
|
|
37
|
-
scenario, the %include should be switched for the mp_include.sas
|
|
30
|
+
@param [in] mac= (mp_abort.sas) To contain the name of the calling macro. Do
|
|
31
|
+
not use &sysmacroname as this will always resolve to MP_ABORT.
|
|
32
|
+
@param [out] msg= message to be returned
|
|
33
|
+
@param [in] iftrue= (1=1) Condition under which the macro should be executed
|
|
34
|
+
@param [in] errds= (work.mp_abort_errds) There is no clean way to end a
|
|
35
|
+
process within a %include called within a macro. Furthermore, there is no
|
|
36
|
+
way to test if a macro is called within a %include. To handle this
|
|
37
|
+
particular scenario, the %include should be switched for the mp_include.sas
|
|
38
|
+
macro.
|
|
38
39
|
This provides an indicator that we are running a macro within a \%include
|
|
39
40
|
(`_SYSINCLUDEFILEDEVICE`) and allows us to provide a dataset with the abort
|
|
40
41
|
values (msg, mac).
|
|
@@ -45,8 +46,8 @@
|
|
|
45
46
|
@li msg (the message)
|
|
46
47
|
@li mac (the mac param)
|
|
47
48
|
|
|
48
|
-
@param mode= (REGULAR) If mode=INCLUDE then the &errds dataset is checked
|
|
49
|
-
an abort status.
|
|
49
|
+
@param [in] mode= (REGULAR) If mode=INCLUDE then the &errds dataset is checked
|
|
50
|
+
for an abort status.
|
|
50
51
|
Valid values:
|
|
51
52
|
@li REGULAR (default)
|
|
52
53
|
@li INCLUDE
|
|
@@ -225,15 +226,51 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
|
|
|
225
226
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
|
226
227
|
put ',"_PROGRAM" : ' _PROGRAM ;
|
|
227
228
|
put ",""SYSCC"" : ""&syscc"" ";
|
|
228
|
-
syserrortext=cats(
|
|
229
|
-
|
|
229
|
+
syserrortext=cats(symget('syserrortext'));
|
|
230
|
+
if findc(syserrortext,'"\'!!'0A0D09000E0F010210111A'x) then do;
|
|
231
|
+
syserrortext='"'!!trim(
|
|
232
|
+
prxchange('s/"/\\"/',-1, /* double quote */
|
|
233
|
+
prxchange('s/\x0A/\n/',-1, /* new line */
|
|
234
|
+
prxchange('s/\x0D/\r/',-1, /* carriage return */
|
|
235
|
+
prxchange('s/\x09/\\t/',-1, /* tab */
|
|
236
|
+
prxchange('s/\x00/\\u0000/',-1, /* NUL */
|
|
237
|
+
prxchange('s/\x0E/\\u000E/',-1, /* SS */
|
|
238
|
+
prxchange('s/\x0F/\\u000F/',-1, /* SF */
|
|
239
|
+
prxchange('s/\x01/\\u0001/',-1, /* SOH */
|
|
240
|
+
prxchange('s/\x02/\\u0002/',-1, /* STX */
|
|
241
|
+
prxchange('s/\x10/\\u0010/',-1, /* DLE */
|
|
242
|
+
prxchange('s/\x11/\\u0011/',-1, /* DC1 */
|
|
243
|
+
prxchange('s/\x1A/\\u001A/',-1, /* SUB */
|
|
244
|
+
prxchange('s/\\/\\\\/',-1,syserrortext)
|
|
245
|
+
)))))))))))))!!'"';
|
|
246
|
+
end;
|
|
247
|
+
else syserrortext=cats('"',syserrortext,'"');
|
|
248
|
+
put ',"SYSERRORTEXT" : ' syserrortext;
|
|
230
249
|
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
|
231
250
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
|
232
251
|
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
|
233
252
|
put ",""SYSSITE"" : ""&syssite"" ";
|
|
234
253
|
sysvlong=quote(trim(symget('sysvlong')));
|
|
235
254
|
put ',"SYSVLONG" : ' sysvlong;
|
|
236
|
-
syswarningtext=cats(
|
|
255
|
+
syswarningtext=cats(symget('syswarningtext'));
|
|
256
|
+
if findc(syswarningtext,'"\'!!'0A0D09000E0F010210111A'x) then do;
|
|
257
|
+
syswarningtext='"'!!trim(
|
|
258
|
+
prxchange('s/"/\\"/',-1, /* double quote */
|
|
259
|
+
prxchange('s/\x0A/\n/',-1, /* new line */
|
|
260
|
+
prxchange('s/\x0D/\r/',-1, /* carriage return */
|
|
261
|
+
prxchange('s/\x09/\\t/',-1, /* tab */
|
|
262
|
+
prxchange('s/\x00/\\u0000/',-1, /* NUL */
|
|
263
|
+
prxchange('s/\x0E/\\u000E/',-1, /* SS */
|
|
264
|
+
prxchange('s/\x0F/\\u000F/',-1, /* SF */
|
|
265
|
+
prxchange('s/\x01/\\u0001/',-1, /* SOH */
|
|
266
|
+
prxchange('s/\x02/\\u0002/',-1, /* STX */
|
|
267
|
+
prxchange('s/\x10/\\u0010/',-1, /* DLE */
|
|
268
|
+
prxchange('s/\x11/\\u0011/',-1, /* DC1 */
|
|
269
|
+
prxchange('s/\x1A/\\u001A/',-1, /* SUB */
|
|
270
|
+
prxchange('s/\\/\\\\/',-1,syswarningtext)
|
|
271
|
+
)))))))))))))!!'"';
|
|
272
|
+
end;
|
|
273
|
+
else syswarningtext=cats('"',syswarningtext,'"');
|
|
237
274
|
put ",""SYSWARNINGTEXT"" : " syswarningtext;
|
|
238
275
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
|
|
239
276
|
put "}" ;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Apply leading blanks to align numbers vertically in a char variable
|
|
4
|
+
@details This is particularly useful when storing numbers (as character) that
|
|
5
|
+
need to be sorted.
|
|
6
|
+
|
|
7
|
+
It works by splitting the number left and right of the decimal place, and
|
|
8
|
+
aligning it accordingly. A temporary variable is created as part of this
|
|
9
|
+
process (which is automatically dropped)
|
|
10
|
+
|
|
11
|
+
The macro can be used only in data step, eg as follows:
|
|
12
|
+
|
|
13
|
+
data _null_;
|
|
14
|
+
length myvar $50;
|
|
15
|
+
do i=1 to 1000 by 50;
|
|
16
|
+
if mod(i,2)=0 then j=ranuni(0)*i*100;
|
|
17
|
+
else j=i*100;
|
|
18
|
+
|
|
19
|
+
%mp_aligndecimal(myvar,width=7)
|
|
20
|
+
|
|
21
|
+
leading_spaces=length(myvar)-length(cats(myvar));
|
|
22
|
+
putlog +leading_spaces myvar;
|
|
23
|
+
end;
|
|
24
|
+
run;
|
|
25
|
+
|
|
26
|
+
The generated code will look something like this:
|
|
27
|
+
|
|
28
|
+
length aligndp4e49996 $7;
|
|
29
|
+
if index(myvar,'.') then do;
|
|
30
|
+
aligndp4e49996=cats(scan(myvar,1,'.'));
|
|
31
|
+
aligndp4e49996=right(aligndp4e49996);
|
|
32
|
+
myvar=aligndp4e49996!!'.'!!cats(scan(myvar,2,'.'));
|
|
33
|
+
end;
|
|
34
|
+
else do;
|
|
35
|
+
aligndp4e49996=myvar;
|
|
36
|
+
aligndp4e49996=right(aligndp4e49996);
|
|
37
|
+
myvar=aligndp4e49996;
|
|
38
|
+
end;
|
|
39
|
+
drop aligndp4e49996;
|
|
40
|
+
|
|
41
|
+
Results (myvar variable):
|
|
42
|
+
|
|
43
|
+
0.7683559324
|
|
44
|
+
122.8232796
|
|
45
|
+
99419.50552
|
|
46
|
+
42938.5143414
|
|
47
|
+
763.3799189
|
|
48
|
+
15170.606073
|
|
49
|
+
15083.285773
|
|
50
|
+
85443.198707
|
|
51
|
+
2022999.2251
|
|
52
|
+
12038.658867
|
|
53
|
+
1350582.6734
|
|
54
|
+
52777.258221
|
|
55
|
+
11723.347628
|
|
56
|
+
33101.268376
|
|
57
|
+
6181622.8603
|
|
58
|
+
7390614.0669
|
|
59
|
+
73384.537893
|
|
60
|
+
1788362.1016
|
|
61
|
+
2774586.2219
|
|
62
|
+
7998580.8415
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@param [in] var The (data step, character) variable to modify
|
|
66
|
+
@param [in] width= (8) The number of characters BEFORE the decimal point
|
|
67
|
+
|
|
68
|
+
<h4> SAS Macros </h4>
|
|
69
|
+
@li mf_getuniquename.sas
|
|
70
|
+
|
|
71
|
+
<h4> Related Programs </h4>
|
|
72
|
+
@li mp_aligndecimal.test.sas
|
|
73
|
+
|
|
74
|
+
@version 9.2
|
|
75
|
+
@author Allan Bowe
|
|
76
|
+
**/
|
|
77
|
+
|
|
78
|
+
%macro mp_aligndecimal(var,width=8);
|
|
79
|
+
|
|
80
|
+
%local tmpvar;
|
|
81
|
+
%let tmpvar=%mf_getuniquename(prefix=aligndp);
|
|
82
|
+
length &tmpvar $&width;
|
|
83
|
+
if index(&var,'.') then do;
|
|
84
|
+
&tmpvar=cats(scan(&var,1,'.'));
|
|
85
|
+
&tmpvar=right(&tmpvar);
|
|
86
|
+
&var=&tmpvar!!'.'!!cats(scan(&var,2,'.'));
|
|
87
|
+
end;
|
|
88
|
+
else do;
|
|
89
|
+
&tmpvar=cats(&var);
|
|
90
|
+
&tmpvar=right(&tmpvar);
|
|
91
|
+
&var=&tmpvar;
|
|
92
|
+
end;
|
|
93
|
+
drop &tmpvar;
|
|
94
|
+
|
|
95
|
+
%mend mp_aligndecimal;
|
package/macros/mp_appendfile.sas
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
%mp_appendfile(baseref=tmp1, appendrefs=tmp2 tmp3)
|
|
18
18
|
|
|
19
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
|
|
20
|
+
@param [in] baseref= (0) Fileref of the base file (should exist)
|
|
21
|
+
@param [in] appendrefs= (0) One or more filerefs to be appended to the base
|
|
22
22
|
fileref. Space separated.
|
|
23
23
|
|
|
24
24
|
@version 9.2
|
|
@@ -94,7 +94,7 @@ data &outds;
|
|
|
94
94
|
if libref(lib) ne 0 then do;
|
|
95
95
|
msg=catx(' ','libref',lib,'is not assigned!');
|
|
96
96
|
%if &errds=0 %then %do;
|
|
97
|
-
putlog
|
|
97
|
+
putlog 'ERR' +(-1) "OR: " msg;
|
|
98
98
|
%end;
|
|
99
99
|
output;
|
|
100
100
|
return;
|
|
@@ -102,7 +102,7 @@ data &outds;
|
|
|
102
102
|
if exist(cats(lib,'.',ds)) ne 1 then do;
|
|
103
103
|
msg=catx(' ','libds',lib,'.',ds,'does not exist!');
|
|
104
104
|
%if &errds=0 %then %do;
|
|
105
|
-
putlog
|
|
105
|
+
putlog 'ERR' +(-1) "OR: " msg;
|
|
106
106
|
%end;
|
|
107
107
|
output;
|
|
108
108
|
return;
|
|
@@ -111,7 +111,7 @@ data &outds;
|
|
|
111
111
|
if is_fmt=0 then do;
|
|
112
112
|
msg=catx(' ','format',fmt,'on libds',lib,'.',ds,'.',var,'is not valid!');
|
|
113
113
|
%if &errds=0 %then %do;
|
|
114
|
-
putlog
|
|
114
|
+
putlog 'ERR' +(-1) "OR: " msg;
|
|
115
115
|
%end;
|
|
116
116
|
output;
|
|
117
117
|
return;
|
|
@@ -123,7 +123,7 @@ data &outds;
|
|
|
123
123
|
if dsid=0 then do;
|
|
124
124
|
msg=catx(' ','libds',lib,'.',ds,' could not be opened!');
|
|
125
125
|
%if &errds=0 %then %do;
|
|
126
|
-
putlog
|
|
126
|
+
putlog 'ERR' +(-1) "OR: " msg;
|
|
127
127
|
%end;
|
|
128
128
|
output;
|
|
129
129
|
return;
|
|
@@ -131,7 +131,7 @@ data &outds;
|
|
|
131
131
|
if varnum(dsid,var)<1 then do;
|
|
132
132
|
msg=catx(' ','Variable',lib,'.',ds,'.',var,' was not found!');
|
|
133
133
|
%if &errds=0 %then %do;
|
|
134
|
-
putlog
|
|
134
|
+
putlog 'ERR' +(-1) "OR: " msg;
|
|
135
135
|
%end;
|
|
136
136
|
output;
|
|
137
137
|
end;
|
package/macros/mp_assert.sas
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
results. If it does not exist, it will be created, with the following format:
|
|
23
23
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|
24
24
|
|---|---|---|
|
|
25
|
-
|User Provided description|PASS|
|
|
25
|
+
|User Provided description|PASS|Dataset &inds contained ALL columns|
|
|
26
26
|
|
|
27
27
|
@version 9.2
|
|
28
28
|
@author Allan Bowe
|
package/macros/mp_assertcols.sas
CHANGED
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
|
|
32
32
|
|
|
33
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= (
|
|
34
|
+
@param [in] cols= (0) The list of columns to check for
|
|
35
|
+
@param [in] desc= (0) The user provided test description
|
|
36
36
|
@param [in] test= (ALL) The test to apply. Valid values are:
|
|
37
37
|
@li ALL - Test is a PASS if ALL columns exist in &inds
|
|
38
38
|
@li ANY - Test is a PASS if ANY of the columns exist in &inds
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
results. If it does not exist, it will be created, with the following format:
|
|
42
42
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|
43
43
|
|---|---|---|
|
|
44
|
-
|User Provided description|PASS|
|
|
44
|
+
|User Provided description|PASS|Dataset &inds contained ALL columns|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
<h4> Related Macros </h4>
|
|
@@ -36,12 +36,13 @@
|
|
|
36
36
|
|
|
37
37
|
|
|
38
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
|
|
39
|
+
@param [in] checkvals= (0) A library.dataset.column value containing a UNIQUE
|
|
40
40
|
list of values to be compared against the source (indscol).
|
|
41
41
|
@param [in] desc= (Testing observations) The user provided test description
|
|
42
42
|
@param [in] test= (ALLVALS) The test to apply. Valid values are:
|
|
43
43
|
@li ALLVALS - Test is a PASS if ALL values have a match in checkvals
|
|
44
44
|
@li ANYVAL - Test is a PASS if at least 1 value has a match in checkvals
|
|
45
|
+
@li NOVAL - Test is a PASS if there are NO matches in checkvals
|
|
45
46
|
@param [out] outds= (work.test_results) The output dataset to contain the
|
|
46
47
|
results. If it does not exist, it will be created, with the following format:
|
|
47
48
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|
@@ -97,7 +98,7 @@
|
|
|
97
98
|
|
|
98
99
|
%let test=%upcase(&test);
|
|
99
100
|
|
|
100
|
-
%if &test ne ALLVALS and &test ne ANYVAL %then %do;
|
|
101
|
+
%if &test ne ALLVALS and &test ne ANYVAL and &test ne NOVAL %then %do;
|
|
101
102
|
%mp_abort(
|
|
102
103
|
mac=&sysmacroname,
|
|
103
104
|
msg=%str(Invalid test - &test)
|
|
@@ -108,12 +109,12 @@
|
|
|
108
109
|
%let result=-1;
|
|
109
110
|
%let orig=-1;
|
|
110
111
|
proc sql noprint;
|
|
111
|
-
select count(*) into: result
|
|
112
|
+
select count(*) into: result trimmed
|
|
112
113
|
from &lib..&ds
|
|
113
114
|
where &col not in (
|
|
114
115
|
select &ccol from &clib..&cds
|
|
115
116
|
);
|
|
116
|
-
select count(*) into: orig from &lib..&ds;
|
|
117
|
+
select count(*) into: orig trimmed from &lib..&ds;
|
|
117
118
|
quit;
|
|
118
119
|
|
|
119
120
|
%local notfound tmp1 tmp2;
|
|
@@ -145,7 +146,7 @@
|
|
|
145
146
|
length test_description $256 test_result $4 test_comments $256;
|
|
146
147
|
test_description=symget('desc');
|
|
147
148
|
test_result='FAIL';
|
|
148
|
-
test_comments="&sysmacroname: &lib..&ds..&col has &result values "
|
|
149
|
+
test_comments="&sysmacroname: &lib..&ds..&col has &result/&orig values "
|
|
149
150
|
!!"not in &clib..&cds..&ccol.. First 10 vals:"!!symget('notfound');
|
|
150
151
|
%if &test=ANYVAL %then %do;
|
|
151
152
|
if &result < &orig then test_result='PASS';
|
|
@@ -153,6 +154,9 @@
|
|
|
153
154
|
%else %if &test=ALLVALS %then %do;
|
|
154
155
|
if &result=0 then test_result='PASS';
|
|
155
156
|
%end;
|
|
157
|
+
%else %if &test=NOVAL %then %do;
|
|
158
|
+
if &result=&orig then test_result='PASS';
|
|
159
|
+
%end;
|
|
156
160
|
%else %do;
|
|
157
161
|
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
|
158
162
|
%end;
|
package/macros/mp_base64copy.sas
CHANGED
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
put _infile_;
|
|
29
29
|
run;
|
|
30
30
|
|
|
31
|
-
@param [in] inref= Fileref of the input file (should exist)
|
|
32
|
-
@param [out] outref= Output fileref. If it does not exist, it is created.
|
|
31
|
+
@param [in] inref= (0) Fileref of the input file (should exist)
|
|
32
|
+
@param [out] outref= (0) Output fileref. If it does not exist, it is created.
|
|
33
33
|
@param [in] action= (ENCODE) The action to take. Valid values:
|
|
34
34
|
@li ENCODE - Convert the file to base64 format
|
|
35
35
|
@li DECODE - Decode the file from base64 format
|
package/macros/mp_binarycopy.sas
CHANGED
|
@@ -22,16 +22,17 @@
|
|
|
22
22
|
%mp_binarycopy(inref=tmp1, outref=tmp2, mode=APPEND)
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
@param [in] inloc quoted "path/and/filename.ext" of the file to be copied
|
|
26
|
-
@param [out] outloc quoted "path/and/filename.ext" of the file to
|
|
27
|
-
@param [in] inref (____in) If provided, this fileref
|
|
25
|
+
@param [in] inloc= () quoted "path/and/filename.ext" of the file to be copied
|
|
26
|
+
@param [out] outloc= () quoted "path/and/filename.ext" of the file to create
|
|
27
|
+
@param [in] inref= (____in) If provided, this fileref takes precedence over
|
|
28
28
|
the `inloc` parameter
|
|
29
|
-
@param [out] outref (____in) If provided, this fileref
|
|
29
|
+
@param [out] outref= (____in) If provided, this fileref takes precedence
|
|
30
30
|
over the `outloc` parameter. It must already exist!
|
|
31
|
-
@param [in] mode (CREATE) Valid values:
|
|
31
|
+
@param [in] mode= (CREATE) Valid values:
|
|
32
32
|
@li CREATE - Create the file (even if it already exists)
|
|
33
33
|
@li APPEND - Append to the file (don't overwrite)
|
|
34
|
-
@param iftrue= (1=1)
|
|
34
|
+
@param [in] iftrue= (1=1)
|
|
35
|
+
Supply a condition for which the macro should be executed
|
|
35
36
|
|
|
36
37
|
@returns nothing
|
|
37
38
|
|
package/macros/mp_chop.sas
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
For more examples, see mp_chop.test.sas
|
|
45
45
|
|
|
46
46
|
@param [in] infile The QUOTED path to the file on which to perform the chop
|
|
47
|
-
@param [in] matchvar= Macro variable NAME containing the string to split by
|
|
47
|
+
@param [in] matchvar= () Macro variable NAME containing the string to split by
|
|
48
48
|
@param [in] matchpoint= (START) Valid values:
|
|
49
49
|
@li START - chop at the beginning of the string in `matchvar`.
|
|
50
50
|
@li END - chop at the end of the string in `matchvar`.
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
@li FIRST - keep the section of the file before the chop
|
|
55
55
|
@li LAST - keep the section of the file after the chop
|
|
56
56
|
@param [in] mdebug= (0) Set to 1 to provide macro debugging
|
|
57
|
-
@param outfile= (0)
|
|
57
|
+
@param [out] outfile= (0)
|
|
58
|
+
Optional QUOTED path to the adjusted output file (avoids
|
|
58
59
|
overwriting the first file).
|
|
59
60
|
|
|
60
61
|
<h4> SAS Macros </h4>
|
|
@@ -185,7 +186,7 @@ run;
|
|
|
185
186
|
infile &outfile lrecl=32767;
|
|
186
187
|
input;
|
|
187
188
|
list;
|
|
188
|
-
if _n_>
|
|
189
|
+
if _n_>200 then stop;
|
|
189
190
|
run;
|
|
190
191
|
%end;
|
|
191
192
|
/* END */
|
package/macros/mp_cleancsv.sas
CHANGED
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
fileref mycsv "/path/your/csv";
|
|
13
13
|
%mp_cleancsv(in=mycsv,out=/path/new.csv)
|
|
14
14
|
|
|
15
|
-
@param in= (NOTPROVIDED)
|
|
15
|
+
@param [in] in= (NOTPROVIDED)
|
|
16
|
+
Provide path or fileref to input csv. If a period is
|
|
16
17
|
found, it is assumed to be a file.
|
|
17
|
-
@param out= (NOTPROVIDED) Output path or fileref to output csv.
|
|
18
|
-
is found, it is assumed to be a file.
|
|
19
|
-
@param qchar= ('22'x) Quote char - hex code 22 is the double quote.
|
|
18
|
+
@param [in] out= (NOTPROVIDED) Output path or fileref to output csv.
|
|
19
|
+
If a period is found, it is assumed to be a file.
|
|
20
|
+
@param [in] qchar= ('22'x) Quote char - hex code 22 is the double quote.
|
|
20
21
|
|
|
21
22
|
@version 9.2
|
|
22
23
|
@author Allan Bowe
|
package/macros/mp_cntlout.sas
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
<h4> SAS Macros </h4>
|
|
26
26
|
@li mddl_sas_cntlout.sas
|
|
27
27
|
@li mf_getuniquename.sas
|
|
28
|
+
@li mp_aligndecimal.sas
|
|
28
29
|
|
|
29
30
|
<h4> Related Macros </h4>
|
|
30
31
|
@li mf_getvarformat.sas
|
|
@@ -57,25 +58,33 @@
|
|
|
57
58
|
%end;
|
|
58
59
|
|
|
59
60
|
proc format lib=&libcat cntlout=&cntlds;
|
|
60
|
-
%if "&fmtlist" ne "0" %then %do;
|
|
61
|
+
%if "&fmtlist" ne "0" and "&fmtlist" ne "" %then %do;
|
|
61
62
|
select
|
|
62
|
-
%do i=1 %to %sysfunc(countw(&fmtlist));
|
|
63
|
+
%do i=1 %to %sysfunc(countw(&fmtlist,%str( )));
|
|
63
64
|
%scan(&fmtlist,&i,%str( ))
|
|
64
65
|
%end;
|
|
65
66
|
;
|
|
66
67
|
%end;
|
|
67
68
|
run;
|
|
68
69
|
|
|
69
|
-
data &cntlout;
|
|
70
|
+
data &cntlout/nonote2err;
|
|
70
71
|
if 0 then set &ddlds;
|
|
71
72
|
set &cntlds;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
by type fmtname notsorted;
|
|
74
|
+
|
|
75
|
+
/* align the numeric values to avoid overlapping ranges */
|
|
76
|
+
if type in ("I","N") then do;
|
|
77
|
+
%mp_aligndecimal(start,width=16)
|
|
78
|
+
%mp_aligndecimal(end,width=16)
|
|
75
79
|
end;
|
|
80
|
+
|
|
81
|
+
/* create row marker. Data cannot be sorted without it! */
|
|
82
|
+
if first.fmtname then fmtrow=1;
|
|
83
|
+
else fmtrow+1;
|
|
84
|
+
|
|
76
85
|
run;
|
|
77
86
|
proc sort;
|
|
78
|
-
by fmtname
|
|
87
|
+
by type fmtname fmtrow;
|
|
79
88
|
run;
|
|
80
89
|
|
|
81
90
|
proc sql;
|
package/macros/mp_copyfolder.sas
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
@param [in] source Unquoted path to the folder to copy from.
|
|
20
20
|
@param [out] target Unquoted path to the folder to copy to.
|
|
21
|
-
@param [in] copymax=(MAX) Set to a positive integer to indicate the level of
|
|
21
|
+
@param [in] copymax= (MAX) Set to a positive integer to indicate the level of
|
|
22
22
|
subdirectory copy recursion - eg 3, to go `./3/levels/deep`. For unlimited
|
|
23
23
|
recursion, set to MAX.
|
|
24
24
|
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
rc2=filename(fref2,filepath2,'disk','recfm=n');
|
|
70
70
|
if fcopy(fref1,fref2) ne 0 then do;
|
|
71
71
|
msg=sysmsg();
|
|
72
|
-
putlog
|
|
72
|
+
putlog 'ERR' +(-1) "OR: Unable to copy " filepath " to " filepath2;
|
|
73
73
|
putlog msg=;
|
|
74
74
|
end;
|
|
75
75
|
end;
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
%mp_deleteconstraints(inds=work.constraints,outds=dropped,execute=YES)
|
|
19
19
|
%mp_createconstraints(inds=work.constraints,outds=created,execute=YES)
|
|
20
20
|
|
|
21
|
-
@param inds= (work.mp_getconstraints) The input table containing the
|
|
21
|
+
@param [in] inds= (work.mp_getconstraints) The input table containing the
|
|
22
22
|
constraint info
|
|
23
|
-
@param outds= (work.mp_createconstraints) A table containing the create
|
|
23
|
+
@param [out] outds= (work.mp_createconstraints) A table containing the create
|
|
24
24
|
statements (create_statement column)
|
|
25
|
-
@param execute= (NO) To actually create, use YES.
|
|
25
|
+
@param [in] execute= (NO) To actually create, use YES.
|
|
26
26
|
|
|
27
27
|
<h4> Related Files </h4>
|
|
28
28
|
@li mp_getconstraints.sas
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@file mp_createwebservice.sas
|
|
3
|
-
@brief Create a web service in SAS 9, Viya or SASjs Server
|
|
3
|
+
@brief Create a web service in SAS 9, Viya or SASjs Server (legacy)
|
|
4
4
|
@details This is actually a wrapper for mx_createwebservice.sas, remaining
|
|
5
5
|
for legacy purposes. For new apps, use mx_createwebservice.sas.
|
|
6
6
|
|
package/macros/mp_csv2ds.sas
CHANGED
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
%mp_csv2ds(inref=mycsv,outds=myds,baseds=sashelp.class)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
@param inref=
|
|
23
|
-
@param outds=
|
|
24
|
-
@param view= Set to YES or NO to determine whether the output
|
|
25
|
-
a view or not. Default is NO (not a view).
|
|
26
|
-
@param baseds=
|
|
22
|
+
@param [in] inref= (0) Fileref to the CSV
|
|
23
|
+
@param [out] outds= (0) Output ds (lib.ds format)
|
|
24
|
+
@param [in] view= (NO) Set to YES or NO to determine whether the output
|
|
25
|
+
should be a view or not. Default is NO (not a view).
|
|
26
|
+
@param [in] baseds= (0)
|
|
27
|
+
Template dataset on which to create the input statement.
|
|
27
28
|
Is used to determine types, lengths, and any informats.
|
|
28
29
|
|
|
29
30
|
@version 9.2
|
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
%mp_getconstraints(lib=work,ds=example,outds=work.constraints)
|
|
18
18
|
%mp_deleteconstraints(inds=work.constraints,outds=dropped,execute=YES)
|
|
19
19
|
|
|
20
|
-
@param inds=
|
|
21
|
-
|
|
22
|
-
@param
|
|
20
|
+
@param [in] inds= (mp_getconstraints)
|
|
21
|
+
The input table containing constraint info
|
|
22
|
+
@param [out] outds= (mp_deleteconstraints)
|
|
23
|
+
Table containing the drop statements (drop_statement column)
|
|
24
|
+
@param [in] execute= (NO) `YES|NO` - default is NO. To actually drop, use YES.
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
@version 9.2
|