Question
Ecriture dans excel très lente
- Leloup
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 13
- Remerciements reçus 0
il y a 10 ans 3 mois #21501
par Leloup
Ecriture dans excel très lente a été créé par Leloup
Bonjour,
J'ai fait un script pour pinger une range d’adresse.
Pour une question de présentation j'ai voulut mettre le résultat dans un fichier Excel pour éviter les multiples manipulations pour l'utilisateur en cas d'output en CSV... surtout si on fait 20-30 pings ça fait 20-30 CSV à reformaté à la main. C'est pour cette raison que mon choix s'est porté sur du excel.
Le ping en lui même n'est pas le problème, je ping 1024 adresse en moins de 5 secondes.
Si j'affiche le résultat brute le temps total d’exécution du script est inférieur à 5 secondes.
Si je traite le résultat avec un CSV, le temps monte d'a peine 2 seconde.
PAR CONTRE si je traite ça avec Excel le temps d’exécution monte a:
Days : 0
Hours : 0
Minutes : 4
Seconds : 27
Milliseconds : 88
Ticks : 2670889039
TotalDays : 0,00309130675810185
TotalHours : 0,0741913621944444
TotalMinutes : 4,45148173166667
TotalSeconds : 267,0889039
TotalMilliseconds : 267088,9039
....
Je sais que le soucis vient de l'objet COM.
Donc la question est, comment puis-je contourner ce problème de lenteur?
Ci-dessous mon script:
[code:1]function New-IPRange ($start, $end)
{
# created by Dr. Tobias Weltner, MVP PowerShell
$ip1 = ([System.Net.IPAddress]$start).GetAddressBytes()
[Array]::Reverse($ip1)
$ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
$ip2 = ([System.Net.IPAddress]$end).GetAddressBytes()
[Array]::Reverse($ip2)
$ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
for ($x=$ip1; $x -le $ip2; $x++)
{
$ip = ([System.Net.IPAddress]$x).GetAddressBytes()
[Array]::Reverse($ip)
$ip -join '.'
}
}
$computers = New-IPRange 192.168.0.1 192.168.3.255
$nombrePing = 10
Function PingRange()
{
Param($Range)
$ListePingJob = @()
$FormatOutPut = @()
$SummaryIpResponseTime = @()
$resultReturn = @()
[int]$TotalIpIsResponding = 0
[int]$TotalIpIsNotResponding = 0
$i=$null
foreach ($CurrentIp in $Range)
{
$PingJob = Test-Connection $CurrentIp -Count $nombrePing -BufferSize 64 -AsJob
$tmp = New-Object PSobject -Property @{ip=$CurrentIp;
Job=$PingJob;
name=$null}
$ListePingJob += $tmp
}
Get-Job | Wait-Job | Out-Null
foreach($CurrentJob in $ListePingJob)
{
$tmp = Receive-Job $CurrentJob.Job
if ($tmp.StatusCode -eq 0 )
{
$temp = [decimal]::round(($tmp.ResponseTime | Measure-Object -Average).Average)
$OutPutCsv = New-Object psobject -Property @{Ip=$CurrentJob.ip;
Status=\"Ping OK\";
Tmm=$temp}
$SummaryIpResponseTime += $temp
$FormatOutPut += $OutPutCsv
$i++
$TotalIpIsResponding++
}
else
{
$OutPutCsv = New-Object psobject -Property @{Ip=$CurrentJob.ip;
Status=\"Ping NON-OK\";
Tmm=\"\"}
$FormatOutPut += $OutPutCsv
$i++
$TotalIpIsNotResponding++
}
Write-Host \"\"
}
Get-Job | Remove-Job
$AverageResponseTime = [decimal]::round(($SummaryIpResponseTime | Measure-Object -Average).Average)
$resultReturn += $FormatOutPut
$resultReturn += $AverageResponseTime
$resultReturn += $TotalIpIsResponding
$resultReturn += $TotalIpIsNotResponding
return $resultReturn
}
$FormatOutPut
$arrayResult = PingRange($computers)
$excel = New-Object -ComObject excel.application
$excel.Visible = $True
$excel.DisplayAlerts = $False
$workbook = $excel.Workbooks.Add()
#Remove other worksheets
#1..2 | ForEach {
# $Workbook.worksheets.item(2).Delete()}
$PingOutputExcelSheet = $workbook.Worksheets.Item(1)
$PingOutputExcelSheet.Activate() | Out-Null
$PingOutputExcelSheet.Cells.Item(1,1) = 'Resultat de la session de ping'
$MergeCells = $PingOutputExcelSheet.Range(\"a1\",\"c2\"«»)
$MergeCells.Font.ColorIndex = 17
$MergeCells.Font.Size = 22
$MergeCells.VerticalAlignment = -4108
$MergeCells.HorizontalAlignment = -4108
$MergeCells.BorderAround(1,-4138,0)
$MergeCells.Interior.Color = ([System.Drawing.Color]::FromArgb(242,242,242)).ToArgb()
$PingOutputExcelSheet.Range(\"a5\",\"c500\"«»).VerticalAlignment = -4108
$PingOutputExcelSheet.Range(\"a5\",\"c500\"«»).HorizontalAlignment = -4108
$PingOutputExcelSheet.Range(\"a5\",\"c5\"«»).BorderAround(1,-4138,0)
$PingOutputExcelSheet.Range(\"a5\",\"c5\"«»).Interior.Color = ([System.Drawing.Color]::FromArgb(242,242,242)).ToArgb()
$PingOutputExcelSheet.Cells.Item(5,1) = 'IP'
$PingOutputExcelSheet.Cells.Item(5,2) = 'Status'
$PingOutputExcelSheet.Cells.Item(5,3) = 'Temps moyen'
$excel.Columns.Item(1).columnWidth = 25
$excel.Columns.Item(2).columnWidth = 25
$excel.Columns.Item(3).columnWidth = 25
$MergeCells.MergeCells = $true
$starttime = Get-Date
$i = 5
foreach($currentIP in $arrayResult)
{
$i++
if ($currentIP.Status -eq \"Ping OK\"«»)
{
$PingOutputExcelSheet.Cells.Item($i,1) = $currentIP.IP
$PingOutputExcelSheet.Cells.Item($i,2) = 'Hôte joignable'
$PingOutputExcelSheet.Cells.Item($i,3) = $currentIP.Tmm
Write-Host -BackgroundColor green -ForegroundColor White \"$($currentIP.IP) :\"
Write-Host -BackgroundColor green -ForegroundColor White \"Ping OK\"
Write-Host -BackgroundColor green -ForegroundColor White \"Temps moyens sur $nombrePing ping(s) : $($currentIP.Tmm)\"
Write-Host \"\"
}
elseif ($currentIP.Status -eq \"Ping NON-OK\"«»)
{
$PingOutputExcelSheet.Cells.Item($i,1) = $currentIP.IP
$PingOutputExcelSheet.Cells.Item($i,2) = 'Hôte KO'
$PingOutputExcelSheet.Cells.Item($i,3) = \"N/A\"
Write-Host -BackgroundColor Red -ForegroundColor Yellow \"$($currentIP.IP) :\"
Write-Host -BackgroundColor Red -ForegroundColor Yellow \"Ping NON-OK\"
Write-Host \"\"
}
}
(Get-Date) - $starttime
[/code:1]
J'ai fait un script pour pinger une range d’adresse.
Pour une question de présentation j'ai voulut mettre le résultat dans un fichier Excel pour éviter les multiples manipulations pour l'utilisateur en cas d'output en CSV... surtout si on fait 20-30 pings ça fait 20-30 CSV à reformaté à la main. C'est pour cette raison que mon choix s'est porté sur du excel.
Le ping en lui même n'est pas le problème, je ping 1024 adresse en moins de 5 secondes.
Si j'affiche le résultat brute le temps total d’exécution du script est inférieur à 5 secondes.
Si je traite le résultat avec un CSV, le temps monte d'a peine 2 seconde.
PAR CONTRE si je traite ça avec Excel le temps d’exécution monte a:
Days : 0
Hours : 0
Minutes : 4
Seconds : 27
Milliseconds : 88
Ticks : 2670889039
TotalDays : 0,00309130675810185
TotalHours : 0,0741913621944444
TotalMinutes : 4,45148173166667
TotalSeconds : 267,0889039
TotalMilliseconds : 267088,9039
....
Je sais que le soucis vient de l'objet COM.
Donc la question est, comment puis-je contourner ce problème de lenteur?
Ci-dessous mon script:
[code:1]function New-IPRange ($start, $end)
{
# created by Dr. Tobias Weltner, MVP PowerShell
$ip1 = ([System.Net.IPAddress]$start).GetAddressBytes()
[Array]::Reverse($ip1)
$ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
$ip2 = ([System.Net.IPAddress]$end).GetAddressBytes()
[Array]::Reverse($ip2)
$ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
for ($x=$ip1; $x -le $ip2; $x++)
{
$ip = ([System.Net.IPAddress]$x).GetAddressBytes()
[Array]::Reverse($ip)
$ip -join '.'
}
}
$computers = New-IPRange 192.168.0.1 192.168.3.255
$nombrePing = 10
Function PingRange()
{
Param($Range)
$ListePingJob = @()
$FormatOutPut = @()
$SummaryIpResponseTime = @()
$resultReturn = @()
[int]$TotalIpIsResponding = 0
[int]$TotalIpIsNotResponding = 0
$i=$null
foreach ($CurrentIp in $Range)
{
$PingJob = Test-Connection $CurrentIp -Count $nombrePing -BufferSize 64 -AsJob
$tmp = New-Object PSobject -Property @{ip=$CurrentIp;
Job=$PingJob;
name=$null}
$ListePingJob += $tmp
}
Get-Job | Wait-Job | Out-Null
foreach($CurrentJob in $ListePingJob)
{
$tmp = Receive-Job $CurrentJob.Job
if ($tmp.StatusCode -eq 0 )
{
$temp = [decimal]::round(($tmp.ResponseTime | Measure-Object -Average).Average)
$OutPutCsv = New-Object psobject -Property @{Ip=$CurrentJob.ip;
Status=\"Ping OK\";
Tmm=$temp}
$SummaryIpResponseTime += $temp
$FormatOutPut += $OutPutCsv
$i++
$TotalIpIsResponding++
}
else
{
$OutPutCsv = New-Object psobject -Property @{Ip=$CurrentJob.ip;
Status=\"Ping NON-OK\";
Tmm=\"\"}
$FormatOutPut += $OutPutCsv
$i++
$TotalIpIsNotResponding++
}
Write-Host \"\"
}
Get-Job | Remove-Job
$AverageResponseTime = [decimal]::round(($SummaryIpResponseTime | Measure-Object -Average).Average)
$resultReturn += $FormatOutPut
$resultReturn += $AverageResponseTime
$resultReturn += $TotalIpIsResponding
$resultReturn += $TotalIpIsNotResponding
return $resultReturn
}
$FormatOutPut
$arrayResult = PingRange($computers)
$excel = New-Object -ComObject excel.application
$excel.Visible = $True
$excel.DisplayAlerts = $False
$workbook = $excel.Workbooks.Add()
#Remove other worksheets
#1..2 | ForEach {
# $Workbook.worksheets.item(2).Delete()}
$PingOutputExcelSheet = $workbook.Worksheets.Item(1)
$PingOutputExcelSheet.Activate() | Out-Null
$PingOutputExcelSheet.Cells.Item(1,1) = 'Resultat de la session de ping'
$MergeCells = $PingOutputExcelSheet.Range(\"a1\",\"c2\"«»)
$MergeCells.Font.ColorIndex = 17
$MergeCells.Font.Size = 22
$MergeCells.VerticalAlignment = -4108
$MergeCells.HorizontalAlignment = -4108
$MergeCells.BorderAround(1,-4138,0)
$MergeCells.Interior.Color = ([System.Drawing.Color]::FromArgb(242,242,242)).ToArgb()
$PingOutputExcelSheet.Range(\"a5\",\"c500\"«»).VerticalAlignment = -4108
$PingOutputExcelSheet.Range(\"a5\",\"c500\"«»).HorizontalAlignment = -4108
$PingOutputExcelSheet.Range(\"a5\",\"c5\"«»).BorderAround(1,-4138,0)
$PingOutputExcelSheet.Range(\"a5\",\"c5\"«»).Interior.Color = ([System.Drawing.Color]::FromArgb(242,242,242)).ToArgb()
$PingOutputExcelSheet.Cells.Item(5,1) = 'IP'
$PingOutputExcelSheet.Cells.Item(5,2) = 'Status'
$PingOutputExcelSheet.Cells.Item(5,3) = 'Temps moyen'
$excel.Columns.Item(1).columnWidth = 25
$excel.Columns.Item(2).columnWidth = 25
$excel.Columns.Item(3).columnWidth = 25
$MergeCells.MergeCells = $true
$starttime = Get-Date
$i = 5
foreach($currentIP in $arrayResult)
{
$i++
if ($currentIP.Status -eq \"Ping OK\"«»)
{
$PingOutputExcelSheet.Cells.Item($i,1) = $currentIP.IP
$PingOutputExcelSheet.Cells.Item($i,2) = 'Hôte joignable'
$PingOutputExcelSheet.Cells.Item($i,3) = $currentIP.Tmm
Write-Host -BackgroundColor green -ForegroundColor White \"$($currentIP.IP) :\"
Write-Host -BackgroundColor green -ForegroundColor White \"Ping OK\"
Write-Host -BackgroundColor green -ForegroundColor White \"Temps moyens sur $nombrePing ping(s) : $($currentIP.Tmm)\"
Write-Host \"\"
}
elseif ($currentIP.Status -eq \"Ping NON-OK\"«»)
{
$PingOutputExcelSheet.Cells.Item($i,1) = $currentIP.IP
$PingOutputExcelSheet.Cells.Item($i,2) = 'Hôte KO'
$PingOutputExcelSheet.Cells.Item($i,3) = \"N/A\"
Write-Host -BackgroundColor Red -ForegroundColor Yellow \"$($currentIP.IP) :\"
Write-Host -BackgroundColor Red -ForegroundColor Yellow \"Ping NON-OK\"
Write-Host \"\"
}
}
(Get-Date) - $starttime
[/code:1]
Connexion ou Créer un compte pour participer à la conversation.
- xyz
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 69
il y a 10 ans 3 mois #21503
par xyz
Tutoriels PowerShell
Réponse de xyz sur le sujet Re:Ecriture dans excel très lente
Salut,
dans ce cas j'utilise un fichier XL normé et je le converti en csv avant le traitement.
Sinon utilise des références directes aux 'interface' :
[code:1]
$PingOutputExcelSheet.Cells.Item()
#en
$Cells=$PingOutputExcelSheet.Cells
$Cells.Item()
[/code:1]
Cela peut améliorer les boucles, guère plus.
La v4 je crois est plus rapide
dans ce cas j'utilise un fichier XL normé et je le converti en csv avant le traitement.
Sinon utilise des références directes aux 'interface' :
[code:1]
$PingOutputExcelSheet.Cells.Item()
#en
$Cells=$PingOutputExcelSheet.Cells
$Cells.Item()
[/code:1]
Cela peut améliorer les boucles, guère plus.
La v4 je crois est plus rapide
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.036 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Ecriture dans excel très lente