Powershell:编辑Excel文件非常慢

时间:2014-02-21 13:36:33

标签: performance excel powershell

我正在研究一个powershell脚本,它检查特定行中的excel值,如果值与数组匹配,它应该在它旁边写一些文本。

脚本正在运行,但它非常慢,因为它必须检查超过5000个值。 我希望你们中的一些人可以帮我加速我的剧本?也许我做错了什么......我还是个初学者。

#Open Excel File
#------------------------------------

$xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault

$xl = New-Object -comobject "excel.application"
$xl.visible = $false
$xl.DisplayAlerts = $false

$WorkBook = $xl.WorkBooks.Open("C:\test.xls")



#Definition Variables
#------------------------------------

$arrayCheckCell = @(
"Test 1", <# 1 #>
"Test 2", <# 2 #>
"Test 3", <# 3 #>
"Test 4", <# 4 #>
"Test 5", <# 5 #>
"Test 6", <# 6 #>
"Test 7", <# 7 #>
"Test 8", <# 8 #>
"Test 9"  <# 9 #>
) 

$ArrayInsertText = @(
"Some Text 1", <# 1 #>
"Some Text 2", <# 2 #>
"Some Text 3", <# 3 #>
"Some Text 4", <# 4 #>
"Some Text 5", <# 5 #>
"Some Text 6", <# 6 #>
"Some Text 7", <# 7 #>
"Some Text 8", <# 8 #>
"Some Text 9" <# 9 #>

)

[int]$rowC = 3
[int]$line = 2

$arrayCheckCellCount = $arrayCheckCell.Count


#Check values in row C and insert text in row D
#---------------------------------------------------


for ($i = 1; $i -lt 5000 ; $i++) 
{

    for ($i2=0; $i2 -lt $arrayCheckCellCount ; $i2++) 
    {

                if ($xl.cells.item($line, $rowC).Text -match $arrayCheckCell[$i2]) 
                 {

                    $xl.Range("D$line").value2 = $ArrayInsertText[$i2]

                 }


    }

 $line++
}



#Other definitions
#----------------------------------
 $xl.selection.autofilter(1, "*")
 $table=$xl.ActiveSheet.ListObjects.add( 1,$xl.ActiveSheet.UsedRange,0,1)
 $xl.ActiveSheet.UsedRange.EntireColumn.AutoFit()


#Save File and kill Excel Process
#----------------------------------

$WorkBook.SaveAs("C:\test.xls", $xlFixedFormat)
$xl.Quit() 

Start-Sleep 2
$ExcelProcess = get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)

2 个答案:

答案 0 :(得分:0)

编辑:以适应键的功能匹配。
您的代码中存在一些小错误:

for ($i = 1; $i -lt 5000 ; $i++) 
{
.....
$line++
}

应该是

for ($line = 1; $line -lt 5000 ; $line++) 
{
.....
}

否则$ i变量是没有意义的,因为除了增量之外它没有被用于其他任何东西。

为了加快速度,你可以使用哈希表,这些哈希表是很多更有效的内存结构,你可以在这里找到它们:http://technet.microsoft.com/en-us/library/ee692803.aspx

使用以下代码替换#Definition Variables#Other definitions,在我的示例数据中,新代码的运行速度提高了5倍以上。

#Definition Variables
#------------------------------------

$hCell = @{}
$hCell.Add("Some Text 1","Some Text 1")
$hCell.Add("Some Text 2","Some Text 2")
$hCell.Add("Some Text 3","Some Text 3")
$hCell.Add("Some Text 4","Some Text 4")
$hCell.Add("Some Text 5","Some Text 5")
$hCell.Add("Some Text 6","Some Text 6")
$hCell.Add("Some Text 7","Some Text 7")
$hCell.Add("Some Text 8","Some Text 8")
$hCell.Add("Some Text 9","Some Text 9")
$hCell.Add("Some Text 10","Some Text 10")


[int]$rowC = 3
[int]$line = 2

$arrayCheckCellCount = $arrayCheckCell.Count


#Check values in row C and insert text in row D
#---------------------------------------------------

$k = $hCell.Keys
for ($line = 1; $line -lt 5000 ; $line++) 
{
                if ($k -match ($xl.cells.item($line, $rowC).Text)) 
             {

                $xl.Range("D$line").value2 = $hCell.Item($xl.cells.item($line, $rowC).Text)

             }

}



#Other definitions
#----------------------------------

答案 1 :(得分:0)

您正在检查5000 * 9(arrayCheckCell)字段。在我的测试中,每组9或5000 * 1.75秒我得到1.75秒。

你真的需要检查5000个字段吗?

我过去做过的事情,当我不知道我需要检查一行或一列中有多少字段时,我设置了空字段的最大限制(例如'5')。如果我击中5个空白区域,我会爆发。

例如:

if ([string]::IsNullOrEmpty( $($xl.cells.item($line, $rowC).Text) ) 
{ $EmptyContiguousFilds++ } 
else 
{ $EmptyContiguousFilds= 0 }

if ($EmptyContiguousFilds -gt $MAXEMPTYFIELDS) { break; }