PowerShell открывает Excel во время выполнения сценария и аварийно завершает работу

#excel #powershell

#excel #powershell

Вопрос:

Я создал некоторый код для запуска макроса для 560 файлов Excel.

Существует небольшая проблема с кодом, кажется, что он не сохраняет файл Excel и открывает каждый файл Excel, что приводит к сбою Excel.

есть ли способ запустить макрос для этих 560 файлов в фоновом режиме и автоматически сохранить его после запуска макроса, а не сохранять его вручную?

Спасибо

Вот мой код:

 # start excel
$excel = New-Object -comobject Excel.Application

# get files
$files = Get-ChildItem 'C:UsersMEDesktopTEST'

# loop through all files in the directory
ForEach ($file in $files){

    # open the file
    $workbook = $excel.Workbooks.Open($file.FullName)

    # make file visible
    $excel.Visible = $true

    # run macro
    $app = $excel.Application
    $app.run("PERSONAL.xlsb!Module6.MyMacro")
}
 

Комментарии:

1. Работает ли это при первом запуске? COM-объект может быть сложным и аварийно завершиться после первого запуска, если вы не завершите экземпляр COM-объекта. Кроме того, вы можете сохранить книгу таким образом $workbook.SaveAs($file)

Ответ №1:

При настройке $excel.Visible = $true код станет намного медленнее из-за всех задействованных обновлений экрана.

Кроме того, вы не сохраняете рабочую книгу после выполнения кода, и поскольку вы никогда не выходите из Excel и не удаляете COM-объекты из памяти, в конечном итоге это приведет к сбою из-за нехватки ресурсов.

Попробуйте:

 # start excel
$excel = New-Object -comobject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false

# get files and loop through the list
# the usual extension for macro-enabled Excel files is `*.xlsm`.
# if your files have this extension, add -Filter '*.xlsm' to the 
# Get-ChildItem command below.
Get-ChildItem -Path 'C:UsersMEDesktopTEST' -File | ForEach-Object {
    # open the file
    $workbook = $excel.Workbooks.Open($_.FullName)

    # run macro
    $app = $excel.Application
    $app.run("PERSONAL.xlsb!Module6.MyMacro")
    $workbook.Close($true)  # $true --> save changes
}

$excel.Quit()

# cleanup COM objects
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()