Proc contents
can create a table of data set names to scan. A scanning macro, say %scanner
, can be written and invoked for each data set via call execute
. The results of the scan, the data set name and column containing the target, can be appended to an 'all results' table.
Example:
For simplicity it is presumed no data set has more than 10K variables of the target value type -- the code issues a warning if the scanning will be clipped.
Note: Example of string target would be ..., target="Jane", ...
%macro scanner (libname=, memname=, target=20500, flagMax = 10000);
%local type;
%if %qsysfunc(dequote(&target)) = %superq(target) %then
%let type = _numeric_;
%else
%let type = _character_;
data hits(keep=__libname __memname __varname);
array __flag (&flagMax) _temporary_;
set &libname..&memname;
array __candidates &type;
if dim(__candidates) = 0 then stop;
do __index = 1 to min (dim(__candidates), &flagMax);
if not __flag(__index) then
if __candidates(__index) = &target then do;
length __libname $8;
length __memname __varname $32;
__libname = "&libname";
__memname = "&memname";
__varname = vname(__candidates(__index));
__flag(__index) = 1;
OUTPUT;
end;
end;
if _n_ = 1 then
if dim(__candidates) > &flagMax then put "WARNING: &memname has more than &flagMax variables - scanning will be clipped. Increase flagMax=.";
run;
proc append base=hasTarget data=hits(rename=(__libname=libname __memname=memname __varname=varname));
run;
%mend;
proc sql;
create table hasTarget (libname char(8), memname char(32), varname char(32));
quit;
%let libname = SASHELP;
ods noresults;
ods output members=datasets;
proc datasets library=&libname memtype=data;
run;
quit;
ods results;
data _null_;
set datasets(keep=name memtype);
where memtype = 'DATA';
call execute (cats('%nrstr(%scanner(libname=' || "&LIBNAME., " || "memname=", name, '))'));
run;