Macros for SAS Application Developers
https://github.com/sasjs/core
mp_validatecol.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Used to validate variables in a dataset
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 ISNUM - checks if the variable is numeric
31 @li LIBDS - matches LIBREF.DATASET format
32 @li FORMAT - checks if the provided format is syntactically valid
33 @param [out] outcol The variable to create, with the results of the match
34
35 <h4> SAS Macros </h4>
36 @li mf_getuniquename.sas
37
38 <h4> Related Macros </h4>
39 @li mp_validatecol.test.sas
40
41 @version 9.3
42**/
43
44%macro mp_validatecol(incol,rule,outcol);
45
46/* tempcol is given a unique name with every invocation */
47%local tempcol;
48%let tempcol=%mf_getuniquename();
49
50%if &rule=ISINT %then %do;
51 &outcol=0;
52 if not missing(&incol) then do;
53 &tempcol=input(&incol,?? best32.);
54 if not missing(&tempcol) then if mod(&tempcol,1)=0 then &outcol=1;
55 end;
56 drop &tempcol;
57%end;
58%else %if &rule=ISNUM %then %do;
59 /*
60 credit S├śREN LASSEN
61 https://sasmacro.blogspot.com/2009/06/welcome-isnum-macro.html
62 */
63 &tempcol=input(&incol,?? best32.);
64 if missing(&tempcol) then &outcol=0;
65 else &outcol=1;
66 drop &tempcol;
67%end;
68%else %if &rule=LIBDS %then %do;
69 /* match libref.dataset */
70 if _n_=1 then do;
71 retain &tempcol;
72 &tempcol=prxparse('/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i');
73 if missing(&tempcol) then do;
74 putlog "%str(ERR)OR: Invalid expression for LIBDS";
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=FORMAT %then %do;
83 /* match valid format - regex could probably be improved */
84 if _n_=1 then do;
85 retain &tempcol;
86 &tempcol=prxparse('/^[_a-z\$]\w{0,31}\.[0-9]*$/i');
87 if missing(&tempcol) then do;
88 putlog "%str(ERR)OR: Invalid expression for FORMAT";
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
97%mend mp_validatecol;