【问题标题】:Get DataTable values from anywhere on Excel spreadsheet using OleDB/Powershell使用 OleDB/Powershell 从 Excel 电子表格的任何位置获取 DataTable 值
【发布时间】:2012-05-14 20:34:00
【问题描述】:

我有一个简单的业务需求,即设计一个“名册”电子表格,该电子表格可由 powershell 脚本读取,以提取下游流程的数据。该电子表格有一些标题,例如 FirstName、LastName、Company、StartDate。这些标头从 A1 开始并继续到 J1。电子表格是 2007 (xlsm),包含 1 个带有格式化表格 (DataTable?) 的工作表。 DataTable 的右侧是一些字段,例如 NumberOfRecords 和 ContactInfo。

到目前为止,只要 DataTable 是第一列/行,powershell 脚本就可以正常工作。如果我将 NumberOfRecords & ContactInfo 字段切换到上方或左侧,那么它会打乱整个记录读取顺序。

下面是当前脚本

function getData {
$excelPath = "c:\temp\Roster.xlsm"
$global:roster = @()

$conn = new-object System.Data.OleDb.OleDbConnection
$conn.ConnectionString = 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+$excelPath+';Extended Properties="Excel 12.0 Xml;HDR=YES";'

$cmd = new-object System.Data.OleDb.OleDbCommand("SELECT * FROM [Roster$] WHERE [Valid] = true",$conn)
$conn.open()

$reader = $cmd.ExecuteReader()
while ($reader.Read())
{
    $user = new-object object
    $user | add-member -MemberType NoteProperty -Name "FirstName" -Value $reader.item(1).ToString()
    $user | add-member -MemberType NoteProperty -Name "MName" -Value $reader.item(2).ToString()
    $user | add-member -MemberType NoteProperty -Name "LastName" -Value $reader.item(3).ToString()
    $user | add-member -MemberType NoteProperty -Name "Company" -Value $reader.item(6).ToString()
    $user | add-member -MemberType NoteProperty -Name $reader.GetName(8) -Value $reader.item(8).ToString()
    $global:roster += $user
}

$conn.close()

$global:roster | out-gridview
#
}

有什么方法可以直接引用这个 DataTable 吗?我知道在 Excel 2010 中将数据格式化为表格时,您可以为其命名(默认 Table1)。我可以做类似"SELECT Table1.* FROM [Roster$] WHERE [VALUE] = true" 的事情吗??

我的目标是提供一个格式良好的电子表格,通过 Powershell 从格式化表格中提取数据。

【问题讨论】:

  • 走投无路,也许这没有用,但我认为您必须在 excel 中命名数据表,而不是生成的 SQL 才能工作。为了确认,您也可以为 2007 年的数据表命名。
  • 我按照微软的例子:support.microsoft.com/kb/316934。我将表重命名为 MyNamedRange,但是当我尝试运行阅读器时,我得到:使用“0”参数调用“ExecuteReader”的异常:“Microsoft Access 数据库引擎找不到对象'MyNamedRange'。确保该对象存在并且您正确拼写了它的名称和路径名。如果“MyNamedRange”不是本地对象,请检查您的网络连接或联系服务器管理员。”我使用的查询是“SELECT * FROM [MyNamedRange]”

标签: excel powershell oledb


【解决方案1】:

我找到了一个解决方案,但它需要使用 COM 而不是 OLEDB 或 ADO。我无法使用 OLE 在线找到任何解决方案来调用命名对象。这个解决方案要好一些,因为我可以在工作表中的任何位置安排我的 DataTable,但是我不太喜欢它,因为它需要安装 Office,但基本上我可以通过创建 Excel 对象来调用对命名表的引用和然后在 ActiveSheet 上调用它的 ListObjects。这将返回包含所有列/行/范围的 DataTable。然后我需要做的就是遍历每一行和每一列来获取数据。

$excel = new-object -ComObject Excel.Application
$tmp = $excel.Workbooks.Open('c:\temp\Roster.xlsm')
$table = $excel.ActiveSheet.ListObjects | where-object { $_.DisplayName -eq "MyNamedRange" }    
$rows = $table.ListRows

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多