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 LABEL - var label. https://core.sasjs.io/mp__getcols_8sas.html
28 @li FMTNAME - derived format. https://core.sasjs.io/mp__getcols_8sas.html
29 @li DDTYPE - derived dropdown. C=CHARACTER, N=NUMERIC, else DATE / TIME /
30 DATETIME. 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. Trim COLS payload in the SQL below - DDTYPE
492 C=CHARACTER N=NUMERIC (dates kept in full), VARNUM dropped (client
493 relies on column order, not position) */
494proc sql;
495create table work.cols as
496 select a.NAME
497 ,coalesce(c.desc,a.NAME) as LABEL
498 ,a.FMTNAME
499 ,case a.DDTYPE
500 when 'CHARACTER' then 'C'
501 when 'NUMERIC' then 'N'
502 else a.DDTYPE end as DDTYPE
503 ,case b.cls_hide
504 when 1 then 'HIDE'
505 when 0 then 'EDIT'
506 else 'READ' end as CLS_RULE
507 ,c.memlabel
508 ,c.longdesc
509 ,d.colType
510 from work.cols1(drop=varnum) a
511 left join work.cls_rules b
512 on a.NAME=b.CLS_VARIABLE_NM
513 left join work.spec c
514 on a.NAME=c.NAME
515 left join work.vars4 d
516 on a.NAME=d.NAME;
517
518proc sql;
519create table approvers as select distinct membername as personname
520 ,membername as email, membername as userid
521 from work.access1;
522/*
523create table access3 as select b.userid,b.email
524 from access2 a
525 ,support.users b
526 where a.personname=b.userid
527 and a.personname ne "%mf_getuser()"
528 and %sysfunc(datetime()) lt b.tx_to_dttm
529 order by 1;
530*/
531data _null_;
532 infile filtref end=eof;
533 input;
534 length filter_text $32767;
535 retain filter_text;
536 filter_text=catx(' ',filter_text,_infile_);
537 if eof then do;
538 if cats(filter_text)='1=1' then filter_text='';
539 call symputx('filter_text',filter_text);
540 end;
541run;
542
543%put params;
544%let ismap=0;
545proc sql noprint;
546select count(*) into: ismap from &mpelib..mpe_xlmap_info
547 where XLMAP_TARGETLIBDS="&orig_libds" and &dc_dttmtfmt. le TX_TO;
548
549data sasparams;
550 length colHeaders $20000 filter_text $32767;
551 colHeaders=cats(upcase("%mf_getvarlist(sasdata1,dlm=%str(,))"));
552 pkCnt=countw("&pk");
553 pk="&pk";
554 dtvars=compbl("&jsdtvars");
555 dttmvars=compbl("&jsdttmvars");
556 tmvars=compbl("&jstmvars");
557 loadtype=symget('loadtype');
558 if trim(symget('rk_underlying')) ne '' then rk_flag=1;
559 else rk_flag=0;
560 filter_text=symget('filter_text');
561 if %mf_nobs(work.cls_rules)=0 then cls_flag=0;
562 else cls_flag=1;
563 put (_all_)(=);
564 if "&orig_libds"="&mpelib..MPE_XLMAP_DATA" or &ismap ne 0 then ismap=1;
565 else ismap=0;
566run;
567
568
569/* Extract validation DQ Rules */
570proc sort data=&mpelib..mpe_validations
571 (where=(&dc_dttmtfmt. le TX_TO
572 and BASE_LIB="%scan(&orig_libds,1,.)" and BASE_DS="%scan(&orig_libds,2,.)"
573 and rule_active=1))
574 out=dqrules (keep=base_col rule_type rule_value);
575 by base_col rule_type rule_value;
576run;
577
578/* merge with NOTNULL constraints in the physical table */
579proc sql;
580create table _data_ as
581 select * from dqrules
582union
583 select upcase(name) as base_col
584 ,'NOTNULL' as rule_type
585 ,'' as rule_value
586 from dictionary.columns
587 where upcase(libname)="%scan(&orig_libds,1,.)"
588 and upcase(memname)="%scan(&orig_libds,2,.)"
589 and upcase(name) in (select name from vars3)
590 and notnull='yes'
591 order by 1,2,3;
592data dqrules;
593 set &syslast;
594 by base_col rule_type rule_value;
595 if last.rule_type;
596 if rule_type in ('HARDSELECT','SOFTSELECT') and countw(rule_value)=3 then
597 do;
598 retain x 0; x+1;
599 call symputx(cats('source',x),rule_value);
600 %let sourcecnt=0;
601 call symputx('sourcecnt',x);
602 call symputx(cats('base_col',x),base_col);
603 end;
604run;
605
606proc sql;
607create table dqdata as
608 select distinct base_column as base_col length=32
609 ,upcase(base_column) as rule_value length=74 /* deprecated */
610 ,selectbox_value as rule_data length=1000
611 ,selectbox_order
612 from &mpelib..mpe_selectbox
613 where &dc_dttmtfmt. lt ver_to_dttm
614 and select_lib="%scan(&orig_libds,1,.)"
615 and select_ds="%scan(&orig_libds,2,.)";
616
617%mp_abort(iftrue= (&syscc ne 0)
618 ,mac=&_program
619 ,msg=%str(syscc=&syscc during DQ rule validation)
620)
621
622/* extract selectbox data */
623%macro dq_selects();
624 %local x source lib ds col;
625 %do x=1 %to &sourcecnt;
626 %let source=&&source&x;
627 %let lib=%scan(&source,1,.);
628 %let ds=%scan(&source,2,.);
629 %let col=%scan(&source,3,.);
630 %put &=source;
631 %put &=lib;
632 %dc_assignlib(READ,&lib)
633 %dc_casload(&lib..&ds)
634 proc sql;
635 create table dqdata&x as
636 select distinct "&&base_col&x" as base_col length=32
637 ,"&source" as rule_value length=74
638 ,cats(&col) as rule_data length=1000
639 ,&col as tmp_order
640 from &lib..&ds
641 order by tmp_order;
642 /* ensure both numerics and char vals are ordered correctly */
643 data work.dqdata&x (drop=tmp_order);
644 set work.dqdata&x;
645 selectbox_order=_n_;
646 run;
647 %mp_abort(iftrue= (&syscc ne 0)
648 ,mac=&_program
649 ,msg=%str(syscc=&syscc when selecting &&base_col&x from &orig_libds)
650 )
651 proc append base=dqdata data=dqdata&x;run;
652 proc sql; drop table dqdata&x;
653 %end;
654%mend dq_selects;
655%dq_selects()
656
657proc sort data=dqdata;
658 /* order by selectbox_order then the value */
659 by base_col selectbox_order rule_data;
660run;
661
662%mp_getmaxvarlengths(work.sasdata1,outds=maxvarlengths)
663
664data maxvarlengths;
665 set maxvarlengths;
666 if name='_____DELETE__THIS__RECORD_____' then mAXLEN=3;
667run;
668
669data xl_rules;
670 set &mpelib..mpe_excel_config;
671 where &dc_dttmtfmt. lt tx_to;
672 where also upcase(xl_libref)="%scan(&orig_libds,1,.)";
673 where also upcase(xl_table)="%scan(&orig_libds,2,.)";
674 where also xl_active=1;
675 keep xl_column xl_rule;
676run;
677
678%mpe_dsmeta(&orig_libds, outds=dsmeta)
679
680%mpe_getversions(&mpelib,
681 %scan(&orig_libds,1,.),
682 %scan(&orig_libds,2,.),
683 outds=versions
684)
685
686
687/* send to the client */
688%webout(OPEN)
689%webout(OBJ,approvers)
690%webout(OBJ,cols)
691%webout(OBJ,dqdata,missing=STRING)
692%webout(OBJ,dqrules)
693%webout(OBJ,dsmeta)
694%webout(OBJ,maxvarlengths)
695%webout(OBJ,query)
696%webout(OBJ,sasdata1,fmt=N,missing=STRING,showmeta=YES,dslabel=sasdata)
697%webout(OBJ,sasparams)
698%webout(OBJ,versions)
699%webout(OBJ,xl_rules)
700%webout(CLOSE)
701
702/*
703$N8601Bw
704$N8601BAw
705$N8601Ew
706$N8601EAw
707$N8601EHw
708$N8601EXw
709$N8601Hw
710$N8601Xw
711B8601DAw
712B8601DNw
713B8601DTw
714B8601DZw
715B8601LZw
716B8601TMw
717B8601TZw
718DATEw
719DATEAMPMw
720DATETIMEw
721DAYw
722DDMMYYw
723DDMMYYxw
724DOWNAMEw
725DTDATEw
726DTMONYYw
727DTWKDATXw
728DTYEARw
729DTYYQCw
730E8601DAw
731E8601DNw
732E8601DTw
733E8601DZw
734E8601LZw
735E8601TMw
736E8601TZw
737HHMMw
738HOURw
739JULDAYw
740JULIANw
741MMDDYYw
742MMDDYYxw
743MMSSw
744MMYYw
745MMYYxw
746MONNAMEw
747MONTHw
748MONYYw
749PDJULGw
750PDJULIw
751QTRw
752QTRRw
753TIMEw
754TIMEAMPMw
755TODw
756WEEKDATEw
757WEEKDATXw
758WEEKDAYw
759WEEKUw
760WEEKVw
761WEEKWw
762WORDDATEw
763WORDDATXw
764YEARw
765YYMMw
766YYMMxw
767YYMMDDw
768YYMMDDxw
769YYMONw
770YYQw
771YYQxw
772YYQRw
773YYQRxw
774$N8601BAw
775$N8601Ew
776$N8601EAw
777$N8601EHw
778$N8601EXw
779$N8601Hw
780$N8601Xw
781B8601DAw
782B8601DNw
783B8601DTw
784B8601DZw
785B8601LZw
786B8601TMw
787B8601TZw
788E8601DAw
789E8601DNw
790E8601DTw
791E8601DZw
792E8601LZw
793E8601TMw
794E8601TZw
795*/
796%mpeterm()