为什么在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 – 我只希望它能在未来演变成更“标准”的替代品。