2014-02-18 59 views
0

我有一個withell腳本,它創建一個excel com對象來反覆讀取* .csv文件,生成圖形,然後將圖形另存爲* .pdf文件。代碼段如下所示。腳本啓動時,每個文件需要2-4秒。腳本運行的時間越長,處理單個csv文件所需的時間越長。大約1,000個文件後,每個文件大約需要60秒。所有的csv文件都是小2列70行。當我有215個圖形生成時,大約需要12分鐘才能運行。當我有1,522個圖表時,需要20多個小時。我能做些什麼來加快速度?在powershell腳本中降低excel com對象的性能

蒂亞, 馬克K.

# 
# Create an Excell object and use it to generate the graphs. 
# 

$ex = New-Object -ComObject Excel.Application 
$chartType = "microsoft.office.interop.excel.xlChartType" -as [type] 
$xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type] 
$ex.DisplayAlerts = $False 
$ex.Visible = $False 
$wb = $ex.Workbooks.Add() 
$ws = $wb.worksheets 
$ws1 = $ws.Item(1) 

try {           # Delete unneeded worksheets, if present 
    $ws.item(3).delete() 
    $ws.item(2).delete() 
} 
catch [Exception] { 
    Out-Null 
} 

$i = 0 

foreach ($p in $pdfs) {      # $p is a csv file to be the source for a pdf 

    Try { 
     $ws1.Name = $p.Substring(0,$p.IndexOf('.')) 
     $Connector = ("text;http://xxxxxxxxxxxxx/" + $lpar + "/" + $p) 
     $CellRef = $ws1.Range("A1") 
     $Conn = $ws1.QueryTables.Add($Connector,$CellRef) 
     $ws1.QueryTables.item($Conn.name).TextFileCommaDelimiter = $True 
     $ws1.QueryTables.item($Conn.name).TextFileParseType = 1 
     $ws1.QueryTables.item($Conn.name).Refresh() | Out-Null 
     $ws2 = $ex.charts.add() 
     $ws2.chartType = $chartType::xlLine 
     $ws2.Name = $ws1.Name + " Graph" 
     $ws2.HasTitle = $True 
     $ws2.ChartTitle.Text = $ws1.Range("A1").text 
     $Data = $ws1.range("b2:b71") 
     $ws2.setSourceData($Data) | Out-Null 
     $ws2.SeriesCollection(1).XValues = $ws1.Range("A2:A71") 
     $wb.ExportAsFixedFormat($xlFixedFormat::xlTypePDF,"$drive`:\captrendGraphs\$lpar\" + $ws1.Name + ".pdf",0,$True,$True,1,1) 
     $ws2.Delete() | Out-Null 
     $ws1.UsedRange.ClearContents() | Out-Null 
    } 
    catch [Exception] { 
     Write-Host $_.Exception.toString() 
     Write-Log $($_.Exception.toString()) 
     Write-Host $_.Exception.message 
     Write-Log $($_.Exception.message) 
     Write-Host $_.Exception.source 
     Write-Log $($_.Exception.source) 
     Write-Host $_.Exception.StackTrace 
     Write-Log $($_.Exception.StackTrace) 
     Write-Host "Error occured with: " $p 
     Write-Log $("Error occured with: " + $p) 
    } 

    $i++ 
    $rptP = $("{0:D4}" -f $i + " " + $p) 
    Write-Host $rptP 
    Write-Log $rptP 
} 
+0

嘗試爲每個文件創建一個新的Com對象。這樣你可以處理文件並讓垃圾收集器清理它。否則,您將重複使用相同的會話並在內存中進行所有這些更改。 – websch01ar

+2

終止並重新創建Excel COM對象也很昂貴(就時間而言) - 在我的系統上執行100次約54秒(沒有執行其他工作)。先嚐試爲循環的每次迭代創建(和「關閉」)一個新的工作簿。 – alroc

+0

這是昂貴的原因是由於不受控制的數據增長,例如單元格格式化,撤消數據和查詢表,這些數據並沒有被處理。也可能是PowerShell在釋放COM接口指針方面效率不高,您可以直接使用'$ Conn'而不是'$ ws1.QueryTables.item($ Conn.name)'。但總的來說,你可以創建一個新的工作表並刪除以前的工作表嗎?這可能會爲您節省很多頭痛。 – acelent

回答

0

你可能打開和關閉的時間間隔(15分鐘)或圖表生成區間(每1000)中的新的Excel會話,並看看是否有幫助一些。