@sasjs/utils 3.5.1 → 3.5.3

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.
Files changed (102) hide show
  1. package/file/file.js +4 -2
  2. package/file/file.js.map +1 -1
  3. package/macros/mf_abort.sas +7 -2
  4. package/macros/mf_deletefile.sas +1 -1
  5. package/macros/mf_existds.sas +1 -1
  6. package/macros/mf_existfileref.sas +2 -2
  7. package/macros/mf_existfunction.sas +1 -1
  8. package/macros/mf_existvar.sas +8 -4
  9. package/macros/mf_existvarlist.sas +2 -2
  10. package/macros/mf_getapploc.sas +1 -0
  11. package/macros/mf_getattrc.sas +2 -2
  12. package/macros/mf_getattrn.sas +2 -2
  13. package/macros/mf_getfmtlist.sas +3 -4
  14. package/macros/mf_getgitbranch.sas +37 -0
  15. package/macros/mf_getkeyvalue.sas +3 -2
  16. package/macros/mf_getplatform.sas +1 -1
  17. package/macros/mf_getschema.sas +1 -1
  18. package/macros/mf_getuniquelibref.sas +2 -2
  19. package/macros/mf_getuniquename.sas +1 -1
  20. package/macros/mf_getuser.sas +0 -2
  21. package/macros/mf_getvalue.sas +3 -3
  22. package/macros/mf_getvarformat.sas +2 -1
  23. package/macros/mf_getvarlen.sas +2 -2
  24. package/macros/mf_getvarnum.sas +2 -2
  25. package/macros/mf_getvartype.sas +2 -2
  26. package/macros/mf_getxengine.sas +1 -1
  27. package/macros/mf_increment.sas +2 -2
  28. package/macros/mf_isblank.sas +2 -2
  29. package/macros/mf_isdir.sas +1 -1
  30. package/macros/mf_loc.sas +6 -1
  31. package/macros/mf_mimetype.sas +436 -0
  32. package/macros/mf_mkdir.sas +1 -1
  33. package/macros/mf_mval.sas +2 -0
  34. package/macros/mf_nobs.sas +1 -1
  35. package/macros/mf_readfile.sas +63 -0
  36. package/macros/mf_trimstr.sas +2 -2
  37. package/macros/mf_wordsinstr1andstr2.sas +2 -2
  38. package/macros/mf_wordsinstr1butnotstr2.sas +2 -2
  39. package/macros/mf_writefile.sas +2 -2
  40. package/macros/mp_abort.sas +50 -13
  41. package/macros/mp_aligndecimal.sas +95 -0
  42. package/macros/mp_appendfile.sas +2 -2
  43. package/macros/mp_applyformats.sas +5 -5
  44. package/macros/mp_assert.sas +1 -1
  45. package/macros/mp_assertcols.sas +3 -3
  46. package/macros/mp_assertcolvals.sas +9 -5
  47. package/macros/mp_assertscope.sas +4 -4
  48. package/macros/mp_base64copy.sas +2 -2
  49. package/macros/mp_binarycopy.sas +7 -6
  50. package/macros/mp_chop.sas +4 -3
  51. package/macros/mp_cleancsv.sas +5 -4
  52. package/macros/mp_cntlout.sas +16 -7
  53. package/macros/mp_copyfolder.sas +2 -2
  54. package/macros/mp_createconstraints.sas +3 -3
  55. package/macros/mp_createwebservice.sas +1 -1
  56. package/macros/mp_csv2ds.sas +6 -5
  57. package/macros/mp_deleteconstraints.sas +5 -3
  58. package/macros/mp_deletefolder.sas +1 -1
  59. package/macros/mp_dictionary.sas +1 -1
  60. package/macros/mp_dirlist.sas +1 -1
  61. package/macros/mp_distinctfmtvalues.sas +5 -5
  62. package/macros/mp_ds2csv.sas +10 -1
  63. package/macros/mp_ds2ddl.sas +14 -2
  64. package/macros/mp_ds2md.sas +1 -0
  65. package/macros/mp_dsmeta.sas +2 -2
  66. package/macros/mp_filtercheck.sas +105 -16
  67. package/macros/mp_filtergenerate.sas +2 -2
  68. package/macros/mp_filterstore.sas +4 -3
  69. package/macros/mp_getcols.sas +6 -4
  70. package/macros/mp_getdbml.sas +4 -4
  71. package/macros/mp_getddl.sas +15 -10
  72. package/macros/mp_getformats.sas +13 -3
  73. package/macros/mp_gitlog.sas +104 -0
  74. package/macros/mp_gitstatus.sas +1 -1
  75. package/macros/mp_gsubfile.sas +6 -6
  76. package/macros/mp_guesspk.sas +1 -1
  77. package/macros/mp_hashdataset.sas +1 -1
  78. package/macros/mp_init.sas +1 -0
  79. package/macros/mp_lib2cards.sas +7 -7
  80. package/macros/mp_loadformat.sas +127 -47
  81. package/macros/mp_lockanytable.sas +31 -24
  82. package/macros/mp_md5.sas +3 -4
  83. package/macros/mp_perflog.sas +3 -3
  84. package/macros/mp_prevobs.sas +5 -5
  85. package/macros/mp_recursivejoin.sas +7 -6
  86. package/macros/mp_replace.sas +7 -5
  87. package/macros/mp_runddl.sas +3 -3
  88. package/macros/mp_searchcols.sas +7 -6
  89. package/macros/mp_stackdiffs.sas +1 -0
  90. package/macros/mp_storediffs.sas +8 -8
  91. package/macros/mp_stprequests.sas +4 -3
  92. package/macros/mp_stripdiffs.sas +256 -0
  93. package/macros/mp_testjob.sas +2 -2
  94. package/macros/mp_testwritespeedlibrary.sas +3 -3
  95. package/macros/mp_tree.sas +2 -2
  96. package/macros/mp_unzip.sas +5 -4
  97. package/macros/mp_updatevarlength.sas +3 -3
  98. package/macros/mp_validatecol.sas +3 -3
  99. package/macros/mp_wait4file.sas +1 -1
  100. package/macros/mp_webin.sas +1 -1
  101. package/macros/mp_zip.sas +5 -5
  102. package/package.json +5 -6
@@ -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 not
31
- use &sysmacroname as this will always resolve to MP_ABORT.
32
- @param msg= message to be returned
33
- @param iftrue= (1=1) Supply a condition for which the macro should be executed
34
- @param errds= (work.mp_abort_errds) There is no clean way to end a process
35
- within a %include called within a macro. Furthermore, there is no way to
36
- test if a macro is called within a %include. To handle this particular
37
- scenario, the %include should be switched for the mp_include.sas macro.
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 for
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('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
229
- put ",""SYSERRORTEXT"" : " syserrortext;
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('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
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;
@@ -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 "%str(ERR)OR: " msg;
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 "%str(ERR)OR: " msg;
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 "%str(ERR)OR: " msg;
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 "%str(ERR)OR: " msg;
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 "%str(ERR)OR: " msg;
134
+ putlog 'ERR' +(-1) "OR: " msg;
135
135
  %end;
136
136
  output;
137
137
  end;
@@ -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|Column &inds contained ALL columns|
25
+ |User Provided description|PASS|Dataset &inds contained ALL columns|
26
26
 
27
27
  @version 9.2
28
28
  @author Allan Bowe
@@ -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= (Testing observations) The user provided test description
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|Column &inds contained ALL columns|
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;
@@ -73,10 +73,6 @@
73
73
  ignorelist=,
74
74
  outds=work.test_results
75
75
  )/*/STORE SOURCE*/;
76
- %local ds test_result test_comments del add mod ilist;
77
- %let ilist=%upcase(&sasjs_prefix._FUNCTIONS SYS_PROCHTTP_STATUS_CODE
78
- SYS_PROCHTTP_STATUS_CODE SYS_PROCHTTP_STATUS_PHRASE &ignorelist);
79
-
80
76
  /**
81
77
  * this sets up the global vars, it will also enter STRICT mode. If this
82
78
  * behaviour is not desired, simply initiate the following global macro
@@ -84,6 +80,10 @@
84
80
  */
85
81
  %mp_init()
86
82
 
83
+ %local ds test_result test_comments del add mod ilist;
84
+ %let ilist=%upcase(&sasjs_prefix._FUNCTIONS SYS_PROCHTTP_STATUS_CODE
85
+ SYS_PROCHTTP_STATUS_CODE SYS_PROCHTTP_STATUS_PHRASE &ignorelist);
86
+
87
87
  /* get current variables */
88
88
  %if &action=SNAPSHOT %then %do;
89
89
  proc sql;
@@ -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
@@ -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 be created
27
- @param [in] inref (____in) If provided, this fileref will take precedence over
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 will take precedence
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) Supply a condition for which the macro should be executed
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
 
@@ -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) Optional QUOTED path to the adjusted output file (avoids
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_>50 then stop;
189
+ if _n_>200 then stop;
189
190
  run;
190
191
  %end;
191
192
  /* END */
@@ -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) Provide path or fileref to input csv. If a period is
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. If a period
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
@@ -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
- if type="N" then do;
73
- start=cats(start);
74
- end=cats(end);
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 start;
87
+ by type fmtname fmtrow;
79
88
  run;
80
89
 
81
90
  proc sql;
@@ -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 "%str(ERR)OR: Unable to copy " filepath " to " filepath2;
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
 
@@ -19,11 +19,12 @@
19
19
  %mp_csv2ds(inref=mycsv,outds=myds,baseds=sashelp.class)
20
20
 
21
21
 
22
- @param inref= fileref to the CSV
23
- @param outds= output ds (lib.ds format)
24
- @param view= Set to YES or NO to determine whether the output should be
25
- a view or not. Default is NO (not a view).
26
- @param baseds= Template dataset on which to create the input statement.
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= The input table containing the constraint info
21
- @param outds= a table containing the drop statements (drop_statement column)
22
- @param execute= `YES|NO` - default is NO. To actually drop, use YES.
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
@@ -15,7 +15,7 @@
15
15
 
16
16
  %mp_deletefolder(&rootdir)
17
17
 
18
- @param path Unquoted path to the folder to delete.
18
+ @param [in] folder Unquoted path to the folder to delete.
19
19
 
20
20
  <h4> SAS Macros </h4>
21
21
  @li mf_getuniquename.sas
@@ -29,7 +29,7 @@
29
29
 
30
30
  ![](https://user-images.githubusercontent.com/4420615/188278365-2987db97-0594-4a39-ac81-dbacdef5cdc8.png)
31
31
 
32
- @param lib= (WORK) The libref in which to create the views
32
+ @param [in] lib= (WORK) The libref in which to create the views
33
33
 
34
34
  <h4> Related Files </h4>
35
35
  @li mp_dictionary.test.sas
@@ -85,7 +85,7 @@ data;run;
85
85
  data &out_ds(compress=no
86
86
  keep=file_or_folder filepath filename ext msg directory level
87
87
  );
88
- length directory filepath $500 fref fref2 $8 file_or_folder $6 filename $80
88
+ length directory filepath $2000 fref fref2 $8 file_or_folder $6 filename $255
89
89
  ext $20 msg $200 foption $16;
90
90
  if _n_=1 then call missing(of _all_);
91
91
  retain level &level;
@@ -7,11 +7,11 @@
7
7
 
8
8
  %mp_distinctfmtvalues(libds=sashelp.class,var=age,outvar=age,outds=test)
9
9
 
10
- @param libds input dataset
11
- @param var variable to get distinct values for
12
- @param outvar variable to create. Default: `formatted_value`
13
- @param outds dataset to create. Default: work.mp_distinctfmtvalues
14
- @param varlen length of variable to create (default 200)
10
+ @param [in] libds= () input dataset
11
+ @param [in] var= (0) variable to get distinct values for
12
+ @param [out] outvar= (formatteed_value) variable to create.
13
+ @param [out] outds= (work.mp_distinctfmtvalues) dataset to create.
14
+ @param [in] varlen= (2000) length of variable to create
15
15
 
16
16
  @version 9.2
17
17
  @author Allan Bowe
@@ -118,13 +118,21 @@ data _null_;
118
118
  header = cats(coalescec(varlabel(dsid,i),varnm),dlm);
119
119
  %end;
120
120
  %else %if &headerformat=SASJS %then %do;
121
- if vartype(dsid,i)='C' then header=cats(varnm,':$char',varlen(dsid,i),'.');
121
+ vlen=varlen(dsid,i);
122
+ if vartype(dsid,i)='C' then header=cats(varnm,':$char',vlen,'.');
122
123
  else do;
123
124
  vfmt=coalescec(varfmt(dsid,i),'0');
124
125
  fmttype=mcf_getfmttype(vfmt);
125
126
  if fmttype='DATE' then header=cats(varnm,':date9.');
126
127
  else if fmttype='DATETIME' then header=cats(varnm,':E8601DT26.6');
127
128
  else if fmttype='TIME' then header=cats(varnm,':TIME12.');
129
+ /**
130
+ * there is not much point importing a short length numeric like this,
131
+ * eg with best4., as the resulting variable will still be stored as
132
+ * length 8. We need a length or format statement to ensure variable
133
+ * is creatd with the smaller length...
134
+ **/
135
+ else if vlen<8 then header=cats(varnm,':best',vlen,'.');
128
136
  else header=cats(varnm,':best.');
129
137
  end;
130
138
  %end;
@@ -151,6 +159,7 @@ data _null_;
151
159
  set &ds end=last;
152
160
  %do i=1 %to &vcnt;
153
161
  %let var=%scan(&varlist,&i);
162
+ %local vlen&i;
154
163
  %if %mf_getvartype(&ds,&var)=C %then %do;
155
164
  %let dsv1=%mf_getuniquename(prefix=csvcol1_);
156
165
  %let dsv2=%mf_getuniquename(prefix=csvcol2_);