【问题标题】:Quick way to determine the names of the sheets of an Excel file using SAS?使用 SAS 确定 Excel 文件工作表名称的快速方法?
【发布时间】:2020-12-10 13:29:08
【问题描述】:

在没有including the Excel-file as library 的情况下,有没有快速确定 Excel 文件中 Excel 工作表名称的方法?我只需要一个包含所有工作表名称的数组,而不是工作表本身的数据,理想情况下我可以模拟如下形式:

%let my_sheet_names = Sheet1 Sheet2 Sheet5; /* Assuming that there are no spaces in the tab sheet names */
%let my_sheet_number = 3;

背景

我有一个巨大的 XLSX 文件,我必须从中提取几张纸上的几个单元格。没错,我将它们转换为 XLS,以便以下(历史)结构起作用:

%do i=1 %to &my_sheet_number.;
   %let my_sheet = %scan(&my_sheet_names.,&i.);
   proc import 
        data= &full_path.;
        dbms= xls   out=work.raw_value replace;
        getnames=NO;
        range="&mysheet.$E1:E1";
   run;
   proc sql noprint;
        select * into :tmp;
        from work.raw_value;
   quit;
   /* Do something with &tmp.; */
     
%end;

我需要预先提供 Excel 工作表 all_sheets 的整体列表,以便找到 all_sheets 与另一个列表 chosen_sheets 的交集,然后从上面是 my_sheet_names,包含我想要循环的工作表.如果我可以直接提取单元格,那么阅读包含所有工作表的完整 XLS(X) 对我来说听起来不太实用。

参考文献

相关,但不能解决我的问题:

【问题讨论】:

  • 您有 XLSX 文件或旧的 XLS 文件或其他类型的 Excel 文件吗?
  • 现在是 XLS,但如果您能详细说明这两个问题,那就太好了。
  • XLSX 文件会更容易,因为您可以使用 XLSX libname 引擎,甚至只需从文件中提取带有工作表列表的 XML 文件并读取它。无需 Microsoft 工具。
  • @Tom 我可以将它转换回 XLSX,但问题是历史结构(我刚刚编辑到问题中)将停止工作。

标签: excel sas


【解决方案1】:

您是否有不能使用LIBNAME MyData EXCEL "<filename>"; 的原因?

LIBNAME 只创建一个 LIBREF,它是一个指向数据源的昵称。一个库的成员可以在Proc SQL使用DICTIONARY.TABLES获得

例子:

* create a sample workbook that has several sheets (one per name);

ods excel file='sandbox.xlsx' options(sheet_name="#BYVAL1");

options nobyline;
ods noresults; /* prevent automatic opening when destination closed */

proc print data=sashelp.class;
  by name;
run;

ods excel close;

/*
 * Determine sheet names from DICTIONARY.TABLES
 * The metadata for a sheet name is the value in MEMNAME column
 * The memnames have trailing dollar sign ($)
 * The $ should be familiar to Excel users that understand
 *   <workbook>!<sheetname>$<cell-reference> syntax
 */

libname students EXCEL 'sandbox.xlsx';

proc sql;
  reset noprint;
  select compress(memname,'$') into :SHEET_NAMES separated by ' '
  from dictionary.tables
  where libname = "STUDENTS"
  ;

libname students;

%put &=SHEET_NAMES;

日志

SHEET_NAMES=Alfred Alice Barbara Carol Henry James Jane Janet Jeffrey John Joyce Judy Louise Mary
Philip Robert Ronald Thomas William

【讨论】:

  • 我想我会选择这个选项。
  • 为了清楚起见,任何 DMBS 类型都应该使用这种方法 - 所以 LIBNAME XLS [a libname] [your excel path];如果这是您喜欢做事的方式,应该也可以正常工作。这会让你做你已经在做的 RANGE 事情。 (我认为 LIBNAME EXCEL 也可以让你做类似的事情,不过,如果你将范围命名为 in excel,则使用 [RANGE]$。)
  • 是的,我想使用 Excel 中的范围名称。感谢您的帮助!
【解决方案2】:

如果您打算以这种方式使用 Excel 文件,您可能需要考虑 SAS Add-In for Microsoft Office,它包含在某些 SAS 软件包中(通常是“BI”服务器类型的软件包,或者我认为是 Office Analytics 软件包) .这允许您在 excel 中运行 SAS 代码,从而更轻松地处理来自单个单元格的数据。

如果您不走那条 路线,您可能需要考虑“查看”excel 工作表或工作簿。那将是一本参考您想要的位的工作簿,其结构以 SAS 更容易阅读的方式。

想象一下,如果您有一个包含三张工作表(SHEET1、SHEET2 和 SHEET3)的工作簿,并且您需要 SHEET1!A1、SHEET2!B4 和 SHEET3!C3。然后,您可以制作一张新工作表 SHEET4,其中:

A1 = 'Q1 Data'
B1 = SHEET1!A1 
A2 = 'Q2 Data'
B2 = SHEET2!B4
A3 = 'Q3 Data'
B3 = SHEET3!C3

然后您只需导入 SHEET4,您就拥有了所有数据 - 即使数据发生更改,它仍然有效。

这将是一个很好的解决方案,例如,如果您有每周或任何数据转储,并且总是想要相同的单元格,但工作簿发生了变化。您可以拥有一个使用 excel 公式确定每周适合的工作簿的工作簿,然后通过引用将所有数据填充到单个工作表中。然后,您只需每周导入该工作簿,即可获得正确的数据。您可能需要手动干预 - 刷新单个工作簿中的数据连接;我不确定 SAS 是否会在导入时强制执行该操作 - 但使用脚本语言和/或 Excel (VBA) 宏以编程方式执行此操作相对容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多