Loading...
Searching...
No Matches
mp_validatecol.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Used to validate values in a data step
4 @details Useful when sanitising inputs, to ensure that they arrive with a
5 certain pattern.
6 Usage:
7
8 data test;
9 infile datalines4 dsd;
10 input;
11 libds=_infile_;
12 %mp_validatecol(libds,LIBDS,is_libds)
13 datalines4;
14 some.libname
15 !lib.blah
16 %abort
17 definite.ok
18 not.ok!
19 nineletrs._
20 ;;;;
21 run;
22
23 For more examples, see mp_validatecol.test.sas
24
25 Tip - when contributing, use https://regex101.com to test the regex validity!
26
27 @param [in] incol The column to be validated
28 @param [in] rule The rule to apply. Current rules:
29 @li ISINT - checks if the variable is an integer
30 @li ISLIB - checks if the value is a valid libref (NOT whether it exists)
31 @li ISNUM - checks if the variable is numeric
32 @li LIBDS - matches LIBREF.DATASET format
33 @li FORMAT - checks if the provided format is syntactically valid
34 @param [out] outcol The variable to create, with the results of the match
35
36 <h4> SAS Macros </h4>
37 @li mf_getuniquename.sas
38
39 <h4> Related Macros </h4>
40 @li mp_validatecol.test.sas
41
42 @version 9.3
43**/
44
45%macro mp_validatecol(incol,rule,outcol);
46
47/* tempcol is given a unique name with every invocation */
48%local tempcol;
49%let tempcol=%mf_getuniquename();
50
51%if &rule=ISINT %then %do;
52 &outcol=0;
53 if not missing(&incol) then do;
54 &tempcol=input(&incol,?? best32.);
55 if not missing(&tempcol) then if mod(&tempcol,1)=0 then &outcol=1;
56 end;
57 drop &tempcol;
58%end;
59%else %if &rule=ISNUM %then %do;
60 /*
61 credit SOREN LASSEN
62 https://sasmacro.blogspot.com/2009/06/welcome-isnum-macro.html
63 */
64 &tempcol=input(&incol,?? best32.);
65 if missing(&tempcol) then &outcol=0;
66 else &outcol=1;
67 drop &tempcol;
68%end;
69%else %if &rule=ISLIB %then %do;
70 if _n_=1 then do;
71 retain &tempcol;
72 &tempcol=prxparse('/^[_a-z]\w{0,7}$/i');
73 if missing(&tempcol) then do;
74 putlog 'ERR' +(-1) "OR: Invalid expression for ISLIB";
75 stop;
76 end;
77 drop &tempcol;
78 end;
79 if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
80 else &outcol=0;
81%end;
82%else %if &rule=LIBDS %then %do;
83 /* match libref.dataset */
84 if _n_=1 then do;
85 retain &tempcol;
86 &tempcol=prxparse('/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i');
87 if missing(&tempcol) then do;
88 putlog 'ERR' +(-1) "OR: Invalid expression for LIBDS";
89 stop;
90 end;
91 drop &tempcol;
92 end;
93 if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
94 else &outcol=0;
95%end;
96%else %if &rule=FORMAT %then %do;
97 /* match valid format - regex could probably be improved */
98 if _n_=1 then do;
99 retain &tempcol;
100 &tempcol=prxparse('/^[_a-z\$]\w{0,31}\.[0-9]*$/i');
101 if missing(&tempcol) then do;
102 putlog 'ERR' +(-1) "OR: Invalid expression for FORMAT";
103 stop;
104 end;
105 drop &tempcol;
106 end;
107 if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
108 else &outcol=0;
109%end;
110
111%mend mp_validatecol;