如何获取excel文件中不同工作表的范围以用于在宏中导入?

时间:2017-08-21 19:24:12

标签: sql import macros sas

我正在尝试导入一些包含多个工作表的文件。每个工作表中的变量名称从不同的行开始。我当前的代码允许我在一个数据集中获取所有工作表名称。我使用它将工作表名称存储在宏列表中,然后在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;

2 个答案:

答案 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

在我的情况下,我只有一个文件要处理,所以我确信这可以在你的情况下简化,但它应该提供你需要的起点。