📄 metadata.sas
字号:
%macro metadata(datain= , form=standard, delim='09'x);
%put Get metadata.;
%put;
%let memname = %scan(&datain, 2, .); /* extract library and member names */
%if (&memname eq ) %then %do;
%let libname = WORK;
%let memname = %upcase(&datain);
%end;
%else %do;
%let libname = %upcase(%scan(&datain, 1, .));
%let memname = %upcase(&memname);
%end;
proc sql; /* create dataset of libraries and members */
create view members as
select libname, memname, memtype
from dictionary.members;
quit;
%let libfound = ; /* check library and member names */
%let memfound = ;
data _null_;
set members;
if (libname eq "&libname") then do;
call symput('libfound', 'y');
if (memname eq "&memname" and memtype eq "DATA") then call symput('memfound', 'y');
end;
run;
%if (&libfound ne y) %then %let msg = Library &libname not defined.;
%else %if (&memfound ne y) %then %let msg = Dataset &libname..&memname not found.;
%else %do;
%let frames = ; /* get formats */
%if (%sysfunc(libref(library)) eq 0) %then %do;
%if (%sysfunc(exist(library.formats, catalog))) %then %do;
%let frames = y;
proc format library=library cntlout=formats; /* create formats dataset */
run;
%end;
%end;
%if (&frames eq ) %then %do; /* no formats */
proc sql; /* create variables dataset without formats */
create view variables as
select name, type, label
from dictionary.columns
where libname = "&libname" and memname = "&memname";
quit;
data vars1; /* change attributes of variables dataset */
attrib
Name label="Variable name"
Type label="Variable type"
Label label="Variable label"
;
set variables;
run;
%end;
%else %do; /* formats */
proc sql; /* create variables dataset with formats */
create view variables as
select name, type, format, label
from dictionary.columns
where libname = "&libname" and memname = "&memname";
quit;
data vars1; /* replace formats with codeframes in variables dataset */
attrib
Name label="Variable name"
Type label="Variable type"
Frame label="Variable codeframe"
Label label="Variable label"
;
set formats(in=_form_ keep=fmtname) variables end=_end_;
%if (%sysevalf(&sysver lt 9)) %then %do;
length form1 - form5000 oldform $ 8;
%end;
%else %do;
length form1 - form5000 oldform $ 32;
%end;
retain form1 - form5000 oldform "";
array formats(5000) form1 - form5000;
retain _forms_ _frames_ 0;
keep Name Type Frame Label;
if (_form_) then do; /* formats file */
if (fmtname ne oldform) then do; /* build formats list */
oldform = fmtname;
_i_ = 1;
do while(_i_ le _forms_);
if (fmtname eq formats(_i_)) then leave;
_i_ = _i_ + 1;
end;
if (_i_ gt _forms_) then do;
formats(_i_) = fmtname;
_forms_ = _i_;
end;
end;
end;
else do; /* variables file */
if (format ne "") then do; /* drop unmatched formats */
format1 = upcase(substr(format, 1, 1));
if (format1 eq '_' or format1 ge 'A' and format1 le 'Z') then do;
format = substr(format, 1, length(format)-1);
_i_ = 1;
do while(_i_ le _forms_);
if (format eq formats(_i_)) then leave;
_i_ = _i_ + 1;
end;
if (_i_ le _forms_) then do;
frame = format;
_frames_ = 1;
end;
end;
end;
output; /* write updated variable record */
end;
if (_end_ and _frames_ eq 0) then call symput('frames', ''); /* update frames */
run;
%if (&frames eq ) %then %do; /* no referenced codeframes */
data vars1; /* drop formats attribute */
set vars1(drop = frame);
run;
%end;
%else %do;
data codes1; /* build codeframes dataset */
attrib
Frame label="Codeframe name"
Value label="Code value"
Label label="Code label"
;
set vars1(in=_var_ keep=frame) formats(rename=(fmtname=Frame start=Value LABEL=Label)) end=_end_;
%if (%sysevalf(&sysver lt 9)) %then %do;
length frame1 - frame5000 oldframe $ 8;
%end;
%else %do;
length frame1 - frame5000 oldframe $ 32;
%end;
array frames(5000) frame1 - frame5000;
retain frame1 - frame5000 oldframe "" _frames_ _keep_ 0;
keep Frame Value Label;
if (_var_) then do; /* variables file */
if (frame ne "") then do; /* build frames list */
_i_ = 1;
do while(_i_ le _frames_);
if (frame eq frames(_i_)) then leave;
_i_ = _i_ + 1;
end;
if (_i_ gt _frames_) then do;
frames(_i_) = frame;
_frames_ = _i_;
end;
end;
end;
else do; /* frames file */
if (frame ne oldframe) then do; /* check format */
oldframe = frame;
_i_ = 1;
do while(_i_ le _frames_);
if (frame eq frames(_i_)) then leave;
_i_ = _i_ + 1;
end;
if (_i_ le _frames_) then _keep_ = 1;
else _keep_ = 0;
end;
if (_keep_) then output; /* write updated code record */
end;
run;
%end;
%end;
%if (%lowcase(&form) eq standard or %lowcase(&form) eq text) %then %do; /* standard or text output */
data _null_; /* write metadata file */
%if (&frames eq ) %then %do;
set vars1;
%end;
%else %do;
set vars1(in=_var_) codes1 end=_end_;
%end;
%if (&sysver eq 6.12) %then %do;
length line $ 200 oldframe $ 8;
%end;
%else %do;
length line $ 1024;
%if (%sysevalf(&sysver lt 9)) %then %do;
length oldframe $ 8;
%end;
%else %do;
length oldframe $ 32;
%end;
%end;
length oldtype $ 8;
retain oldtype oldframe ' ' _code_ 0;
file "&path..met";
if (_n_ eq 1) then do; /* write header */
%if (&form eq standard) %then %do;
put 'standard;';
%end;
%else %if (&delim eq ) %then %do;
put 'delim " ";';
%end;
%else %if (&delim eq '09'x) %then %do;
put 'delim "\t";';
%end;
%else %do;
put 'delim "' "&delim" '";';
%end;
put 'variables';
end;
%if (&frames ne ) %then %do; /* write variable lines */
if (_var_) then do;
%end;
line = 'name=' || name;
if (label ne ' ') then do;
line = trim(line) || ' label="';
do until (label eq ' ');
next = indexc(label, '"');
if (next eq 0) then do;
line = trim(line) || label;
label = ' ';
end;
else do;
line = trim(line) || substr(label, 1, next) || '"';
label = substr(label, next+1);
end;
end;
line = trim(line) || '"';
end;
if (type ne oldtype) then do;
oldtype = type;
if (type eq 'char') then line = trim(line) || ' type=char';
%if (&form eq standard) %then %do;
else line = trim(line) || ' type=float';
%end;
%else %do;
else line = trim(line) || ' type=num';
%end;
end;
%if (&form eq standard) %then %do;
if (_n_ eq 1) then line = trim(line) || ' width=8';
%end;
%if (&frames ne ) %then %do;
if (frame ne ' ') then line = trim(line) || ' codeframe=' || trim(frame);
%end;
line = trim(line) || ';';
put @3 line;
%if (&frames ne ) %then %do; /* write codeframe lines */
end;
else do;
if (frame ne ' ') then do;
if (frame ne oldframe) then do;
oldframe = frame;
if (_code_ eq 0) then do;
_code_ = 1;
put 'codeframes';
end;
else put ' ;';
put @3 'name=' frame;
end;
line = trim(value) || ' = "';
do until (label eq ' ');
next = indexc(label, '"');
if (next eq 0) then do;
line = trim(line) || label;
label = ' ';
end;
else do;
line = trim(line) || substr(label, 1, next) || '""';
label = substr(label, next+1);
end;
end;
line = trim(line) || '"';
put @5 line;
end;
if (_end_ and _code_) then put ' ;';
end;
%end;
run;
%end;
%end;
%mend metadata;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -