【问题标题】:Using Powershell to loop through Excel files and check if Spreadsheet name exists使用 Powershell 循环遍历 Excel 文件并检查电子表格名称是否存在
【发布时间】:2015-05-20 00:13:49
【问题描述】:

我正在尝试编写一个 powershell 脚本,该脚本将遍历给定目录中的每个 excel 文件,检查文件中是否有专门命名的工作表,然后将该文件复制到另一个位置(如果匹配)。

请参阅下面我已经尝试过的内容:

[void][reflection.assembly]::Loadwithpartialname("microsoft.office.excel")

$Excel = New-Object -ComObject Excel.Application
$tempLocation = "C:\Test\"     # Path to read files
$files = Get-ChildItem C:\Test

ForEach ($file in $files)
{
#Check for Worksheet named TestSheet

     $WorkBook = $Excel.Workbooks.Open($file)
     $WorkSheets = $WorkBook.WorkSheets

     foreach ($WorkSheet in $Workbook.Worksheets) {
     If ($WorkSheet.Name -eq "TestSheet")
    {$path = $tempLocation + "\" + $file
         Write "Saving $path"
         Copy-Item c:\Test\$file c:\Confirmed}
     Else {Write "$path does not contain TestSheet"}
     $WorkBook.Close()
}
}

此脚本在 PowerShell 中没有返回任何错误,但只是坐在那里而不编写任何内容或复制任何文件。有什么想法吗?

编辑:这是我现在成功运行的最终脚本

$ErrorActionPreference= 'silentlycontinue'
$tempLocation = "C:\Source"     # Path to read files
$targetlocation = "C:\Target"
Write "Loading Files..."
$files = Get-ChildItem C:\Source
Write "Files Loaded."
ForEach ($file in $files)
{
#Check for Worksheet named TestSheet
     $Excel = New-Object -ComObject Excel.Application
     $Excel.visible = $false
     $Excel.DisplayAlerts = $false
     $WorkBook = $Excel.Workbooks.Open($file.Fullname)
     $WorkSheets = $WorkBook.WorkSheets | where {$_.name -eq "TestSheet"}

     if($WorkSheets) {
     $path = $tempLocation + "\" + $file
     $dest = $targetlocation + "\" + $file
     Write "Saving $path"
     $WorkBook.SaveAs($dest)
     }
     $Excel.Quit()
     Stop-Process -processname EXCEL
}
Read-host -prompt "The Scan has completed.  Press ENTER to close..."
clear-host;

【问题讨论】:

  • 我猜没有名为 TestSheet 的工作表,因为这是脚本真正执行任何操作的唯一条件
  • 语法看起来正确吗?我正在寻找的工作表可能是“非常隐藏”的工作表。它还会被程序识别吗?感谢您的快速回复。
  • 哈,看得很清楚,你刚刚回答了你自己的问题! Powershell中的比较测试使用-eq而不是=,所以你需要:$WorkSheet.Name -eq "TestSheet"
  • @acro444,感谢您的纠错!但是,它仍然坐在那里。我什至在我的逻辑中添加了Else。请查看我更新的帖子,如果我只是想做一些愚蠢的事情,请告诉我......目录绝对正确,我正在从PS C:\> 在powershell 中执行,所以不是那样的。

标签: excel powershell


【解决方案1】:

我的脚本逻辑存在几个问题。以下脚本运行成功!花了几个小时的研究......

$ErrorActionPreference= 'silentlycontinue'
$tempLocation = "C:\Source"     # Path to read files
$targetlocation = "C:\Target"
Write "Loading Files..."
$files = Get-ChildItem C:\Source
Write "Files Loaded."
ForEach ($file in $files)
{
#Check for Worksheet named TestSheet
     $Excel = New-Object -ComObject Excel.Application
     $Excel.visible = $false
     $Excel.DisplayAlerts = $false
     $WorkBook = $Excel.Workbooks.Open($file.Fullname)
     $WorkSheets = $WorkBook.WorkSheets | where {$_.name -eq "TestSheet"}

     if($WorkSheets) {
     $path = $tempLocation + "\" + $file
     $dest = $targetlocation + "\" + $file
     Write "Saving $path"
     $WorkBook.SaveAs($dest)
     }
     $Excel.Quit()
     Stop-Process -processname EXCEL
}
Read-host -prompt "The Scan has completed.  Press ENTER to close..."
clear-host;

【讨论】:

  • 这是低效的。您不想为每个文件打开和关闭 Excel;您只想关闭和打开工作簿。
  • 好收获。您将如何更新脚本以确保它打开和关闭工作簿而不是整个程序?谢谢!
  • 在进入循环之前,将ForEach 循环中的前三个非注释行移到外部;然后在退出循环后将ForEach 循环中的最后两行移到外面。算法是 1)在进入循环之前打开 Excel 2)循环:打开工作簿然后关闭工作簿 3)退出循环并退出 Excel。您只需要一个您不想每次都重新创建它的 ComObject。
  • 另外,我不确定您是否处理宏工作簿,但我喜欢将 VBA 设置为关闭 $Excel.AutomationSecurity = [Microsoft.Office.Core.MsoAutomationSecurity]::msoAutomationSecurityForceDisable。打开工作簿的处理时间更短。
  • @MadTomVane,好建议。是的,它们启用了宏。所以这也是一个很好的调整。
【解决方案2】:

你不需要这一行:

[void][reflection.assembly]::Loadwithpartialname("microsoft.office.excel")

($Excel = New-Object -ComObject Excel.Application 这里就足够了)

我认为您引用的不是 Excel 文件的完整路径。尝试修改这一行:

$WorkBook = $Excel.Workbooks.Open($file)

修改为:

$WorkBook = $Excel.Workbooks.Open($file.Fullname)

另外,可以考虑给你的Get-ChildItem命令加个过滤器,如果有子目录或者非Excel文件,会报错:

$files = Get-ChildItem C:\Test -filter "*.xls"

【讨论】:

  • 谢谢,@nimizen。我会试一试。这是一个包含 10,000 多个文件的文件夹,因此可能需要一分钟才能开始......也许我太不耐烦了。
  • 嘿,@nimizen。 PowerShell 仍然只是坐在那里......我已经等了一个多小时,它还没有写出任何结果。还有其他想法吗?谢谢!
猜你喜欢
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 2021-02-20
  • 1970-01-01
相关资源
最近更新 更多