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