@sasjs/utils 3.5.1 → 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.
Files changed (100) 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 +1 -1
  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_mkdir.sas +1 -1
  32. package/macros/mf_mval.sas +2 -0
  33. package/macros/mf_nobs.sas +1 -1
  34. package/macros/mf_readfile.sas +63 -0
  35. package/macros/mf_trimstr.sas +2 -2
  36. package/macros/mf_wordsinstr1andstr2.sas +2 -2
  37. package/macros/mf_wordsinstr1butnotstr2.sas +2 -2
  38. package/macros/mf_writefile.sas +2 -2
  39. package/macros/mp_abort.sas +50 -13
  40. package/macros/mp_aligndecimal.sas +95 -0
  41. package/macros/mp_appendfile.sas +2 -2
  42. package/macros/mp_applyformats.sas +5 -5
  43. package/macros/mp_assert.sas +1 -1
  44. package/macros/mp_assertcols.sas +3 -3
  45. package/macros/mp_assertcolvals.sas +9 -5
  46. package/macros/mp_base64copy.sas +2 -2
  47. package/macros/mp_binarycopy.sas +7 -6
  48. package/macros/mp_chop.sas +4 -3
  49. package/macros/mp_cleancsv.sas +5 -4
  50. package/macros/mp_cntlout.sas +16 -7
  51. package/macros/mp_copyfolder.sas +2 -2
  52. package/macros/mp_createconstraints.sas +3 -3
  53. package/macros/mp_createwebservice.sas +1 -1
  54. package/macros/mp_csv2ds.sas +6 -5
  55. package/macros/mp_deleteconstraints.sas +5 -3
  56. package/macros/mp_deletefolder.sas +1 -1
  57. package/macros/mp_dictionary.sas +1 -1
  58. package/macros/mp_dirlist.sas +1 -1
  59. package/macros/mp_distinctfmtvalues.sas +5 -5
  60. package/macros/mp_ds2csv.sas +10 -1
  61. package/macros/mp_ds2ddl.sas +14 -2
  62. package/macros/mp_ds2md.sas +1 -0
  63. package/macros/mp_dsmeta.sas +2 -2
  64. package/macros/mp_filtercheck.sas +105 -16
  65. package/macros/mp_filtergenerate.sas +2 -2
  66. package/macros/mp_filterstore.sas +4 -3
  67. package/macros/mp_getcols.sas +3 -2
  68. package/macros/mp_getdbml.sas +4 -4
  69. package/macros/mp_getddl.sas +15 -10
  70. package/macros/mp_getformats.sas +13 -3
  71. package/macros/mp_gitlog.sas +104 -0
  72. package/macros/mp_gitstatus.sas +1 -1
  73. package/macros/mp_gsubfile.sas +6 -6
  74. package/macros/mp_guesspk.sas +1 -1
  75. package/macros/mp_hashdataset.sas +1 -1
  76. package/macros/mp_init.sas +1 -0
  77. package/macros/mp_lib2cards.sas +7 -7
  78. package/macros/mp_loadformat.sas +127 -47
  79. package/macros/mp_lockanytable.sas +31 -24
  80. package/macros/mp_md5.sas +3 -4
  81. package/macros/mp_perflog.sas +3 -3
  82. package/macros/mp_prevobs.sas +5 -5
  83. package/macros/mp_recursivejoin.sas +7 -6
  84. package/macros/mp_replace.sas +5 -4
  85. package/macros/mp_runddl.sas +3 -3
  86. package/macros/mp_searchcols.sas +7 -6
  87. package/macros/mp_stackdiffs.sas +1 -0
  88. package/macros/mp_storediffs.sas +8 -8
  89. package/macros/mp_stprequests.sas +4 -3
  90. package/macros/mp_stripdiffs.sas +255 -0
  91. package/macros/mp_testjob.sas +2 -2
  92. package/macros/mp_testwritespeedlibrary.sas +3 -3
  93. package/macros/mp_tree.sas +2 -2
  94. package/macros/mp_unzip.sas +5 -4
  95. package/macros/mp_updatevarlength.sas +3 -3
  96. package/macros/mp_validatecol.sas +3 -3
  97. package/macros/mp_wait4file.sas +1 -1
  98. package/macros/mp_webin.sas +1 -1
  99. package/macros/mp_zip.sas +5 -5
  100. package/package.json +5 -6
@@ -9,6 +9,9 @@
9
9
  format, to prevent loss of data - UNLESS the input dataset contains a marker
10
10
  column, specifying that a particular row needs to be deleted (`delete_col=`).
11
11
 
12
+ Positions of formats are made using the FMTROW variable - this must be present
13
+ and unique (on TYPE / FMTNAME / FMTROW).
14
+
12
15
  This macro can also be used to identify which records would be (or were)
13
16
  considered new, modified or deleted (`loadtarget=`) by creating the following
14
17
  tables:
@@ -17,7 +20,7 @@
17
20
  @li work.outds_del
18
21
  @li work.outds_mod
19
22
 
20
- For example usage, see mp_loadformat.test.sas
23
+ For example usage, see test (under Related Macros)
21
24
 
22
25
  @param [in] libcat The format catalog to be loaded
23
26
  @param [in] libds The staging table to load
@@ -34,18 +37,22 @@
34
37
  @param [in] mdebug= (0) Set to 1 to enable DEBUG messages and preserve outputs
35
38
 
36
39
  <h4> SAS Macros </h4>
37
- @li mddl_sas_cntlout.sas
40
+ @li mf_existds.sas
41
+ @li mf_existvar.sas
38
42
  @li mf_getuniquename.sas
39
43
  @li mf_nobs.sas
40
44
  @li mp_abort.sas
45
+ @li mp_aligndecimal.sas
41
46
  @li mp_cntlout.sas
42
47
  @li mp_lockanytable.sas
48
+ @li mp_md5.sas
43
49
  @li mp_storediffs.sas
44
50
 
45
51
  <h4> Related Macros </h4>
46
52
  @li mddl_dc_difftable.sas
47
53
  @li mddl_dc_locktable.sas
48
- @li mp_loadformat.test.sas
54
+ @li mp_loadformat.test.1.sas
55
+ @li mp_loadformat.test.2.sas
49
56
  @li mp_lockanytable.sas
50
57
  @li mp_stackdiffs.sas
51
58
 
@@ -67,7 +74,7 @@
67
74
  );
68
75
  /* set up local macro variables and temporary tables (with a prefix) */
69
76
  %local err msg prefix dslist i var fmtlist ibufsize;
70
- %let dslist=base_fmts template inlibds ds1 stagedata storediffs;
77
+ %let dslist=base_fmts template inlibds ds1 stagedata storediffs del1 del2;
71
78
  %if &outds_add=0 %then %let dslist=&dslist outds_add;
72
79
  %if &outds_del=0 %then %let dslist=&dslist outds_del;
73
80
  %if &outds_mod=0 %then %let dslist=&dslist outds_mod;
@@ -78,17 +85,20 @@
78
85
  %let &var=%upcase(&prefix._&var);
79
86
  %end;
80
87
 
81
- /*
82
- format values can be up to 32767 wide. SQL joins on such a wide column can
83
- cause buffer issues. Update ibufsize and reset at the end.
84
- */
85
- %let ibufsize=%sysfunc(getoption(ibufsize));
86
- options ibufsize=32767 ;
87
-
88
88
  /* in DC, format catalogs maybe specified in the libds with a -FC extension */
89
89
  %let libcat=%scan(&libcat,1,-);
90
90
 
91
91
  /* perform input validations */
92
+ %mp_abort(
93
+ iftrue=(%mf_existds(&libds)=0)
94
+ ,mac=&sysmacroname
95
+ ,msg=%str(&libds could not be found)
96
+ )
97
+ %mp_abort(
98
+ iftrue=(%mf_existvar(&libds,FMTROW)=0)
99
+ ,mac=&sysmacroname
100
+ ,msg=%str(FMTROW not found in &libds)
101
+ )
92
102
  %let err=0;
93
103
  %let msg=0;
94
104
  data _null_;
@@ -109,13 +119,6 @@ data _null_;
109
119
  stop;
110
120
  end;
111
121
  end;
112
- else if name='LIBDS' then do;
113
- if exist(value) le 0 then do;
114
- call symputx('msg',"Unable to open staging table: "!!value);
115
- call symputx('err',1);
116
- stop;
117
- end;
118
- end;
119
122
  else if (name=:'OUTDS' or name in ('DELETE_COL','LOCKLIBDS','AUDITLIBDS'))
120
123
  and missing(value) then do;
121
124
  call symputx('msg',"missing value in var: "!!name);
@@ -123,6 +126,14 @@ data _null_;
123
126
  stop;
124
127
  end;
125
128
  run;
129
+ data _null_;
130
+ set &libds;
131
+ if missing(fmtrow) then do;
132
+ call symputx('msg',"missing fmtrow in format: "!!FMTNAME);
133
+ call symputx('err',1);
134
+ stop;
135
+ end;
136
+ run;
126
137
 
127
138
  %mp_abort(
128
139
  iftrue=(&err ne 0)
@@ -130,33 +141,69 @@ run;
130
141
  ,msg=%str(&msg)
131
142
  )
132
143
 
144
+ %local cnt;
145
+ proc sql noprint;
146
+ select count(distinct catx('|',type,fmtname,fmtrow)) into: cnt from &libds;
147
+ %mp_abort(
148
+ iftrue=(&cnt ne %mf_nobs(&libds))
149
+ ,mac=&sysmacroname
150
+ ,msg=%str(Non-unique primary key on &libds)
151
+ )
152
+
133
153
  /**
134
154
  * First, extract only relevant formats from the catalog
135
155
  */
136
156
  proc sql noprint;
137
- select distinct upcase(fmtname) into: fmtlist separated by ' ' from &libds;
157
+ select distinct
158
+ case
159
+ when type='N' then upcase(fmtname)
160
+ when type='C' then cats('$',upcase(fmtname))
161
+ when type='I' then cats('@',upcase(fmtname))
162
+ when type='J' then cats('@$',upcase(fmtname))
163
+ else "&sysmacroname:UNHANDLED"
164
+ end
165
+ into: fmtlist separated by ' '
166
+ from &libds;
138
167
 
139
168
  %mp_cntlout(libcat=&libcat,fmtlist=&fmtlist,cntlout=&base_fmts)
140
169
 
170
+ /* get a hash of the row */
171
+ %local cvars nvars;
172
+ %let cvars=TYPE FMTNAME START END LABEL PREFIX FILL SEXCL EEXCL HLO DECSEP
173
+ DIG3SEP DATATYPE LANGUAGE;
174
+ %let nvars=FMTROW MIN MAX DEFAULT LENGTH FUZZ MULT NOEDIT;
175
+ data &base_fmts/note2err;
176
+ set &base_fmts;
177
+ fmthash=%mp_md5(cvars=&cvars, nvars=&nvars);
178
+ run;
141
179
 
142
180
  /**
143
181
  * Ensure input table and base_formats have consistent lengths and types
144
182
  */
145
- %mddl_sas_cntlout(libds=&template)
146
- data &inlibds;
147
- length &delete_col $3;
148
- if 0 then set &template;
183
+ data &inlibds/nonote2err;
184
+ length &delete_col $3 FMTROW 8 start end label $32767;
185
+ if 0 then set &base_fmts;
149
186
  set &libds;
187
+ by type fmtname notsorted;
150
188
  if &delete_col='' then &delete_col='No';
151
189
  fmtname=upcase(fmtname);
190
+ type=upcase(type);
152
191
  if missing(type) then do;
153
- if substr(fmtname,1,1)='$' then type='C';
154
- else type='N';
192
+ if substr(fmtname,1,1)='@' then do;
193
+ if substr(fmtname,2,1)='$' then type='J';
194
+ else type='I';
195
+ end;
196
+ else do;
197
+ if substr(fmtname,1,1)='$' then type='C';
198
+ else type='N';
199
+ end;
155
200
  end;
156
- if type='N' then do;
157
- start=cats(start);
158
- end=cats(end);
201
+ if type in ('N','I') then do;
202
+ %mp_aligndecimal(start,width=16)
203
+ %mp_aligndecimal(end,width=16)
159
204
  end;
205
+
206
+ fmthash=%mp_md5(cvars=&cvars, nvars=&nvars);
160
207
  run;
161
208
 
162
209
  /**
@@ -167,11 +214,22 @@ create table &outds_add(drop=&delete_col) as
167
214
  select a.*
168
215
  from &inlibds a
169
216
  left join &base_fmts b
170
- on a.fmtname=b.fmtname
171
- and a.start=b.start
217
+ on a.type=b.type and a.fmtname=b.fmtname and a.fmtrow=b.fmtrow
172
218
  where b.fmtname is null
173
219
  and upcase(a.&delete_col) ne "YES"
174
- order by fmtname, start;;
220
+ order by type, fmtname, fmtrow;
221
+
222
+ /**
223
+ * Identify modified records
224
+ */
225
+ create table &outds_mod (drop=&delete_col) as
226
+ select a.*
227
+ from &inlibds a
228
+ inner join &base_fmts b
229
+ on a.type=b.type and a.fmtname=b.fmtname and a.fmtrow=b.fmtrow
230
+ where upcase(a.&delete_col) ne "YES"
231
+ and a.fmthash ne b.fmthash
232
+ order by type, fmtname, fmtrow;
175
233
 
176
234
  /**
177
235
  * Identify deleted records
@@ -180,24 +238,28 @@ create table &outds_del(drop=&delete_col) as
180
238
  select a.*
181
239
  from &inlibds a
182
240
  inner join &base_fmts b
183
- on a.fmtname=b.fmtname
184
- and a.start=b.start
241
+ on a.type=b.type and a.fmtname=b.fmtname and a.fmtrow=b.fmtrow
185
242
  where upcase(a.&delete_col)="YES"
186
- order by fmtname, start;
243
+ order by type, fmtname, fmtrow;
187
244
 
188
245
  /**
189
- * Identify modified records
246
+ * Identify fully deleted formats (where every record is removed)
247
+ * These require to be explicitly deleted in proc format
248
+ * del1 - identify _partial_ deletes
249
+ * del2 - exclude these, and also formats that come with _additions_
190
250
  */
191
- create table &outds_mod (drop=&delete_col) as
251
+ create table &del1 as
192
252
  select a.*
193
- from &inlibds a
194
- inner join &base_fmts b
195
- on a.fmtname=b.fmtname
196
- and a.start=b.start
197
- where upcase(a.&delete_col) ne "YES"
198
- order by fmtname, start;
253
+ from &base_fmts a
254
+ left join &outds_del b
255
+ on a.type=b.type and a.fmtname=b.fmtname and a.fmtrow=b.fmtrow
256
+ where b.fmtrow is null;
257
+
258
+ create table &del2 as
259
+ select * from &outds_del
260
+ where cats(type,fmtname) not in (select cats(type,fmtname) from &outds_add)
261
+ and cats(type,fmtname) not in (select cats(type,fmtname) from &del1);
199
262
 
200
- options ibufsize=&ibufsize;
201
263
 
202
264
  %mp_abort(
203
265
  iftrue=(&syscc ne 0)
@@ -206,19 +268,21 @@ options ibufsize=&ibufsize;
206
268
  )
207
269
 
208
270
  %if &loadtarget=YES %then %do;
271
+ /* new records plus base records that are not deleted or modified */
209
272
  data &ds1;
210
273
  merge &base_fmts(in=base)
211
274
  &outds_mod(in=mod)
212
275
  &outds_add(in=add)
213
276
  &outds_del(in=del);
214
277
  if not del and not mod;
215
- by fmtname start;
278
+ by type fmtname fmtrow;
216
279
  run;
280
+ /* add back the modified records */
217
281
  data &stagedata;
218
282
  set &ds1 &outds_mod;
219
283
  run;
220
284
  proc sort;
221
- by fmtname start;
285
+ by type fmtname fmtrow;
222
286
  run;
223
287
  %end;
224
288
  /* mp abort needs to run outside of conditional blocks */
@@ -228,7 +292,7 @@ options ibufsize=&ibufsize;
228
292
  ,msg=%str(SYSCC=&syscc prior to actual load)
229
293
  )
230
294
  %if &loadtarget=YES %then %do;
231
- %if %mf_nobs(&stagedata)=0 %then %do;
295
+ %if %mf_nobs(&stagedata)=0 and %mf_nobs(&del2)=0 %then %do;
232
296
  %put There are no changes to load in &libcat!;
233
297
  %return;
234
298
  %end;
@@ -244,6 +308,22 @@ options ibufsize=&ibufsize;
244
308
  /* do the actual load */
245
309
  proc format lib=&libcat cntlin=&stagedata;
246
310
  run;
311
+ /* apply any full deletes */
312
+ %if %mf_nobs(&del2)>0 %then %do;
313
+ %local delfmtlist;
314
+ proc sql noprint;
315
+ select distinct case when type='N' then cats(fmtname,'.FORMAT')
316
+ when type='C' then cats(fmtname,'.FORMATC')
317
+ when type='J' then cats(fmtname,'.INFMTC')
318
+ when type='I' then cats(fmtname,'.INFMT')
319
+ else cats(fmtname,'.BADENTRY!!!') end
320
+ into: delfmtlist
321
+ separated by ' '
322
+ from &del2;
323
+ proc catalog catalog=&libcat;
324
+ delete &delfmtlist;
325
+ quit;
326
+ %end;
247
327
  %if &locklibds ne 0 %then %do;
248
328
  /* unlock the table */
249
329
  %mp_lockanytable(UNLOCK
@@ -266,7 +346,7 @@ options ibufsize=&ibufsize;
266
346
 
267
347
  %mp_storediffs(&libcat-FC
268
348
  ,&base_fmts
269
- ,FMTNAME START
349
+ ,TYPE FMTNAME FMTROW
270
350
  ,delds=&outds_del
271
351
  ,modds=&outds_mod
272
352
  ,appds=&outds_add
@@ -167,7 +167,7 @@ run;
167
167
  data _null_;
168
168
  putlog 'NOTE-' / 'NOTE-';
169
169
  putlog "NOTE- &sysmacroname: table locked, waiting "@;
170
- putlog "%sysfunc(sleep(&loop_inc)) seconds.. ";
170
+ putlog "%sysfunc(sleep(&loop_secs)) seconds.. ";
171
171
  putlog "NOTE- (iteration &x of &loops)";
172
172
  putlog 'NOTE-' / 'NOTE-';
173
173
  run;
@@ -194,32 +194,39 @@ run;
194
194
  %end;
195
195
  %end;
196
196
  %else %if &ACTION=UNLOCK %then %do;
197
- %local status;
197
+ %local status cnt;
198
+ %let cnt=0;
198
199
  proc sql noprint;
199
- select LOCK_STATUS_CD into: status from &ctl_ds
200
- where LOCK_LIB ="&lib" and LOCK_DS="&ds";
201
- quit;
202
- %if &syscc>0 %then %put syscc=&syscc sqlrc=&sqlrc;
203
- %if &status=LOCKED %then %do;
204
- data _null_;
205
- putlog "&sysmacroname: unlocking &lib..&ds:";
206
- run;
207
- proc sql;
208
- update &ctl_ds
209
- set LOCK_STATUS_CD='UNLOCKED'
210
- , LOCK_END_DTTM="%sysfunc(datetime(),%mf_fmtdttm())"dt
211
- , LOCK_USER_NM="&user"
212
- , LOCK_PID="&sysjobid"
213
- , LOCK_REF="&ref"
214
- where LOCK_LIB ="&lib" and LOCK_DS="&ds";
215
- quit;
216
- %end;
217
- %else %if &status=UNLOCKED %then %do;
218
- %put %str(WAR)NING: &lib..&ds is already unlocked!;
200
+ select count(*) into: cnt from &ctl_ds where LOCK_LIB ="&lib" & LOCK_DS="&ds";
201
+ %if &cnt=0 %then %do;
202
+ %put %str(WAR)NING: &lib..&ds was not previously locked in &ctl_ds!;
219
203
  %end;
220
204
  %else %do;
221
- %put NOTE: Unrecognised STATUS_CD (&status) in &ctl_ds;
222
- %let abortme=1;
205
+ select LOCK_STATUS_CD into: status from &ctl_ds
206
+ where LOCK_LIB ="&lib" and LOCK_DS="&ds";
207
+ quit;
208
+ %if &syscc>0 %then %put syscc=&syscc sqlrc=&sqlrc;
209
+ %if &status=LOCKED %then %do;
210
+ data _null_;
211
+ putlog "&sysmacroname: unlocking &lib..&ds:";
212
+ run;
213
+ proc sql;
214
+ update &ctl_ds
215
+ set LOCK_STATUS_CD='UNLOCKED'
216
+ , LOCK_END_DTTM="%sysfunc(datetime(),%mf_fmtdttm())"dt
217
+ , LOCK_USER_NM="&user"
218
+ , LOCK_PID="&sysjobid"
219
+ , LOCK_REF="&ref"
220
+ where LOCK_LIB ="&lib" and LOCK_DS="&ds";
221
+ quit;
222
+ %end;
223
+ %else %if &status=UNLOCKED %then %do;
224
+ %put %str(WAR)NING: &lib..&ds is already unlocked!;
225
+ %end;
226
+ %else %do;
227
+ %put NOTE: Unrecognised STATUS_CD (&status) in &ctl_ds;
228
+ %let abortme=1;
229
+ %end;
223
230
  %end;
224
231
  %end;
225
232
  %else %do;
package/macros/mp_md5.sas CHANGED
@@ -2,8 +2,7 @@
2
2
  @file
3
3
  @brief Generates an md5 expression for hashing a set of variables
4
4
  @details This is the same algorithm used to hash records in
5
- [Data Controller for SAS](https://datacontroller.io) (free for up
6
- to 5 users).
5
+ [Data Controller for SAS](https://datacontroller.io).
7
6
 
8
7
  It is not designed to be efficient - it is designed to be effective,
9
8
  given the range of edge cases (large floating points, special missing
@@ -29,8 +28,8 @@
29
28
  @li Global option: `options dsoptions=nonote2err;`
30
29
  @li Data step option: `data YOURLIB.YOURDATASET /nonote2err;`
31
30
 
32
- @param cvars= Space seperated list of character variables
33
- @param nvars= Space seperated list of numeric variables
31
+ @param [in] cvars= () Space seperated list of character variables
32
+ @param [in] nvars= () Space seperated list of numeric variables
34
33
 
35
34
  <h4> Related Programs </h4>
36
35
  @li mp_init.sas
@@ -11,9 +11,9 @@
11
11
  %mp_perflog(finished)
12
12
 
13
13
 
14
- @param label Provide label to go into the control dataset
15
- @param libds= Provide a dataset in which to store performance stats. Default
16
- name is <code>work.mp_perflog</code>;
14
+ @param [in] label Provide label to go into the control dataset
15
+ @param [in] libds= (work.mp_perflog) Provide a dataset in which to store
16
+ performance stats. Default name is <code>work.mp_perflog</code>;
17
17
 
18
18
  @version 9.2
19
19
  @author Allan Bowe
@@ -34,12 +34,12 @@
34
34
  Credit is made to `data _null_` for authoring this very helpful paper:
35
35
  https://www.lexjansen.com/pharmasug/2008/cc/CC08.pdf
36
36
 
37
- @param action Either FETCH a current or previous record, or INITialise.
38
- @param record The relative (to current) position of the previous observation
37
+ @param [in] action Either FETCH a current or previous record, or INITialise.
38
+ @param [in] record The relative (to current) position of the previous row
39
39
  to return.
40
- @param history= The number of records to retain in the hash table. Default=5
41
- @param prefix= the prefix to give to the variables used to store the hash name
42
- and index. Default=mp_prevobs
40
+ @param [in] history= (5) The number of records to retain in the hash table.
41
+ @param [in] prefix= (mp_prevobs) The prefix to give to the variables used to
42
+ store the hash name and index.
43
43
 
44
44
  @version 9.2
45
45
  @author Allan Bowe
@@ -23,12 +23,13 @@
23
23
  ,childvar=c
24
24
  )
25
25
 
26
- @param base_ds= base table containing hierarchy (not modified)
27
- @param outds= the output dataset to create with the generated hierarchy
28
- @param matchval= the ultimate parent from which to filter
29
- @param parentvar= name of the parent variable
30
- @param childvar= name of the child variable (should be same type as parent)
31
- @param mdebug= set to 1 to prevent temp tables being dropped
26
+ @param [in] base_ds= base table containing hierarchy (not modified)
27
+ @param [out] outds= the output dataset to create with the generated hierarchy
28
+ @param [in] matchval= the ultimate parent from which to filter
29
+ @param [in] parentvar= name of the parent variable
30
+ @param [in] childvar= () name of the child variable (should be same type as
31
+ parent)
32
+ @param [in] mdebug= set to 1 to prevent temp tables being dropped
32
33
 
33
34
 
34
35
  @returns outds contains the following variables:
@@ -32,10 +32,11 @@
32
32
  Note - if you are running a version of SAS that will allow the io package in
33
33
  LUA, you can also use this macro: mp_gsubfile.sas
34
34
 
35
- @param infile The QUOTED path to the file on which to perform the substitution
36
- @param findvar= Macro variable NAME containing the string to search for
37
- @param replacevar= Macro variable NAME containing the replacement string
38
- @param outfile= (0) Optional QUOTED path to the adjusted output file (to
35
+ @param [in] infile The QUOTED path to the file on which to perform the
36
+ substitution
37
+ @param [in] findvar= Macro variable NAME containing the string to search for
38
+ @param [in] replacevar= Macro variable NAME containing the replacement string
39
+ @param [out] outfile= (0) Optional QUOTED path to the adjusted output file (to
39
40
  avoid overwriting the first file).
40
41
 
41
42
  <h4> SAS Macros </h4>
@@ -31,9 +31,9 @@
31
31
  %mp_runddl(/some/rootlib, exc=LIBREF3) * same as above ;
32
32
 
33
33
 
34
- @param path location of the DDL folder structure
35
- @param inc= list of librefs to include
36
- @param exc= list of librefs to exclude (takes precedence over inc=)
34
+ @param [in] path location of the DDL folder structure
35
+ @param [in] inc= list of librefs to include
36
+ @param [in] exc= list of librefs to exclude (takes precedence over inc=)
37
37
 
38
38
  @version 9.3
39
39
  @author Allan Bowe
@@ -9,12 +9,13 @@
9
9
 
10
10
  %mp_searchcols(libs=sashelp work, cols=name sex age)
11
11
 
12
- @param libs=(SASHELP) Space separated list of libraries to search for columns
13
- @param cols= Space separated list of column names to search for (not case
14
- sensitive)
15
- @param outds=(mp_searchcols) the table to create with the results. Will have
16
- one line per table match.
17
- @param match=(ANY) The match type. Valid values:
12
+ @param [in] libs= (SASHELP)
13
+ Space separated list of libraries to search for columns
14
+ @param [in] cols=
15
+ Space separated list of column names to search for (not case sensitive)
16
+ @param [out] outds= (mp_searchcols)
17
+ The table to create with the results. Will have one line per table match.
18
+ @param [in] match= (ANY) The match type. Valid values:
18
19
  @li ANY - The table contains at least one of the columns
19
20
  @li WILD - The table contains a column with a name that partially matches
20
21
 
@@ -197,6 +197,7 @@
197
197
  @li mp_coretable.sas
198
198
  @li mp_stackdiffs.test.sas
199
199
  @li mp_storediffs.sas
200
+ @li mp_stripdiffs.sas
200
201
 
201
202
  @todo The current approach assumes that a variable called KEY_HASH is not on
202
203
  the base table. This part will need to be refactored (eg using
@@ -6,8 +6,7 @@
6
6
  data recovery, and change re-application. This macro is one of many
7
7
  data management utilities used in [Data Controller for SAS](
8
8
  https:datacontroller.io) - a comprehensive data ingestion solution, which
9
- works on any SAS platform (Viya, SAS 9, Foundation) and is free for up to 5
10
- users.
9
+ works on any SAS platform (Viya, SAS 9, Foundation).
11
10
 
12
11
  NOTE - this macro does not validate the inputs. It is assumed that the
13
12
  datasets containing the new / changed / deleted rows are CORRECT, contain
@@ -65,6 +64,7 @@
65
64
  <h4> Related Macros </h4>
66
65
  @li mp_stackdiffs.sas
67
66
  @li mp_storediffs.test.sas
67
+ @li mp_stripdiffs.sas
68
68
 
69
69
  @version 9.2
70
70
  @author Allan Bowe
@@ -147,9 +147,9 @@ run;
147
147
 
148
148
  %if %index(&libds,-)>0 and %scan(&libds,2,-)=FC %then %do;
149
149
  /* this is a format catalog - cannot query cols directly */
150
- %let vlist="FMTNAME","START","END","LABEL","MIN","MAX","DEFAULT","LENGTH"
151
- ,"FUZZ","PREFIX","MULT","FILL","NOEDIT","TYPE","SEXCL","EEXCL","HLO"
152
- ,"DECSEP","DIG3SEP","DATATYPE","LANGUAGE";
150
+ %let vlist="TYPE","FMTNAME","FMTROW","START","END","LABEL","MIN","MAX"
151
+ ,"DEFAULT","LENGTH","FUZZ","PREFIX","MULT","FILL","NOEDIT","SEXCL"
152
+ ,"EEXCL","HLO","DECSEP","DIG3SEP","DATATYPE","LANGUAGE";
153
153
  %end;
154
154
  %else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE);
155
155
 
@@ -165,7 +165,7 @@ data &ds4;
165
165
  if upcase(&inds_auto)="&ds2" then tgtvar_type='N';
166
166
  else if upcase(&inds_auto)="&ds3" then tgtvar_type='C';
167
167
  else do;
168
- putlog "%str(ERR)OR: unidentified vartype input!" &inds_auto;
168
+ putlog 'ERR' +(-1) "OR: unidentified vartype input!" &inds_auto;
169
169
  call symputx('syscc',98);
170
170
  end;
171
171
 
@@ -174,7 +174,7 @@ data &ds4;
174
174
  else if &inds_keep="&modds" then move_type='M';
175
175
  else if &inds_keep="&origds" then move_type='O';
176
176
  else do;
177
- putlog "%str(ERR)OR: unidentified movetype input!" &inds_keep;
177
+ putlog 'ERR' +(-1) "OR: unidentified movetype input!" &inds_keep;
178
178
  call symputx('syscc',99);
179
179
  end;
180
180
  tgtvar_nm=upcase(tgtvar_nm);
@@ -184,7 +184,7 @@ data &ds4;
184
184
  run;
185
185
 
186
186
  %if "&loadref"="0" %then %let loadref=%sysfunc(uuidgen());
187
- %if &processed_dttm=0 %then %let processed_dttm=%sysfunc(datetime());
187
+ %if &processed_dttm=0 %then %let processed_dttm=%sysfunc(datetime(),8.6);
188
188
  %let libds=%upcase(&libds);
189
189
 
190
190
  /* join orig vals for modified & deleted */
@@ -21,9 +21,10 @@
21
21
  %mp_stprequests(status_cd=INIT, libds=YOURLIB.DATASET )
22
22
 
23
23
 
24
- @param status_cd= Use INIT for INIT and TERM for TERM events
25
- @param libds= Location of base table (library.dataset). To minimise risk
26
- of table locks, we HIGHLY recommend using a database (NOT a SAS dataset).
24
+ @param [in] status_cd= Use INIT for INIT and TERM for TERM events
25
+ @param [in] libds= (somelib.stp_requests) Location of base table
26
+ (library.dataset). To minimise risk of table locks, we HIGHLY recommend
27
+ using a database (NOT a SAS dataset).
27
28
  THE LIBRARY SHOULD BE ASSIGNED ALREADY - eg in autoexec or earlier in the
28
29
  init program proper.
29
30