为什么在VBScript中快速写入Excel单元格值,但在PowerShell中速度慢?

为什么在VBScript中将单元格值写入Excel比在PowerShell中快得多? PowerShell不是新事物,而VBScript是不赞成的MS脚本语言?

VBScript的例子(保存到filename.vbs)这运行在一瞬间。

Set objExcel = CreateObject("Excel.Application") objExcel.Visible = false Set objWorkbook = objExcel.Workbooks.Add() ' Edit: increased number of writes to 500 to make speed difference more noticeable For row = 1 To 500 'Edit: using .cells(row,1) instead of .cells(50,1) - this was a mistake objWorkbook.workSheets(1).cells(row,1).value = "test" Next objWorkbook.SaveAs(CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) & "\test.xlsx") objExcel.Quit msgbox "Done." 

PowerShell示例(保存到filename.ps1)运行需要几秒钟(数千条logging存在问题)

 #need this to work around bug if you use a non-US locale: http://support.microsoft.com/default.aspx?scid=kb;en-us;320369 [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-US" $excel = New-Object -ComObject Excel.Application $excel.Visible = $False $xls_workbook = $excel.Workbooks.Add() # Edit: using foreach instead of for # Edit: increased number of writes to 500 to make speed difference more noticeable foreach ($row in 1..500) { # Edit: Commented out print-line, slows down the script #"Row " + $row # This is very slow! - http://forums.redmondmag.com/forums/forum_posts.asp?tid=4037&pn=7 $xls_workbook.sheets.item(1).cells.item($row,1) = "test" } $xls_workbook.SaveAs($MyInvocation.MyCommand.Definition.Replace($MyInvocation.MyCommand.Name, "") + "test.xlsx") $excel.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) 

我想用这个成千上万的logging。 如果没有快速的方法来做到这一点,PowerShell不是一个选项。 有更好的select吗?

你可以通过不循环单个单元格来加快速度:

 $excel = New-Object -ComObject Excel.Application $excel.Visible = $True $xls_workbook = $excel.Workbooks.Add() $range = $xls_workbook.sheets.item(1).Range("A1:A100") $range.Value2 = "test" 

如果你想写一个范围值的数组,这里是一个很好的博客文章,展示了类似的技术:

如何使用PowerShell快速获取数据到Excel电子表格中

有些东西不加在这里:

你的VBScript,一遍又一遍地写入一个单元,而你的PowerShell代码写入100个单元

 objWorkbook.workSheets(1).cells(50,1).value = "test" $xls_workbook.sheets.item(1).cells.item($row,1) = "test" 

你在PowerShell上执行"Row " + $row – 这也可能会抵消比较。

如果你想写入多个单元格,你应该考虑使用数组,并在整个范围内打字,因为这具有更好的性能。

您可以通过消除for循环testing和使用foreach来缩短PowerShell版本的一些时间。

 for ($row = 1; $row -le 100; $row++) 

去:

 foreach ($row in 1..100) 

通过这样做,您可以消除比较和增量。

但是除此之外,我的观察与你的观察相符(见我对Jook的答案的评论)。

你仍然通过COM接口与Excel。 由于COMInterop处理,这增加了一些开销。

PowerShell通过其非常的devise和使用cmdlet是一个非标准的混乱,至less对于基本的东西来说。 任何程序员都应该能够使用和理解的VBScript有一个基本的东西的一般方法,不需要特殊的cmdlets被安装或包含在部署的代码中。 我相信这在很多方面都是倒退的。

在任何人破坏我之前说我只是没有PowerShell,我必须提到我背后有很长的UNIX shell脚本历史。 PowerShell显然是相似的,但对我来说,它不是很好实施。

我知道现实意味着我最终会迟早地使用PowerShell – 我只希望它能在未来演变成更“标准”的替代品。