使用Powershell,我想将一些以制表符分隔的Ascii文件导入MS Excel。我使用循环来做到这一点,现在我有一个简单的解决方案:
for each file: start Excel , import tsv file, close Excel.
..假设Excel在路径中,它是Excel,Excel 2010的正确版本
现在我想切换到更高效的版本:保持excel打开。
对于每个文件:如果有的话,抓取excel的运行实例,如果没有,尝试启动excel。处理文件。保持excel开放。最后,保持打开状态(我想在脚本运行时查看excel文件,这可能需要一段时间。令人讨厌的是,在当前版本的脚本中,excel正在关闭,而我正在查看输出)。
我还没有找到一个全面的解决方案,无论是在这里还是互联网上的其他地方。 “全面”是指“异常处理”。在Powershell中,它有点令人困惑。有两种处理异常的方法:使用trap和try-catch块。
以下是我的代码,从几个互联网资源中汇总,我该如何改进?
我想将它包装在一个函数中,但COM对象作为返回值是有问题的。 ( 我想要的是“简单工厂”和“单身”的组合。)
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Excel")
try {
$excelApp = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
} catch [System.Runtime.InteropServices.COMException], [System.Management.Automation.RuntimeException]{
write-host
write-host $("TRAPPED: " + $_.Exception.GetType().FullName);
write-host $("TRAPPED: " + $_.Exception.Message);
write-host "Excel is not running, trying to start it";
$excelApp = New-Object -ComObject "Excel.Application"
if (-not $excelApp){
# excel not installed, not in path
Write-Error "Excel not running, and cannot be started, exiting."
# Todo: test if excel version is correct, e.g. english Excel 2007 or 2010., if not set outfile extension xls.
exit;
}
}
catch [System.Exception]{
write-host $("EXCEPTION: " + $_.Exception.GetType().FullName);
write-host $("EXCEPTION: " + $_.Exception.Message);c
Write-Error 'Something went wrong during creation of "Excel.Application" object, => Exit.'
exit;
}
答案 0 :(得分:0)
你问这个问题已经有一段时间了,但我遇到了同样的问题。您的代码似乎只是合理解决方案的一个很好的例子。不过,我确实质疑你的担忧。具体来说,一旦Excel运行,是否需要在函数中再次调用此例程?也就是说,一旦Excel打开,那么您可以将其视为打开/关闭工作簿,访问其中的工作表以及最终$ excelApp.Quit()应用程序的服务(尽管在Powershell v1.0中。.Quit()赢了退出应用程序......但是没关系,因为我正在抓取一个正在运行的实例。
下面的链接讨论了一种启动和获取Excel实例的PID的方法,以便在需要时明确地将其删除。
答案 1 :(得分:0)
所有变量必须为null。 Excel.Workbooks - 全部打开的书。 检查工作簿的数量。如果count = 0,则退出。关闭Powershell后,Excel也将关闭。
$Workbook.Close()
$WorkSheet = $null;
$Workbook = $null;
If($excelApp.Workbooks.Count -eq 0)
{$excelApp.Quit()}
$excelApp = $null;