Вы используете в коде запутанные имена переменных. Зачем называть исходный путь $destination
??
В любом случае, вы должны использовать переключатель -File
в командлете Get-ChildItem
, чтобы убедиться, что будет возвращать только объекты FileInfo, а не объекты DirectoryInfo. (это Объекты , а не строки)
Тогда есть лучший способ построения путей. Используйте Join-Path вместо объединения таких вещей, как $destination + $z
.
Наконец, я бы создал объект Excel только один раз, до l oop и после очистки памяти. Теперь вы создаете новые COM-объекты на каждой итерации и никогда не освобождаете их из памяти.
Ниже код должен делать то, что вы намерены:
$source = "C:\JJ"
$destination = Join-Path -Path $source -ChildPath 'new'
# test if the destination path already exists and if not, create it
if (!(Test-Path -Path $destination -PathType Container)) {
$null = New-Item -Path $destination -ItemType Directory
}
# create the Excel COM object outside the loop
$excel = New-Object -ComObject Excel.Application
$excel.visible = $false
$excel.DisplayAlerts = $false
# get all *.xlsm files inside the source folder
Get-ChildItem -Path $source -Filter '*.xlsm' -File | ForEach-Object {
# The $_ automatic variable represents 1 FileInfo object in each iteration
$book = $excel.Workbooks.Open($_.FullName)
$sheet = $book.Worksheets.item(1)
$sheet.Cells.Item(1,5) = "=max(B2:B6)"
# join the destination path and the file name for output
$saveAs = Join-Path -Path $destination -ChildPath $_.Name
$book.SaveAs($saveAs)
$book.Close()
}
# cleanup Com objects
$excel.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
$excel = $null
Примечание. Если у вас версия PowerShell ниже 3.0 переключатель -File
недоступен. Вместо этого используйте
Get-ChildItem -Path $source -Filter '*.xlsm' | Where-Object {!$_.PSIsContainer} | ForEach-Object { ... }