我正在尝试导入一些包含多个工作表的文件。每个工作表中的变量名称从不同的行开始。我当前的代码允许我在一个数据集中获取所有工作表名称。我使用它将工作表名称存储在宏列表中,然后在do循环中使用proc导入来导入每个工作表。我面临的问题是每张纸上的数据都是从不同的行开始的。我想知道是否有办法在数据开始的每个工作表中获取行号,这样我就可以添加代码来指定导入宏中每个工作表的特定范围。
**********GETTING TAB NAMES****************
PROC SQL noprint;
CONNECT TO pcfiles (path = "[ENTER FILE PATH HERE]");
CREATE TABLE TABS_NAMES as
SELECT * from connection to pcfiles (PCFILES::SQLColumns "","","","");
DISCONNECT FROM pcfiles;
QUIT;
**********CLEANING TAB NAMES****************
Data Tab_names_1;
set TABS_NAMES;
Clean_tab_name = dequote(tranwrd(TABLE_NAME,"$",""));
if prxmatch ('/print/i',Table_name) > 0 then delete;
keep TABLE_CAT Clean_tab_name;
run;
Proc sort data = Tab_names_1 out = Tab_names_2 nodupkey;
by _all_;
run;
**********STORING TAB NAMES****************
Proc sql noprint;
select TABLE_CAT, Clean_tab_name
into :Path1-:Path999, :Tab_Name1-:Tab_name999
from Tab_names_2;
%let max=&sqlobs.;
quit;
***************IMPORTING FILES*********
%MACRO Import;
%do i=1 %to &max.;
Proc import
datafile = "&&Path&i.."
out = Raw_Data_&i..
dbms = excelcs
replace;
sheet = "&&Tab_Name&i..";
run;
%end;
%mend;
%Import;
答案 0 :(得分:0)
这是一个动态获取每个标签的第一行的一般(未经测试)的想法。 解释在代码中发表评论。这是一个粗略的想法,很可能需要修补。请注意,例如我假设您的选项卡名称解析为有效的SAS表名
/* assign a libname using the appropriate excel engine (XLS or XLSX)*/
LIBNAME lib XLS "path-to-xls";
/* get the the list of sheets and variables in your excel and output it to 'contents' */
proc contents data=lib._all_ out=contents;
run;
/* get the list of tab names from the contents table and store them in macro variables */
proc sql noprint;
select distinct memname
into :tab1-
from contents
;
quit;
%macro import();
%let i=1;
/* iterate accross all your tabs */
%do %while(%symexist(tab&i.));
proc sql noprint;
/* get the column names for the current tab in a comma separated list */
select name
into cols separated by ','
from contents
where name="&&tab&i."
;
/* store the number of columns for the current tab in another macro variable */
select count(name)
into ncols
from contents
where name="&&tab&i."
;
quit;
/* go through each record of your tab until you encounter the first non-empty one and store the record number in a macro variable */
data _null_;
retain first 1;
set lib.&&tab&i.;
if cmiss(&cols.) = &ncols. then do;
first=first+1;
call symput("&&tab&i.",first);
end;
else stop;
run;
/* you now have the first record of each tab in a macro variable named after the corresponding tab */
%put &&&&&&tab&i.;
/* add some code to import your worksheet */
%let i=%eval(&i+1);
%end;
%let n=%eval(&i-1);
%mend;
%import;
答案 1 :(得分:0)
我有一段时间遇到过类似的问题。我需要从包含许多空行的特定工作表中导入数据,以及在第一列中导入无用的标题。我能想到的最简单的解决方案是从SAS调用VB脚本(使用SYSTASK)将干净的表格导出到临时的csv文件,然后我可以轻松导入。
以下是脚本的代码:
file
在我的情况下,我只有一个文件要处理,所以我确信这可以在你的情况下简化,但它应该提供你需要的起点。