每次EDC系统升级,我们总需要对升级前后的excel数据集、SAS数据集进行一致性比对,以保证升级前后数据完全一致。
我做了相应的SAS比对工具,但每次都要手动将所有数据集名称手敲一遍,这样未免太蠢了吧。。。
所以,我们需要学习如何让SAS自动读取excel中所有sheetname。
思路
1、定义两个空的逻辑库(升级\改库前后)备用。
2、通过SASHELP.vstabvw将excel中的sheet放到"EXCEL"逻辑库中,但这时的sheet不可读且,表名具有特殊的格式(eg:AE ->'AE$')。
3、将"EXCEL"逻辑库中的所有数据集名称放到"sheetname"表中。
4、利用compress去掉"sheetname"中所有观测里的特殊符号。
5、通过"sheetname"的观测生成sheetname相对应的宏变量。
6、通过循环和第5步产生的宏变量,将所有sheet中内容导入第1步生成的逻辑库中。
实现
*****************************需要修改内容*****************************;
libname pre "E:\Your previous libname";
libname post "E:\Your post libname";
%let bef_dir=E:\Your Before Directory.xlsx;
%let aft_dir=E:\Your After Directory.xlsx;
%let PROTOCOL=Your protocol id;
********************************************************************;
libname excel excel "&bef_dir";
proc sql noprint;
create table sheetname as
select memname
from sashelp.vstabvw
where upcase(libname)= "EXCEL";
data sheetname;
set sheetname;
memname=compress(memname,"'$ ");
run;
data _null_;
set sheetname nobs=num;
n = _n_;
call symputx("num",num);
call symputx("COL"||left(put(n,3.)),memname);
run;
%put &COL1;
/*两段宏分别读取两个excel中的所有sheet*/
%macro importFile1();
%let i=1;
%do i=1 %to &num.;
%let sheetName=&&COL&i.;
proc import out=pre.&sheetName. dbms=excel replace datafile="&bef_dir";
getnames=yes;
sheet=&sheetName.;
run;
%end;
%mend;
%importFile1();
后记
后续比较则通过循环proc compare即可,与主题无关,这边不赘述了。按这个思路,解决了第一版工具80%的问题,但在仍然存在未解决的问题:
如果sheetname中有空格,则需要去excel中将空格删除掉,否则程序会报错。这点我这边的思路是可以不进行第四部的compress,在import程序的主体中做文章。
demo重点在于记录这个方法,写法比较naive。