68%macro mp_filtercheck(inds,targetds=,outds=work.badrecords,abort=YES);
70%mp_abort(iftrue= (&syscc ne 0)
72 ,msg=%str(syscc=&syscc - on macro entry)
77%let vtype=%mf_getvartype(&inds,RAW_VALUE);
78%mp_abort(iftrue=(&abort=YES and &vtype ne C),
80 msg=%str(%str(ERR)OR: RAW_VALUE must be character)
82%
if &vtype ne C %then %
do;
83 %put &sysmacroname: RAW_VALUE must be character;
99 length reason_cd $4032 vtype vtype2 $1 vnum dsid 8 tmp $4000 re_temporal 8
101 drop tmp re_temporal vref;
104 if _n_=1 then re_temporal=prxparse(
"/^'[^']*'(dt|d|t)$/i");
107 if upcase(VARIABLE_NM) not in
108 (%upcase(%mf_getvarlist(&targetds,dlm=%str(,),quote=SINGLE)))
110 REASON_CD=
"Variable "!!cats(variable_nm)!!
" not in &targetds";
111 putlog REASON_CD= VARIABLE_NM=;
112 call symputx(
'reason_cd',reason_cd,
'l');
113 call symputx(
'nobs',_n_,
'l');
120 if _n_=1 then dsid=open(
"&targetds",
"i");
122 vnum=varnum(dsid,VARIABLE_NM);
125 REASON_CD=cats(
"Variable (",VARIABLE_NM,
") not found in &targetds");
126 putlog REASON_CD= dsid=;
127 call symputx(
'reason_cd',reason_cd,
'l');
128 call symputx(
'nobs',_n_,
'l');
133 else vtype=vartype(dsid,vnum);
136 REASON_CD=cats(
"Could not open &targetds");
137 putlog REASON_CD= dsid=;
138 call symputx(
'reason_cd',reason_cd,
'l');
139 call symputx(
'nobs',_n_,
'l');
145 if GROUP_LOGIC not in (
'AND',
'OR') then do;
146 REASON_CD='GROUP_LOGIC should be AND/OR, not:'!!cats(GROUP_LOGIC);
147 putlog REASON_CD= GROUP_LOGIC=;
148 call symputx('reason_cd',reason_cd,
'l');
149 call symputx('nobs',_n_,
'l');
152 if SUBGROUP_LOGIC not in ('AND
','OR') then do;
153 REASON_CD='SUBGROUP_LOGIC should be AND/OR, not:'!!cats(SUBGROUP_LOGIC);
154 putlog REASON_CD= SUBGROUP_LOGIC=;
155 call symputx('reason_cd',reason_cd,
'l');
156 call symputx('nobs',_n_,
'l');
159 if mod(SUBGROUP_ID,1) ne 0 then do;
160 REASON_CD='SUBGROUP_ID should be integer, not '!!cats(subgroup_id);
161 putlog REASON_CD= SUBGROUP_ID=;
162 call symputx('reason_cd',reason_cd,
'l');
163 call symputx('nobs',_n_,
'l');
166 if OPERATOR_NM not in
167 (
'=',
'>',
'<','<=
','>=
','NE
','GE
','LE
','BETWEEN
','IN
','NOT IN
','CONTAINS')
169 REASON_CD='Invalid OPERATOR_NM: '!!cats(OPERATOR_NM);
170 putlog REASON_CD= OPERATOR_NM=;
171 call symputx('reason_cd',reason_cd,
'l');
172 call symputx('nobs',_n_,
'l');
179 if vtype=
'N' & OPERATOR_NM='CONTAINS' then do;
180 vref=cats(
"&targetds",
'.',VARIABLE_NM);
181 REASON_CD=catx(
' ','CONTAINS is only valid for character variables -'
183 putlog REASON_CD= OPERATOR_NM=;
184 call symputx('reason_cd',reason_cd,
'l');
185 call symputx('nobs',_n_,
'l');
193 if vtype=
'C' & OPERATOR_NM='CONTAINS'
194 & subpad(strip(raw_value),1,1) not in (
'"',
"'")
196 vref=cats(
"&targetds",
'.',VARIABLE_NM);
199 if prxmatch('/^[a-z_][a-z0-9_]*$/i',strip(raw_value))>0 then do;
200 vnum=varnum(dsid,strip(raw_value));
204 vtype2=vartype(dsid,vnum);
205 if vtype2=
'C' then return;
206 REASON_CD=catx(
' ',
"Compared Type ("!!vtype2!!
") is not (C) -"
207 ,vref,'CONTAINS',cats(raw_value));
209 else REASON_CD=catx(
' ','CONTAINS requires a quoted value or a character'
210 ,'variable -',vref,'CONTAINS',cats(raw_value));
211 putlog REASON_CD= OPERATOR_NM=;
212 call symputx('reason_cd',reason_cd,
'l');
213 call symputx('nobs',_n_,
'l');
219 if vtype=
'N' & OPERATOR_NM in (
'=',
'>',
'<','<=
','>=
','NE
','GE
','LE') then do;
220 if cats(upcase(raw_value)) in (
221 '.','.A
','.B
','.C
','.D
','.E
','.F
','.G
','.H
','.I
','.J
','.K
','.L
','.M
','.N'
222 '.N
','.O
','.P
','.Q
','.R
','.S
','.T
','.U
','.V
','.W
','.X
','.Y
','.Z
','._'
228 else if subpad(upcase(raw_value),1,1) in (
229 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N'
230 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'_'
234 vnum=varnum(dsid,subpad(raw_value,1,32));
237 vtype2=vartype(dsid,vnum);
239 if vtype2=vtype then do;
244 REASON_CD=cats(
"Compared Type (",vtype2,
") is not (",vtype,
")");
245 putlog REASON_CD= dsid=;
246 call symputx('reason_cd',reason_cd,
'l');
247 call symputx('nobs',_n_,
'l');
256 if vtype=
'N' and prxmatch(re_temporal,cats(raw_value))>0 then return;
259 if OPERATOR_NM in ('IN
','NOT IN
','BETWEEN') then do;
260 if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND
',',');
262 if substr(raw_value,1,1) ne
'('
263 or substr(cats(reverse(raw_value)),1,1) ne
')'
265 REASON_CD='Missing start/end bracket in RAW_VALUE';
266 putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
267 call symputx('reason_cd',reason_cd,
'l');
268 call symputx('nobs',_n_,
'l');
271 else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
274 if vtype=
'N' then do i=1 to countc(raw_value1,
',')+1;
275 tmp=scan(raw_value1,i,
',');
276 if cats(tmp) ne
'.' and input(tmp, ?? 8.) eq . then do;
278 if prxmatch(re_temporal,cats(tmp))=0 then do;
279 if OPERATOR_NM ='BETWEEN' and subpad(upcase(tmp),1,1) in (
280 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N'
281 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'_'
286 vnum=varnum(dsid,subpad(tmp,1,32));
289 vtype2=vartype(dsid,vnum);
291 if vtype2 ne vtype then do;
292 REASON_CD=cats(
"Compared Type (",vtype2,
") is not (",vtype,
")");
293 putlog REASON_CD= dsid=;
294 call symputx('reason_cd',reason_cd,
'l');
295 call symputx('nobs',_n_,
'l');
301 REASON_CD='Non Numeric value provided';
302 putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
303 call symputx('reason_cd',reason_cd,
'l');
304 call symputx('nobs',_n_,
'l');
309 REASON_CD='Non Numeric value provided';
310 putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
311 call symputx('reason_cd',reason_cd,
'l');
312 call symputx('nobs',_n_,
'l');
321 if vtype=
'N' then return;
323 else raw_value1=raw_value;
326 raw_value1=tranwrd(raw_value1,
"''",'');
329 raw_value2=raw_value1;
330 regex = prxparse(
"s/(\').*?(\')//");
331 call prxchange(regex,-1,raw_value2);
334 raw_value3=compress(raw_value2,',.');
337 if notdigit(compress(raw_value3,
' '))>0 then do;
338 if vtype=
'C' and subpad(upcase(raw_value),1,1) in (
339 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N'
340 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'_'
344 vnum=varnum(dsid,subpad(raw_value,1,32));
347 vtype2=vartype(dsid,vnum);
349 if vtype2=vtype then do;
354 REASON_CD=cats(
"Compared Char Type (",vtype2,
") is not (",vtype,
")");
355 putlog REASON_CD= dsid=;
356 call symputx('reason_cd',reason_cd,
'l');
357 call symputx('nobs',_n_,
'l');
364 putlog raw_value3= $hex32.;
365 REASON_CD=cats('Invalid RAW_VALUE:',raw_value);
367 call symputx('reason_cd',reason_cd,
'l');
368 call symputx('nobs',_n_,
'l');
373 if last then rc=close(dsid);
382%mp_abort(iftrue=(&abort=YES and &nobs>0),
384 msg=%str(Data issue: %superq(reason_cd))
387%if &nobs>0 %then %do;
397%let fref1=%mf_getuniquefileref();
398%mp_filtergenerate(&inds,outref=&fref1)
401%mp_filtervalidate(&fref1,&targetds,outds=&outds,abort=&abort)