Loading...
Searching...
No Matches
getdata.sas
Go to the documentation of this file.
1/**
2 @file getdata.sas
3 @brief Returns a dataset to the editor front end
4 @details
5
6 <h4> Service Inputs </h4>
7
8 <h5> SASCONTROLTABLE </h5>
9 |LIBDS:$41.|FILTER_RK:$5.|
10 |---|---|
11 |DC258467.MPE_X_TEST|-1|
12
13 <h4> Service Outputs </h4>
14 <h5> sasdata </h5>
15 <h5> sasparams </h5>
16 Contains info on the request. One row is returned.
17 @li CLS_FLG - set to 0 if there are no CLS rules (everything editable)
18 else set to 1 (CLS rules exist)
19 @li ISMAP - set to 1 if the target DS is an excel map target, else 0
20
21 <h5> approvers </h5>
22 <h5> dqrules </h5>
23 <h5> dqdata </h5>
24 <h5> cols </h5>
25 Contains column level attributes.
26 @li NAME - column name
27 @li VARNUM - var position. https://core.sasjs.io/mp__getcols_8sas.html
28 @li LABEL - var label. https://core.sasjs.io/mp__getcols_8sas.html
29 @li FMTNAME - derived format. https://core.sasjs.io/mp__getcols_8sas.html
30 @li DDTYPE - derived dropdown. https://core.sasjs.io/mp__getcols_8sas.html
31 @li CLS_RULE - values include:
32 - EDIT - the column is editable
33 - READ - the column should be readonly
34 - HIDE - the column should be hidden
35 @li memlabel
36 @li desc- augmented with MPE_DATADICTIONARY if exists, else label
37 @li longdesc - from MPE_DATADICTIONARY
38
39
40 <h5> maxvarlengths </h5>
41 <h5> xl_rules </h5>
42 <h5> query </h5>
43
44 <h5> versions </h5>
45 history of DC versions for this particular table
46
47
48 <h4> SAS Macros </h4>
49 @li dc_assignlib.sas
50 @li dc_casload.sas
51 @li dc_getgroupmembers.sas
52 @li mf_existvar.sas
53 @li mf_getattrn.sas
54 @li mf_getvarlist.sas
55 @li mf_existds.sas
56 @li mf_getquotedstr.sas
57 @li mf_getuser.sas
58 @li mf_nobs.sas
59 @li mf_verifymacvars.sas
60 @li mf_wordsinstr1butnotstr2.sas
61 @li mp_abort.sas
62 @li mp_cntlout.sas
63 @li mp_getcols.sas
64 @li mp_getmaxvarlengths.sas
65 @li mp_validatecol.sas
66 @li mpe_accesscheck.sas
67 @li mpe_columnlevelsecurity.sas
68 @li mpe_dsmeta.sas
69 @li mpe_getlabels.sas
70 @li mpe_getversions.sas
71 @li mpe_filtermaster.sas
72 @li mpe_runhook.sas
73
74 @version 9.2
75 @author 4GL Apps Ltd
76 @copyright 4GL Apps Ltd. This code may only be used within Data Controller
77 and may not be re-distributed or re-sold without the express permission of
78 4GL Apps Ltd.
79
80**/
81
82%mpeinit()
83
84/**
85 * Validate inputs
86 */
87data work.intest;
88 length filter_rk 8;
89 set work.SASCONTROLTABLE;
90
91 /* validate filter_rk */
92 if filter_rk le 0 then filter_rk=-1;
93
94 call symputx('orig_libds',upcase(libds));
95
96 is_fmt=0;
97 if substr(cats(reverse(libds)),1,3)=:'CF-' then do;
98 libds=scan(libds,1,'-');
99 putlog "Format Catalog Captured";
100 is_fmt=1;
101 libds='work.fmtextract';
102 call symputx('libds',libds);
103 end;
104 call symputx('is_fmt',is_fmt);
105 putlog (_all_)(=);
106
107 /* validate libds */
108 %mp_validatecol(LIBDS,LIBDS,is_libds)
109
110 if is_libds=0 then do;
111 putlog 'ERR' 'OR: Invalid libds:' libds;
112 stop;
113 end;
114 else do;
115 call symputx('filter_rk',filter_rk);
116 call symputx('libds',libds);
117 end;
118 output;
119 stop;
120run;
121
122%mp_abort(iftrue= (%mf_nobs(work.intest)=0)
123 ,mac=&_program
124 ,msg=%str(Some err with service inputs)
125)
126
127%mp_abort(
128 iftrue=(%mf_verifymacvars(libds filter_rk)=0)
129 ,mac=&_program
130 ,msg=%str(Missing: libds filter_rk)
131)
132
133/* export format catalog */
134%mp_cntlout(
135 iftrue=(&is_fmt=1)
136 ,libcat=&orig_libds
137 ,fmtlist=0
138 ,cntlout=work.fmtextract
139)
140
141/* stream back meta info, further calls will return col metadata and actual data
142*/
143%let libref=%upcase(%scan(&libds,1,.));
144%let dsn=%upcase(%scan(&libds,2,.));
145%dc_assignlib(WRITE,&libref)
146%dc_casload(&libds)
147
148/**
149 * First check user has access permission to edit the table
150 */
151%put checking access;
152%let user=%mf_getuser();
153%mpe_accesscheck(&orig_libds,outds=mw_auth,user=&user,access_level=EDIT)
154
155
156%mp_abort(iftrue= (%mf_getattrn(work.mw_auth,NLOBS)=0)
157 ,mac=mpestp_getdata.sas
158 ,msg=&user is not authorised to edit &orig_libds %trim(
159 )in the &mpelib..MPE_SECURITY table
160)
161
162%mp_abort(iftrue= ( %mf_existds(libds=&libds) ne 1)
163 ,mac=mpestp_getdata.sas
164 ,msg=dataset &libds does not exist!!
165)
166
167%mp_abort(iftrue= (&syscc ne 0)
168 ,mac=&_program..sas
169 ,msg=%str(syscc=&syscc at line 60 )
170)
171
172
173%global loadtype var_txfrom var_txto var_processed filter_text pk coltype
174 sortpk;
175
176%put getting table attributes;
177proc sql noprint;
178select upcase(loadtype)
179 ,var_txfrom,var_txto
180 ,var_busfrom,var_busto
181 ,var_processed,rk_underlying,buskey
182 ,coalesce(rk_underlying,buskey)
183 ,pre_edit_hook
184 ,case when missing(rk_underlying) then buskey else rk_underlying end
185 into: loadtype,:var_txfrom,:var_txto
186 ,:var_busfrom ,:var_busto
187 ,:var_processed,:rk_underlying,:buskey, :sortPK, :pre_edit_hook,:pk
188 from &mpelib..mpe_tables
189 where &dc_dttmtfmt. lt TX_TO
190 and upcase(dsn)="%scan(&orig_libds,2,.)"
191 and upcase(libref)="%scan(&orig_libds,1,.)";
192
193%put preparing filter query:;
194%mpe_filtermaster(EDIT,&orig_libds,
195 dclib=&mpelib,
196 filter_rk=&filter_rk,
197 outref=filtref,
198 outds=work.query
199)
200
201%macro mpestp_getdata();
202 %if not %symexist(DC_MAXOBS_WEBEDIT) %then %do;
203 %put NOTE:;%put NOTE- DC_MAXOBS_WEBEDIT not found!;
204 %put NOTE- Please add to &mpelib..MPE_CONFIG table;
205 %put NOTE-;%put NOTE-;
206 %global DC_MAXOBS_WEBEDIT;
207 %let DC_MAXOBS_WEBEDIT=500;
208 %end;
209 /* for tables which use RKs/SKs then we just expose the business key to
210 users - this lets uploads be sent to multiple environments (with
211 potentially different RK/SK values for the same business key).
212 Note that the config table has the RK column in the buskey field in
213 this scenario. */
214 %if %length(&rk_underlying)>0 %then %let drop_rk=&buskey;
215 %else %let drop_rk=;
216
217 /* always remove the PROCESSED_DTTM column, if it exists */
218 %if %length(&var_processed)=0 %then %do;
219 %if %mf_existvar(&libds,PROCESSED_DTTM)>0 %then
220 %let var_processed=PROCESSED_DTTM;
221 %end;
222
223 /**
224 * Now get the slice of the actual table
225 */
226 options obs=10000;
227
228 %if &loadtype=BITEMPORAL %then %do;
229 data out (drop=&var_txfrom &var_txto &var_processed &drop_rk );
230 _____DELETE__THIS__RECORD_____="No";
231 set &libds;
232 where %inc filtref;;
233 run;
234 proc sort data=out;
235 by &pk &var_busfrom;
236 run;
237 data out;
238 set out;
239 by &pk &var_busfrom;
240 if last.%scan(&pk,-1);
241 run;
242 %end;
243 %else %do;
244 data out (drop=&var_txfrom &var_txto &var_processed &drop_rk);
245 _____DELETE__THIS__RECORD_____="No";
246 set &libds;
247 where %inc filtref;;
248 run;
249 %end;
250 options obs=max;
251 %mp_abort(iftrue= (&syscc ne 0)
252 ,mac=&_program
253 ,msg=%str(Issue with filtering (line 165) )
254 )
255
256 options obs=&DC_MAXOBS_WEBEDIT;
257 %let sortpk=%sysfunc(coalescec(&sortpk &var_busfrom,_ALL_));
258 proc sort data=work.out; by &sortPK; run;
259 options obs=max;
260
261 %mpe_runhook(PRE_EDIT_HOOK)
262
263 %let obscnt=%mf_getattrn(work.out,NLOBS);
264 %mp_abort(iftrue=(&obscnt>&DC_MAXOBS_WEBEDIT)
265 ,mac=&_program
266 ,msg=Table is too big (&obscnt rows) - please filter and try again!
267 )
268
269
270 /* order delete var and pk fields at start of table */
271 %let sourcevars=%mf_wordsInStr1ButNotStr2(
272 Str1=%mf_getvarlist(work.out)
273 ,Str2= _____DELETE__THIS__RECORD_____ &pk
274 );
275 %put sourcevars=&sourcevars;
276 data outdata;
277 /* delete & pk fields come first */
278 attrib _____DELETE__THIS__RECORD_____ &pk label='';
279 /* keep remaining variable order */
280 %if %length(&sourcevars)>0 %then %do;
281 attrib &sourcevars label='';
282 %end;
283 _____DELETE__THIS__RECORD_____="No ";
284 %if %mf_nobs(work.out)=0 %then %do;
285 /* send empty row if empty table to help with hot rendering */
286 output;
287 %end;
288 set work.out ;
289 run;
290
291
292
293 /* get list of variables and their formats */
294 proc contents noprint data=outdata
295 out=vars(keep=name type length varnum format: label);
296 run;
297
298 proc sort;
299 by varnum;
300 run;
301
302 data vars3(keep=name type length format label pk varnum ctrloptions formatd);
303 set vars(rename=(format=format2 type=type2));
304 name=upcase(name);
305 /* not interested in transaction or processing dates
306 (append table must be supplied without them) */
307 if name not in ("&VAR_TXFROM","&VAR_TXTO","&VAR_PROCESSED");
308 if type2=2 or type2=6 then do;
309 length format $49.;
310 if format2='' then format=cats('$',length,'.');
311 else format=cats(format2,formatl,'.');
312 type='char';
313 end;
314 else do;
315 if format2='' then format=cats(length,'.');
316 else if upcase(format2)='DATETIME' and formatl=0 then format='DATETIME.';
317 else format=cats(format2,formatl,'.',formatd);
318 type='num';
319 end;
320
321 if name in ('',%upcase(%mf_getQuotedStr(&pk,dlm=%str(,),quote=S)))
322 then PK='YES';
323
324 length ctrlOptions $500;
325 if name="_____DELETE__THIS__RECORD_____" then ctrlOptions='["No","Yes"]';
326 else ctrlOptions='';
327 run;
328 %mp_abort(iftrue= (&syscc ne 0)
329 ,mac=&_program..sas
330 ,msg=%str(syscc=&syscc at 242 (vars3 step) in &_program \n
331 %superq(syserrortext)
332 )
333 )
334
335 %global jsdttmvars jsdtvars jstmvars;
336 data _null_;
337 set vars3 end=last;
338 if _n_>1 then comma=',';
339 length coltype $500.;
340 format=upcase(format);
341 coltype=cats(comma,'{"data":"',name,'"');
342 if ctrlOptions ne '' then
343 colType=cats(coltype,',"type":"dropdown","source":',ctrlOptions,"}");
344 else if type='num' then do;
345 if format=:'DATETIME' or format=:'E8601DT' or format=:'NLDATM'
346 then do;
347 colType=cats(coltype,',"type":"datetime"}');
348 /* build var list to reformat datetimes in javascript format */
349 call symput('jsdttmvars',symget('jsdttmvars')!!' '!!name);
350 end;
351 else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY'
352 or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA'
353 or format=:'MONYY' or format=:'NLDATE'
354 then do;
355 /* see bottom of file for more date formats!! */
356 /* also when updating, update stagedata.sas and mp_getcols.sas
357 and mpe_loader.sas */
358 colType=cats(coltype,',"type":"date"}');
359 /* build var list to reformat as javascript dates */
360 call symput('jsdtvars',symget('jsdtvars')!!' '!!name);
361 end;
362 else if format=:'TIME' or format=:'HHMM' then do;
363 colType=cats(coltype,',"type":"time"}');
364 /* build var list to reformat as javascript times */
365 call symput('jstmvars',symget('jstmvars')!!' '!!name);
366 end;
367 else do;
368 /* is standard numeric but need to ascertain precision */
369 retain base '000000000000000000';
370 if formatd>0 then numFormat=cats('.',substr(base,1,formatd));
371 colType=cats(coltype,',"type":"numeric","format":"0',numFormat,'"}');
372 end;
373 end;
374 else colType=cats(coltype,'}');
375 length concatcoltype $32767;
376 retain concatcoltype;
377 concatcoltype=cats(concatcoltype,coltype);
378 if last then call symputx('colType',strip(concatcoltype),'g');
379 putlog (_all_)(=);
380 run;
381
382 %mp_abort(iftrue= (&syscc ne 0)
383 ,mac=&_program..sas
384 ,msg=%str(syscc=&syscc at 283 (null step) in &_program)
385 )
386
387 PROC FORMAT;
388 picture yymmddThhmmss (default=28) other='%0Y-%0m-%0d %0H:%0M:%0s'
389 (datatype=datetime);
390 picture JSyymmdd other='%0Y-%0m-%0d' (datatype=date);
391 picture JShhmmss (default=16) other='%0H:%0M:%0s' (datatype=time);
392 RUN;
393 /* before we send the data, need to rebuild all date & datetime vars as char*/
394 %let finalvars=%mf_getvarlist(work.outdata);
395 data sasdata;
396 /* set formats & col order ahead of rename+import */
397 informat &finalvars ;
398 /* read dataset and rename date / datetime vars as necessary */
399 set outdata
400 %if %length(&jsdttmvars&jsdtvars&jstmvars)>0 %then %do;
401 (rename=(
402 %local dtvarnum dtvar tmvar;
403 /* temp datetime vars end in _____ */
404 %do dtvarnum=1 %to %sysfunc(countw(&jsdttmvars,%str( )));
405 %let dtvar=%scan(&jsdttmvars ,&dtvarnum);
406 &dtvar=_____&dtvarnum._____
407 %end;
408 /* temp date vars do not end in _____ */
409 %do dtvarnum=1 %to %sysfunc(countw(&jsdtvars,%str( )));
410 %let dtvar=%scan( &jsdtvars,&dtvarnum);
411 &dtvar=_____&dtvarnum
412 %end;
413 /* temp time vars end in ___tm */
414 %do tmvarnum=1 %to %sysfunc(countw(&jstmvars,%str( )));
415 %let tmvar=%scan( &jstmvars,&tmvarnum);
416 &tmvar=_____&tmvarnum.___tm
417 %end;
418 ))
419 %end;
420 ;
421 %if %length(&jsdttmvars)>0 %then %do ;
422 %do dtvarnum=1 %to %sysfunc(countw(&jsdttmvars,%str( )));
423 %let dtvar=%scan(&jsdttmvars,&dtvarnum);
424 &dtvar=cats(put(_____&dtvarnum._____,yymmddThhmmss28.));
425 if &dtvar="ERROR" then call missing(&dtvar);
426 drop _____&dtvarnum._____;
427 %end;
428 %end;
429 %if %length(&jsdtvars)>0 %then %do;
430 %do dtvarnum=1 %to %sysfunc(countw(&jsdtvars,%str( )));
431 %let dtvar=%scan(&jsdtvars,&dtvarnum);
432 &dtvar=cats(put(_____&dtvarnum,JSyymmdd.));
433 if &dtvar="ERROR" then call missing(&dtvar);
434 drop _____&dtvarnum;
435 %end;
436 %end;
437 %if %length(&jstmvars)>0 %then %do;
438 %do tmvarnum=1 %to %sysfunc(countw(&jstmvars,%str( )));
439 %let tmvar=%scan(&jstmvars,&tmvarnum);
440 &tmvar=cats(put(_____&tmvarnum.___tm,JShhmmss14.));
441 if &tmvar="ERROR" then call missing(&tmvar);
442 drop _____&tmvarnum.___tm;
443 %end;
444 %end;
445 output;
446 run;
447
448 /* get the relevant approvers for the drop down */
449 %put getting approvers;
450 %local sas_groups sas_i sas_group;
451 proc sql noprint;
452 select distinct sas_Group into: sas_groups separated by "|"
453 from &mpelib..mpe_security
454 where libref="%scan(&orig_libds,1,.)"
455 and dsn="%scan(&orig_libds,2,.)"
456 and access_level='APPROVE'
457 and &dc_dttmtfmt. lt TX_TO;
458
459 %if %length(&sas_groups)=0 %then %do;
460 %dc_getgroupmembers(&dc_admin_group,outds=work.access1)
461 %end;
462 %else %do sas_i=1 %to %sysfunc(countw(&sas_groups,%str(|)));
463 %let sas_group=%scan(&sas_Groups,&sas_i,%str(|));
464 %dc_getgroupmembers(&sas_group,outds=work.temp&sas_i)
465 proc append base=work.access1 data=work.temp&sas_i;run;
466 %end;
467
468%mend mpestp_getdata;
469
470%mpestp_getdata()
471
472%mp_abort(mode=INCLUDE)
473
474/* extract column level security rules */
475%mpe_columnlevelsecurity(%scan(&libds,1,.),%scan(&libds,2,.),work.sasdata
476 ,mode=EDIT
477 ,clsds=&mpelib..mpe_column_level_security
478 ,groupds=work.groups /* was created in mpe_filtermaster */
479 ,outds=work.sasdata1
480 ,outmeta=work.cls_rules
481)
482
483/* get labels */
484%mpe_getlabels(COLUMNS,sasdata1,outds=spec)
485%mp_abort(iftrue= (&syscc ne 0)
486 ,mac=&_program
487 ,msg=%str(syscc=&syscc extracting spec info)
488)
489
490/* extract col info */
491%mp_getcols(&libds, outds=cols1)
492
493/* join with cls rules */
494proc sql;
495create table work.cols as
496 select a.NAME
497 ,a.VARNUM
498 ,a.LABEL
499 ,a.FMTNAME
500 ,a.DDTYPE
501 ,case b.cls_hide
502 when 1 then 'HIDE'
503 when 0 then 'EDIT'
504 else 'READ' end as CLS_RULE
505 ,c.memlabel
506 ,c.desc
507 ,c.longdesc
508 from work.cols1 a
509 left join work.cls_rules b
510 on a.NAME=b.CLS_VARIABLE_NM
511 left join work.spec c
512 on a.NAME=c.NAME;
513
514proc sql;
515create table approvers as select distinct membername as personname
516 ,membername as email, membername as userid
517 from work.access1;
518/*
519create table access3 as select b.userid,b.email
520 from access2 a
521 ,support.users b
522 where a.personname=b.userid
523 and a.personname ne "%mf_getuser()"
524 and %sysfunc(datetime()) lt b.tx_to_dttm
525 order by 1;
526*/
527data _null_;
528 infile filtref end=eof;
529 input;
530 length filter_text $32767;
531 retain filter_text;
532 filter_text=catx(' ',filter_text,_infile_);
533 if eof then do;
534 if cats(filter_text)='1=1' then filter_text='';
535 call symputx('filter_text',filter_text);
536 end;
537run;
538
539%put params;
540%let ismap=0;
541proc sql noprint;
542select count(*) into: ismap from &mpelib..mpe_xlmap_info
543 where XLMAP_TARGETLIBDS="&orig_libds" and &dc_dttmtfmt. le TX_TO;
544
545data sasparams;
546 length colHeaders $20000 filter_text $32767;
547 colHeaders=cats(upcase("%mf_getvarlist(sasdata1,dlm=%str(,))"));
548 pkCnt=countw("&pk");
549 pk="&pk";
550 dtvars=compbl("&jsdtvars");
551 dttmvars=compbl("&jsdttmvars");
552 tmvars=compbl("&jstmvars");
553 length coltype $32000;
554 coltype=symget('coltype');
555 loadtype=symget('loadtype');
556 if trim(symget('rk_underlying')) ne '' then rk_flag=1;
557 else rk_flag=0;
558 filter_text=symget('filter_text');
559 if %mf_nobs(work.cls_rules)=0 then cls_flag=0;
560 else cls_flag=1;
561 put (_all_)(=);
562 if "&orig_libds"="&mpelib..MPE_XLMAP_DATA" or &ismap ne 0 then ismap=1;
563 else ismap=0;
564run;
565
566
567/* Extract validation DQ Rules */
568proc sort data=&mpelib..mpe_validations
569 (where=(&dc_dttmtfmt. le TX_TO
570 and BASE_LIB="%scan(&orig_libds,1,.)" and BASE_DS="%scan(&orig_libds,2,.)"
571 and rule_active=1))
572 out=dqrules (keep=base_col rule_type rule_value);
573 by base_col rule_type rule_value;
574run;
575
576/* merge with NOTNULL constraints in the physical table */
577proc sql;
578create table _data_ as
579 select * from dqrules
580union
581 select upcase(name) as base_col
582 ,'NOTNULL' as rule_type
583 ,'' as rule_value
584 from dictionary.columns
585 where upcase(libname)="%scan(&orig_libds,1,.)"
586 and upcase(memname)="%scan(&orig_libds,2,.)"
587 and upcase(name) in (select name from vars3)
588 and notnull='yes'
589 order by 1,2,3;
590data dqrules;
591 set &syslast;
592 by base_col rule_type rule_value;
593 if last.rule_type;
594 if rule_type in ('HARDSELECT','SOFTSELECT') and countw(rule_value)=3 then
595 do;
596 retain x 0; x+1;
597 call symputx(cats('source',x),rule_value);
598 %let sourcecnt=0;
599 call symputx('sourcecnt',x);
600 call symputx(cats('base_col',x),base_col);
601 end;
602run;
603
604proc sql;
605create table dqdata as
606 select distinct base_column as base_col length=32
607 ,upcase(base_column) as rule_value length=74 /* deprecated */
608 ,selectbox_value as rule_data length=1000
609 ,selectbox_order
610 from &mpelib..mpe_selectbox
611 where &dc_dttmtfmt. lt ver_to_dttm
612 and select_lib="%scan(&orig_libds,1,.)"
613 and select_ds="%scan(&orig_libds,2,.)";
614
615%mp_abort(iftrue= (&syscc ne 0)
616 ,mac=&_program
617 ,msg=%str(syscc=&syscc during DQ rule validation)
618)
619
620/* extract selectbox data */
621%macro dq_selects();
622 %local x source lib ds col;
623 %do x=1 %to &sourcecnt;
624 %let source=&&source&x;
625 %let lib=%scan(&source,1,.);
626 %let ds=%scan(&source,2,.);
627 %let col=%scan(&source,3,.);
628 %put &=source;
629 %put &=lib;
630 %dc_assignlib(READ,&lib)
631 proc sql;
632 create table dqdata&x as
633 select distinct "&&base_col&x" as base_col length=32
634 ,"&source" as rule_value length=74
635 ,cats(&col) as rule_data length=1000
636 ,&col as tmp_order
637 from &lib..&ds
638 order by tmp_order;
639 /* ensure both numerics and char vals are ordered correctly */
640 data work.dqdata&x (drop=tmp_order);
641 set work.dqdata&x;
642 selectbox_order=_n_;
643 run;
644 %mp_abort(iftrue= (&syscc ne 0)
645 ,mac=&_program
646 ,msg=%str(syscc=&syscc when selecting &&base_col&x from &orig_libds)
647 )
648 proc append base=dqdata data=dqdata&x;run;
649 proc sql; drop table dqdata&x;
650 %end;
651%mend dq_selects;
652%dq_selects()
653
654proc sort data=dqdata;
655 /* order by selectbox_order then the value */
656 by base_col selectbox_order rule_data;
657run;
658
659%mp_getmaxvarlengths(work.sasdata1,outds=maxvarlengths)
660
661data maxvarlengths;
662 set maxvarlengths;
663 if name='_____DELETE__THIS__RECORD_____' then mAXLEN=3;
664run;
665
666data xl_rules;
667 set &mpelib..mpe_excel_config;
668 where &dc_dttmtfmt. lt tx_to;
669 where also upcase(xl_libref)="%scan(&orig_libds,1,.)";
670 where also upcase(xl_table)="%scan(&orig_libds,2,.)";
671 where also xl_active=1;
672 keep xl_column xl_rule;
673run;
674
675%mpe_dsmeta(&orig_libds, outds=dsmeta)
676
677%mpe_getversions(&mpelib,
678 %scan(&orig_libds,1,.),
679 %scan(&orig_libds,2,.),
680 outds=versions
681)
682
683
684/* send to the client */
685%webout(OPEN)
686%webout(OBJ,approvers)
687%webout(OBJ,cols)
688%webout(OBJ,dqdata,missing=STRING)
689%webout(OBJ,dqrules)
690%webout(OBJ,dsmeta)
691%webout(OBJ,maxvarlengths)
692%webout(OBJ,query)
693%webout(OBJ,sasdata1,fmt=N,missing=STRING,showmeta=YES,dslabel=sasdata)
694%webout(OBJ,sasparams)
695%webout(OBJ,versions)
696%webout(OBJ,xl_rules)
697%webout(CLOSE)
698
699/*
700$N8601Bw
701$N8601BAw
702$N8601Ew
703$N8601EAw
704$N8601EHw
705$N8601EXw
706$N8601Hw
707$N8601Xw
708B8601DAw
709B8601DNw
710B8601DTw
711B8601DZw
712B8601LZw
713B8601TMw
714B8601TZw
715DATEw
716DATEAMPMw
717DATETIMEw
718DAYw
719DDMMYYw
720DDMMYYxw
721DOWNAMEw
722DTDATEw
723DTMONYYw
724DTWKDATXw
725DTYEARw
726DTYYQCw
727E8601DAw
728E8601DNw
729E8601DTw
730E8601DZw
731E8601LZw
732E8601TMw
733E8601TZw
734HHMMw
735HOURw
736JULDAYw
737JULIANw
738MMDDYYw
739MMDDYYxw
740MMSSw
741MMYYw
742MMYYxw
743MONNAMEw
744MONTHw
745MONYYw
746PDJULGw
747PDJULIw
748QTRw
749QTRRw
750TIMEw
751TIMEAMPMw
752TODw
753WEEKDATEw
754WEEKDATXw
755WEEKDAYw
756WEEKUw
757WEEKVw
758WEEKWw
759WORDDATEw
760WORDDATXw
761YEARw
762YYMMw
763YYMMxw
764YYMMDDw
765YYMMDDxw
766YYMONw
767YYQw
768YYQxw
769YYQRw
770YYQRxw
771$N8601BAw
772$N8601Ew
773$N8601EAw
774$N8601EHw
775$N8601EXw
776$N8601Hw
777$N8601Xw
778B8601DAw
779B8601DNw
780B8601DTw
781B8601DZw
782B8601LZw
783B8601TMw
784B8601TZw
785E8601DAw
786E8601DNw
787E8601DTw
788E8601DZw
789E8601LZw
790E8601TMw
791E8601TZw
792*/
793%mpeterm()