我正在研究一个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)
答案 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; }