2015-05-01 3 views
1

У меня есть цикл ForEach в сценарии PowerShell, который пытается пропустить каждый файл, который был создан в папке за последние 2 часа. Он будет принимать каждый файл, удалять определенные столбцы и строки и оставит только один столбец с заголовком ActiveFaults. Затем он сортирует/группирует и форматирует, и даст мне строку ActiveFault для каждого файла.Ручные рабочие листы в PowerShell ForEach loop

Результат моего сценария - это то, что мне нужно, но он занимает много времени для обработки. Есть ли более эффективный способ сделать это? Кроме того, время от времени, он дает мне ошибку, говоря, что «объект не содержит метод Workbooks.Open()» ... Любые идеи о том, почему это так? И почему этот вопрос будет прерывистым? Заранее спасибо.

$PathMX1005 = "\source" 
filesMX1005 = Get-ChildItem $PathMX1005 -recurse -include *1Hz*.csv | Where { $_.CreationTime -ge [datetime]::Now.AddMinutes(-180) } 

Copy-Item $filesMX1005 \destination -Recurse 

$files2MX1005 = Get-ChildItem \destination -Recurse 

foreach($file in $files2MX1005) { 

    $Excel = New-Object -ComObject excel.application 
    $Excel.visible = $false 
    $Workbook = $Excel.Workbooks.open($file.FullName) 
    $range = $Workbook.ActiveSheet.Range("A1:FZ1").EntireColumn 
    $range2 = $Workbook.ActiveSheet.Range("A1:A34").EntireRow 
    $range.Delete() 
    $range2.Delete() 
    $Excel.DisplayAlerts=$False 
    $Workbook.SaveAs("c:\StrippedHeader.csv") 

    $FaultsMX1005 = Import-CSV ":\StrippedHeader.csv" | Group-Object ActiveFaults | foreach-object { $_.group | select -last 1} | Out-String 

    $Excel.Workbooks.Close() 
    $Excel.Quit() 
+0

'$ files2MX1005' не фильтрует документы Excel, это моя первая проблема. Также нет необходимости продолжать ком-объект '$ Excel = New-Object -ComObject excel.application', чтобы он мог запускать эту строку один раз _outside_ в цикле. Это на самом деле просто файлы csv? нам не нужно использовать объект com для них. Я не вижу, что вы заполняете '$ FaultsMX1005', и вам не хватает закрывающей скобки из' ForEach' – Matt

ответ

0

Я вижу, у вас есть .csv в вашем коде несколько раз, что заставляет меня думать, что вам не нужно использовать в Excel COM объект на всех.

Итак, для начала мы меняем $files2MX1005, поэтому он фильтрует только файлы csv, и мы используем Import-CSV для каждого из этих файлов. Если у вас есть столбец с именем ActiveFaults, мы можем просто выбрать его и продолжить.

$files2MX1005 = Get-ChildItem C:\temp\files -Recurse -Filter *.csv 

foreach($file in $files2MX1005){ 
    $ActiveFaults = Import-CSV $file | Select ActiveFaults 
    # Further process $ActiveFaults 
} 

Я не уверен, что еще вы делаете с этими данными, но я думаю, что это будет прогресс вперед для вас.

+0

Привет, Matt, Спасибо за ваш ответ. Каждый из этих CSV составляет 5000 строк по 300 столбцов, импорт которых занимает очень много времени, поэтому я открываю excel и удаляю строки/столбцы перед импортом. Разве это не имеет смысла? Есть ли лучший способ сделать это? –

+0

@CarlosSousa Я не пробовал настольную маркировку кода Excel по сравнению с этим методом, поэтому я не уверен, что быстрее. Хотя это действительно похоже на множество данных, я работал с большими CSV с хорошей эффективностью. Сначала попробуйте, и, возможно, вы быстрее. Было просто неэффективно использовать excel для данных csv. – Matt

+0

, так как Import-CSV считывает весь файл в память, было бы лучше использовать чтение потокового считывателя по строкам. –

Смежные вопросы