-
Notifications
You must be signed in to change notification settings - Fork 75
/
fmtlist.sas
299 lines (251 loc) · 10.2 KB
/
fmtlist.sas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*=====================================================================
Program Name : fmtlist.sas
Purpose : Prints contents of one or more format or
informat entries.
SAS Version : SAS 9.1.3
Input Data : None
Output Data : None
Macros Called : parmv, seplist
Originally Written by : Scott Bass
Date : 04JUL2005
Program Version # : 1.0
=======================================================================
Scott Bass ([email protected])
This code is licensed under the Unlicense license.
For more information, please refer to http://unlicense.org/UNLICENSE.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
=======================================================================
Modification History :
Programmer : Scott Bass
Date : 18SEP2013
Change/reason : Complete rewrite of macro based on features
available in SAS 9.3
Program Version # : 1.1
=====================================================================*/
/*---------------------------------------------------------------------
Usage:
proc format lib=work.formats;
value $chrfmt "A"="A";
value numfmt 2 ="B";
invalue $chrinfmt "C"="C";
invalue numinfmt "D"=4;
run;
%fmtlist()
Lists all formats in the fmtsearch path.
%fmtlist(doesnotexist)
Prints a message to the log since no formats match the filter.
%fmtlist(.*fmt doesnotexist)
Lists all formats in the fmtsearch path
with name ending in "fmt".
Note that non-existent format names are silently ignored.
%fmtlist(age.* .*desc .*current.* assid branch)
Lists all formats in the fmtsearch path
with name beginning with "age",
or ending with "desc",
or containing the word "current",
or exactly named "assid" or "branch"
%fmtlist(catalog=doesnot.exist)
Prints a message to the log since no formats match the filter.
%fmtlist(catalog=apfmtlib.formats work.formats doesnot.exist)
Lists all formats in the apfmtlib.formats or work.formats catalogs,
if those catalogs are in the fmtsearch path.
Note that non-existent format catalogs are silently ignored.
%fmtlist(catalog=work.formats)
Lists all formats in the work.formats catalog,
if that catalog is in the fmtsearch path.
%fmtlist(catalog=work.formats, type=CF NF)
Lists all >>>character formats<<< and >>>numeric formats<<<
from the work.formats catalog.
%fmtlist(type=NF NI)
Lists all >>>numeric formats<<< and >>>numeric informats<<<
in the fmtsearch path.
%fmtlist(catalog=work.formats,details=Y)
Prints the DETAILS of all formats in the work.formats catalog,
rather than just listing their names,
if that catalog is in the fmtsearch path.
%fmtlist(age.*des chr.*,catalog=meta.formats work.formats,details=Y)
Prints the DETAILS of formats with names beginning with "age*des" or "chr",
in the meta.formats and work.formats catalogs,
if those catalogs are in the fmtsearch path.
-----------------------------------------------------------------------
Notes:
This macro uses the metadata from the dictionary.formats view.
This dictionary view only lists (built-in and) user-defined formats that
are in the current fmtsearch path. Therefore, only user-defined formats
in the current fmtsearch path are listed or printed. This is acceptable,
since these are the only formats available.
By default, this macro lists format names in the output destination.
Specify DETAILS=Y to print the format details in the output destination.
The format list uses Perl Regular Expression (PRX) format to filter
the output (vs. say SQL LIKE syntax). Each token is bound by the
word break metacharacter (\b) to prevent "false hits" on the filter.
In particular, the wildcard for "all characters" is "dot-asterisk" (.*),
not just asterisk.
See this link (or Google "Perl Regular Expressions") for more details:
http://support.sas.com/documentation/cdl/en/lefunctionsref/64814/HTML/default/viewer.htm#p0s9ilagexmjl8n1u7e1t1jfnzlk.htm
Specify multiple format names and/or wildcards as a space separated list.
The PRX "or" operator (|) will be added by the macro.
Specify the CAT= parameter to limit the search to a single catalog in
the fmtsearch path. Otherwise, all format catalogs are searched.
Specify the TYPE= parameter to limit the search to one or more format
types:
CF=Character Format (Accepts character input, returns character output)
NF=Numeric Format (Accepts numeric input, returns character output)
CI=Character Informat (Accepts character input, returns character output)
NI=Numeric Informat (Accepts character input, returns numeric output)
----------------------------------------------------------------------*/
%macro fmtlist
/*---------------------------------------------------------------------
Prints contents of one or more format or informat entries
---------------------------------------------------------------------*/
(LIST /* List of one or more formats or informats (Opt). */
/* If not specified, all formats are printed. */
/* Specify wildcards using PRX format, as a */
/* space-separated list. */
,CATALOG= /* Format catalog(s) to search (Opt). */
/* If not specified, uses the current value of the */
/* FMTSEARCH option to locate the format entry. */
/* If specified, use a space-separated list of */
/* catalogs in the fmtsearch path to limit the search */
/* to only those catalogs. */
,TYPE= /* Filter output to specified format type(s) (Opt). */
/* If not specified, all format types are listed. */
/* Valid values are CF, NF, CI, and NF. */
,DETAILS=N /* Print format details instead of just listing the */
/* format name? (Req.) */
/* If N, only the format names are printed. */
/* If Y, the format details are printed. */
/* OFF N NO F FALSE and ON Y YES T TRUE */
/* (case insensitive) are acceptable aliases for */
/* 0 and 1 respectively. */
);
%local macro parmerr where temp flag;
%let macro = &sysmacroname;
%* check input parameters ;
%parmv(LIST, _req=0,_words=1,_CASE=U)
%parmv(CATALOG, _req=0,_words=1,_CASE=U)
%parmv(TYPE, _req=0,_words=1,_CASE=U,_VAL=CF NF CI NI)
%parmv(DETAILS, _req=1,_words=0,_CASE=U,_VAL=0 1)
%if (&parmerr) %then %goto quit;
%* build where clause ;
%let where=;
%if (%superq(list) ne ) %then %do;
%let temp=%seplist(%superq(list),dlm=|,prefix=\b,suffix=\b);
%let temp=%unquote(&temp);
%let where=prxmatch("/&temp/io",objname);
%end;
%if (&catalog ne ) %then %do;
%let temp=%seplist(&catalog,nest=qq);
%let temp=%unquote(&temp);
%if (%superq(where) ne ) %then %let where=&where and;
%let where=&where catx(".",libname,memname) in (&temp);
%end;
%if (&type ne) %then %do;
%let temp=%seplist(&type,nest=qq);
%let temp=%unquote(&temp);
%if (%superq(where) ne ) %then %let where=&where and;
%let where=&where fmttype in (&temp);
%end;
%let where=%unquote(&where);
%let flag=%eval(%superq(where) ne );
%* Create view of all the user-defined formats in the current fmtsearch path ;
%if (not %sysfunc(exist(work.usrfmts,view))) %then %do;
proc sql;
create view work.usrfmts as
select
libname,
memname,
objname,
fmtname,
cats(ifc(substr(fmtname,1,1)="$","C","N"),fmttype) as fmttype length=2
from
dictionary.formats
where
libname is not missing
order by
libname, memname
;
quit;
%end;
%* If just listing format names, output to print location ;
%if (not &details) %then %do;
proc sql print;
select
*
from
work.usrfmts
%if (&flag) %then %do;
where
&where
%end;
order by
objname
;
quit;
%if (&sqlobs eq 0) %then %do;
%put NOTE: No formats matching the filter were found in the fmtsearch path.;
%goto quit;
%end;
%end;
%* Ok, we want the format details, not just the format names ;
%* We need to process each format catalog in the fmtsearch path individually ;
%else %do;
%* get a list of the format catalogs ;
proc sql noprint;
select distinct
catx(".",libname,memname) into :fmtcats separated by " "
from
work.usrfmts
%if (&flag) %then %do;
where
&where
%end;
;
quit;
%if (&sqlobs eq 0) %then %do;
%put NOTE: No format catalogs matching the filter were found in the fmtsearch path.;
%goto quit;
%end;
%* Now loop over each format catalog ;
%macro code;
%let formats=;
%if (&flag) %then %do;
proc sql noprint;
select
cats(ifc(fmttype in ("CI","NI"),"@",""),fmtname) into :formats separated by " "
from
work.usrfmts
where
catx(".",libname,memname)="&word"
%if (&flag) %then %do;
and
&where
%end;
order by
objname
;
quit;
%if (&sqlobs eq 0) %then %do;
%put NOTE: No formats matching the filter were found in the fmtsearch path.;
%end;
%end;
%if (not &flag or &sqlobs ne 0) %then %do;
%* Now call PROC FORMAT to print the format details ;
title "&word";
proc format lib=&word fmtlib page;
%if (&formats ne ) %then %do;
select &formats;
%end;
run;
title;
%end;
%mend;
%loop(&fmtcats)
%end;
%quit:
%mend;
/******* END OF FILE *******/