Skip to content

Instantly share code, notes, and snippets.

@eugrus
Last active September 9, 2025 16:52
Show Gist options
  • Select an option

  • Save eugrus/8e80bff589ba8bb03990cc113f41513b to your computer and use it in GitHub Desktop.

Select an option

Save eugrus/8e80bff589ba8bb03990cc113f41513b to your computer and use it in GitHub Desktop.
Copying Word styles between documents
#Requires -Version 5.1
<#
.SYNOPSIS
Копирует все стили из одного документа Word в другой.
.DESCRIPTION
Этот скрипт открывает два документа Word: документ-донор и целевой документ.
Затем он копирует все стили из донора в целевой документ, перезаписывая существующие стили с теми же именами.
Для работы скрипта требуется, чтобы на компьютере был установлен Microsoft Word.
.PARAMETER SourcePath
Обязательный. Укажите путь к документу Word, из которого нужно скопировать стили (донор).
.PARAMETER TargetPath
Обязательный. Укажите путь к документу Word, в который нужно скопировать стили (целевой).
.EXAMPLE
.\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx"
Эта команда скопирует все стили из файла "Donor.docx" в файл "Target.docx".
.NOTES
Автор: Gemini
Версия: 1.0
#>
param(
[Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx)")]
[string]$SourcePath,
[Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx)")]
[string]$TargetPath
)
# Проверка существования файлов
if (-not (Test-Path -Path $SourcePath -PathType Leaf)) {
Write-Error "Файл-донор не найден по указанному пути: $SourcePath"
Exit 1
}
if (-not (Test-Path -Path $TargetPath -PathType Leaf)) {
Write-Error "Целевой файл не найден по указанному пути: $TargetPath"
Exit 1
}
# Попытка создать COM-объект Word.Application
try {
$wordApp = New-Object -ComObject Word.Application -ErrorAction Stop
}
catch {
Write-Error "Не удалось запустить Microsoft Word. Убедитесь, что он установлен на этом компьютере."
Exit 1
}
# Сделаем Word невидимым для пользователя
$wordApp.Visible = $false
Write-Host "Открытие документов..."
# Открытие документов
try {
# Получение полных путей к файлам
$sourceDocPath = (Resolve-Path -Path $SourcePath).Path
$targetDocPath = (Resolve-Path -Path $TargetPath).Path
$sourceDoc = $wordApp.Documents.Open($sourceDocPath, $false, $true) # Open ReadOnly
$targetDoc = $wordApp.Documents.Open($targetDocPath)
}
catch {
Write-Error "Произошла ошибка при открытии документов. Убедитесь, что пути верны и файлы не повреждены."
# Закрытие Word в случае ошибки
$wordApp.Quit([ref]$false) # Не сохранять изменения
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($wordApp) | Out-Null
Exit 1
}
Write-Host "Копирование стилей из '$($sourceDoc.Name)' в '$($targetDoc.Name)'..."
try {
# Основная операция: копирование стилей
# Метод CopyStylesFromTemplate() принимает путь к шаблону или документу.
$targetDoc.CopyStylesFromTemplate($sourceDoc.FullName)
Write-Host "Стили успешно скопированы." -ForegroundColor Green
}
catch {
Write-Error "Не удалось скопировать стили. Ошибка: $($_.Exception.Message)"
}
finally {
# Закрытие документов и приложения Word
Write-Host "Закрытие документов и выход из Word..."
# Сохранение и закрытие целевого документа
$targetDoc.Close($true) # Сохранить изменения
# Закрытие документа-донора без сохранения
$sourceDoc.Close($false)
# Завершение процесса Word
$wordApp.Quit()
# Освобождение COM-объектов из памяти
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($sourceDoc) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($targetDoc) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($wordApp) | Out-Null
}
Write-Host "Операция завершена."
#Requires -Version 5.1
<#
.SYNOPSIS
Копирует определенный стиль из одного документа Word в другой.
.DESCRIPTION
Этот скрипт открывает два документа Word: документ-донор и целевой документ.
Затем он копирует один указанный стиль из донора в целевой документ, перезаписывая существующий стиль с тем же именем.
Для работы скрипта требуется, чтобы на компьютере был установлен Microsoft Word.
.PARAMETER SourcePath
Обязательный. Укажите путь к документу Word, из которого нужно скопировать стиль (донор).
.PARAMETER TargetPath
Обязательный. Укажите путь к документу Word, в который нужно скопировать стиль (целевой).
.PARAMETER StyleName
Обязательный. Имя стиля, который нужно скопировать.
.EXAMPLE
.\Copy-SingleWordStyle.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" -StyleName "Заголовок 1"
.NOTES
Автор: Modified script
Версия: 3.0
#>
param(
[Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx)")]
[string]$SourcePath,
[Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx)")]
[string]$TargetPath,
[Parameter(Mandatory=$true, HelpMessage="Имя стиля для копирования")]
[string]$StyleName
)
function Release-ComObject([ref]$comObject) {
if ($comObject.Value) {
try { [System.Runtime.Interopservices.Marshal]::ReleaseComObject($comObject.Value) | Out-Null } catch {}
$comObject.Value = $null
}
}
# Проверка существования файлов
if (-not (Test-Path -Path $SourcePath -PathType Leaf)) {
Write-Error "Файл-донор не найден по указанному пути: $SourcePath"
Exit 1
}
if (-not (Test-Path -Path $TargetPath -PathType Leaf)) {
Write-Error "Целевой файл не найден по указанному пути: $TargetPath"
Exit 1
}
# Попытка создать COM-объект Word.Application
try {
$wordApp = New-Object -ComObject Word.Application -ErrorAction Stop
}
catch {
Write-Error "Не удалось запустить Microsoft Word. Убедитесь, что он установлен на этом компьютере."
Exit 1
}
$wordApp.Visible = $false
$sourceDoc = $null
$targetDoc = $null
$tempDoc = $null
$tempPath = $null
try {
# Открытие документов
$sourceDoc = $wordApp.Documents.Open((Resolve-Path $SourcePath).Path, $false, $true) # ReadOnly
$targetDoc = $wordApp.Documents.Open((Resolve-Path $TargetPath).Path)
# Проверка существования стиля в исходном документе
$sourceStyle = $null
foreach ($style in $sourceDoc.Styles) {
if ($style.NameLocal -eq $StyleName) {
$sourceStyle = $style
break
}
}
if (-not $sourceStyle) {
throw "Стиль '$StyleName' не найден в документе-доноре."
}
Write-Host "Копирование стиля '$StyleName' из '$($sourceDoc.Name)' в '$($targetDoc.Name)'..."
# Создаем временный документ для копирования одного стиля
$tempDoc = $wordApp.Documents.Add()
$tempPath = "$env:TEMP\temp_style_copy_$(Get-Date -Format 'yyyyMMdd_HHmmss').docx"
$sourceDoc.SaveAs2($tempPath)
$tempDoc.Close($false)
Release-ComObject ([ref]$tempDoc)
# Открываем временную копию
$tempDoc = $wordApp.Documents.Open($tempPath)
# Удаляем все стили, кроме нужного
foreach ($style in $tempDoc.Styles) {
if ($style.NameLocal -ne $StyleName) {
try { $style.Delete() } catch {}
}
}
$tempDoc.Save()
$targetDoc.CopyStylesFromTemplate($tempDoc.FullName)
Write-Host "Стиль '$StyleName' успешно скопирован." -ForegroundColor Green
}
catch {
Write-Error "Ошибка: $($_.Exception.Message)"
}
finally {
Write-Host "Закрытие документов и выход из Word..."
# Закрытие временного документа
if ($tempDoc) {
try { $tempDoc.Close($false) } catch {}
Release-ComObject ([ref]$tempDoc)
}
# Закрытие целевого документа (с сохранением)
if ($targetDoc) {
try { $targetDoc.Close($true) } catch {}
Release-ComObject ([ref]$targetDoc)
}
# Закрытие документа-донора
if ($sourceDoc) {
try { $sourceDoc.Close($false) } catch {}
Release-ComObject ([ref]$sourceDoc)
}
# Завершение процесса Word
if ($wordApp) {
try { $wordApp.Quit() } catch {}
Release-ComObject ([ref]$wordApp)
}
# Удаление временного файла
if ($tempPath -and (Test-Path $tempPath)) {
Remove-Item $tempPath -ErrorAction SilentlyContinue
}
}
Write-Host "Операция завершена."
#Requires -Version 5.1
<#
.SYNOPSIS
Копирует один или несколько стилей из одного документа Word в другой.
.DESCRIPTION
Этот скрипт открывает два документа Word: документ-донор и целевой документ.
Затем он копирует указанные стили из донора в целевой документ, перезаписывая существующие стили с теми же именами.
.PARAMETER SourcePath
Путь к документу Word, из которого нужно скопировать стили (донор).
.PARAMETER TargetPath
Путь к документу Word, в который нужно скопировать стили (целевой).
.PARAMETER StyleNames
Массив имен стилей, которые нужно скопировать.
.EXAMPLE
.\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" -StyleNames "Заголовок 1","Обычный"
.NOTES
Автор: Modified script
Версия: 4.1
#>
param(
[Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx)")]
[string]$SourcePath,
[Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx)")]
[string]$TargetPath,
[Parameter(Mandatory=$true, HelpMessage="Список стилей для копирования")]
[string[]]$StyleNames
)
function Release-ComObject([ref]$comObject) {
if ($comObject.Value) {
try { [System.Runtime.Interopservices.Marshal]::ReleaseComObject($comObject.Value) | Out-Null } catch {}
$comObject.Value = $null
}
}
# Проверка файлов
foreach ($file in @($SourcePath, $TargetPath)) {
if (-not (Test-Path -Path $file -PathType Leaf)) {
Write-Error "Файл не найден: $file"
Exit 1
}
}
# Создание COM-объекта Word
try {
$wordApp = New-Object -ComObject Word.Application -ErrorAction Stop
} catch {
Write-Error "Не удалось запустить Microsoft Word."
Exit 1
}
$wordApp.Visible = $false
$sourceDoc = $null
$targetDoc = $null
$tempDoc = $null
$tempPath = $null
try {
# Открытие документов
$sourceDoc = $wordApp.Documents.Open((Resolve-Path $SourcePath).Path, $false, $true) # ReadOnly
$targetDoc = $wordApp.Documents.Open((Resolve-Path $TargetPath).Path)
# Проверка существования всех указанных стилей
$missingStyles = @()
foreach ($styleName in $StyleNames) {
if (-not ($sourceDoc.Styles | Where-Object { $_.NameLocal -eq $styleName })) {
$missingStyles += $styleName
}
}
if ($missingStyles.Count -gt 0) {
throw "Следующие стили не найдены в документе-доноре: $($missingStyles -join ', ')"
}
Write-Host "Копирование стилей: $($StyleNames -join ', ')"
# Создаем временный документ
$tempDoc = $wordApp.Documents.Add()
$tempPath = "$env:TEMP\temp_style_copy_$(Get-Date -Format 'yyyyMMdd_HHmmss').docx"
$sourceDoc.SaveAs2($tempPath)
$tempDoc.Close($false)
Release-ComObject ([ref]$tempDoc)
# Открываем временный документ (с параметрами для скрытого открытия)
$tempDoc = $wordApp.Documents.Open($tempPath, $false, $false, $false)
# Убеждаемся, что окно временного документа скрыто
$tempDoc.ActiveWindow.Visible = $false
# Удаляем все стили, кроме нужных
foreach ($style in $tempDoc.Styles) {
if ($StyleNames -notcontains $style.NameLocal) {
try { $style.Delete() } catch {}
}
}
$tempDoc.Save()
# Копирование стилей в целевой документ
$targetDoc.CopyStylesFromTemplate($tempDoc.FullName)
Write-Host "Стили успешно скопированы." -ForegroundColor Green
}
catch {
Write-Error "Ошибка: $($_.Exception.Message)"
}
finally {
Write-Host "Закрытие документов и выход из Word..."
# Закрытие временного документа
if ($tempDoc) {
try { $tempDoc.Close($false) } catch {}
Release-ComObject ([ref]$tempDoc)
}
# Закрытие целевого документа с сохранением
if ($targetDoc) {
try { $targetDoc.Close($true) } catch {}
Release-ComObject ([ref]$targetDoc)
}
# Закрытие документа-донор без сохранения
if ($sourceDoc) {
try { $sourceDoc.Close($false) } catch {}
Release-ComObject ([ref]$sourceDoc)
}
# Завершение Word
if ($wordApp) {
try { $wordApp.Quit() } catch {}
Release-ComObject ([ref]$wordApp)
}
# Удаление временного файла
if ($tempPath -and (Test-Path $tempPath)) {
Remove-Item $tempPath -ErrorAction SilentlyContinue
}
}
Write-Host "Операция завершена."
#Requires -Version 5.1
<#
.SYNOPSIS
Копирует один или несколько стилей из одного документа Word в другой.
.DESCRIPTION
Этот скрипт открывает два документа Word: документ-донор и целевой документ.
Затем он копирует указанные стили из донора в целевой документ, перезаписывая существующие стили с теми же именами.
Поддерживает форматы .docx, .dotm и .rtf.
.PARAMETER SourcePath
Путь к документу Word, из которого нужно скопировать стили (донор).
.PARAMETER TargetPath
Путь к документу Word, в который нужно скопировать стили (целевой).
.PARAMETER StyleNames
Массив имен стилей, которые нужно скопировать.
.PARAMETER Verbose
Включает подробный вывод диагностической информации.
.EXAMPLE
.\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" -StyleNames "Заголовок 1","Обычный"
.EXAMPLE
.\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Template.dotm" -TargetPath "C:\Docs\Target.docx" -StyleNames "MyStyle" -Verbose
.EXAMPLE
.\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Source.rtf" -TargetPath "C:\Docs\Target.rtf" -StyleNames "Citation"
.NOTES
Автор: Modified script
Версия: 4.4
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx/.dotm/.rtf)")]
[string]$SourcePath,
[Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx/.dotm/.rtf)")]
[string]$TargetPath,
[Parameter(Mandatory=$true, HelpMessage="Список стилей для копирования")]
[string[]]$StyleNames
)
function Release-ComObject([ref]$comObject) {
if ($comObject.Value) {
try {
$released = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($comObject.Value)
Write-Verbose "COM-объект освобожден (refcount: $released)"
} catch {
Write-Verbose "Ошибка при освобождении COM-объекта: $_"
}
$comObject.Value = $null
}
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Начало операции копирования стилей" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
# Проверка файлов
Write-Host "1. Проверка существования файлов..." -ForegroundColor Yellow
foreach ($file in @($SourcePath, $TargetPath)) {
if (-not (Test-Path -Path $file -PathType Leaf)) {
Write-Error "❌ Файл не найден: $file"
Exit 1
} else {
$fileInfo = Get-Item $file
Write-Host " ✓ Найден: $($fileInfo.Name) (размер: $([math]::Round($fileInfo.Length/1KB, 2)) КБ)" -ForegroundColor Green
}
}
# Определение расширения исходного файла для временного файла
$sourceExtension = [System.IO.Path]::GetExtension($SourcePath).ToLower()
$targetExtension = [System.IO.Path]::GetExtension($TargetPath).ToLower()
$supportedFormats = @('.docx', '.dotm', '.rtf', '.doc', '.dot')
Write-Host ""
Write-Host "2. Анализ форматов файлов..." -ForegroundColor Yellow
Write-Host " Исходный файл: $sourceExtension" -ForegroundColor Gray
Write-Host " Целевой файл: $targetExtension" -ForegroundColor Gray
if ($sourceExtension -notin $supportedFormats) {
Write-Error "❌ Неподдерживаемый формат исходного файла: $sourceExtension. Поддерживаются: $($supportedFormats -join ', ')"
Exit 1
}
if ($targetExtension -notin $supportedFormats) {
Write-Error "❌ Неподдерживаемый формат целевого файла: $targetExtension. Поддерживаются: $($supportedFormats -join ', ')"
Exit 1
}
Write-Host " ✓ Форматы файлов поддерживаются" -ForegroundColor Green
# Создание COM-объекта Word
Write-Host ""
Write-Host "3. Запуск Microsoft Word..." -ForegroundColor Yellow
try {
$wordApp = New-Object -ComObject Word.Application -ErrorAction Stop
$wordVersion = $wordApp.Version
Write-Host " ✓ Word запущен (версия: $wordVersion)" -ForegroundColor Green
Write-Verbose "Word Application ID: $($wordApp.Application.ProcessID)"
} catch {
Write-Error "❌ Не удалось запустить Microsoft Word: $_"
Exit 1
}
$wordApp.Visible = $false
$wordApp.DisplayAlerts = 0 # wdAlertsNone
Write-Verbose "Word настроен: Visible=$($wordApp.Visible), DisplayAlerts=$($wordApp.DisplayAlerts)"
$sourceDoc = $null
$targetDoc = $null
$tempDoc = $null
$tempPath = $null
try {
# Открытие документов
Write-Host ""
Write-Host "4. Открытие документов..." -ForegroundColor Yellow
Write-Host " Открытие документа-донора..." -ForegroundColor Gray
$sourceFullPath = (Resolve-Path $SourcePath).Path
Write-Verbose "Полный путь донора: $sourceFullPath"
$sourceDoc = $wordApp.Documents.Open($sourceFullPath, $false, $true) # ReadOnly
Write-Host " ✓ Документ-донор открыт" -ForegroundColor Green
Write-Host " Количество стилей: $($sourceDoc.Styles.Count)" -ForegroundColor Gray
Write-Host " Открытие целевого документа..." -ForegroundColor Gray
$targetFullPath = (Resolve-Path $TargetPath).Path
Write-Verbose "Полный путь целевого документа: $targetFullPath"
$targetDoc = $wordApp.Documents.Open($targetFullPath)
Write-Host " ✓ Целевой документ открыт" -ForegroundColor Green
Write-Host " Количество стилей: $($targetDoc.Styles.Count)" -ForegroundColor Gray
# Проверка существования всех указанных стилей
Write-Host ""
Write-Host "5. Проверка наличия запрошенных стилей в документе-доноре..." -ForegroundColor Yellow
$missingStyles = @()
$foundStyles = @()
foreach ($styleName in $StyleNames) {
$styleFound = $false
foreach ($style in $sourceDoc.Styles) {
if ($style.NameLocal -eq $styleName) {
$styleFound = $true
$foundStyles += $styleName
Write-Host " ✓ Найден стиль: '$styleName'" -ForegroundColor Green
Write-Verbose " Тип: $($style.Type), Встроенный: $($style.BuiltIn)"
break
}
}
if (-not $styleFound) {
$missingStyles += $styleName
Write-Host " ✗ Не найден стиль: '$styleName'" -ForegroundColor Red
}
}
if ($missingStyles.Count -gt 0) {
Write-Host ""
Write-Host "Доступные стили в документе-доноре:" -ForegroundColor Yellow
$sourceDoc.Styles | ForEach-Object { Write-Host " - $($_.NameLocal)" -ForegroundColor Gray }
throw "Следующие стили не найдены в документе-доноре: $($missingStyles -join ', ')"
}
Write-Host ""
Write-Host "6. Создание временного документа для переноса стилей..." -ForegroundColor Yellow
# Генерируем путь к временному файлу с правильным расширением
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss_fff'
$tempFileName = "temp_style_copy_${timestamp}${sourceExtension}"
$tempPath = Join-Path $env:TEMP $tempFileName
Write-Host " Путь временного файла: $tempPath" -ForegroundColor Gray
# ИЗМЕНЕНИЕ 1: Упрощенный подход - копирование файла напрямую
Write-Host " Копирование файла-донора во временную папку..." -ForegroundColor Gray
try {
Copy-Item -Path $sourceFullPath -Destination $tempPath -Force
Write-Host " ✓ Файл скопирован" -ForegroundColor Green
# Проверяем, что файл создан
if (Test-Path $tempPath) {
$tempFileInfo = Get-Item $tempPath
Write-Host " Размер: $([math]::Round($tempFileInfo.Length/1KB, 2)) КБ" -ForegroundColor Gray
} else {
throw "Временный файл не был создан по пути: $tempPath"
}
} catch {
Write-Error "Ошибка при копировании файла: $_"
throw
}
# Открываем временный документ
Write-Host " Открытие временного документа..." -ForegroundColor Gray
$tempDoc = $wordApp.Documents.Open($tempPath, $false, $false)
Write-Verbose "Временный документ открыт"
Write-Host ""
Write-Host "7. Очистка временного документа от лишних стилей..." -ForegroundColor Yellow
Write-Host " Всего стилей во временном документе: $($tempDoc.Styles.Count)" -ForegroundColor Gray
# Подсчитываем стили для удаления
$stylesToDelete = 0
$deletedStyles = 0
$keptStyles = 0
$failedToDelete = 0
foreach ($style in $tempDoc.Styles) {
if ($StyleNames -notcontains $style.NameLocal) {
$stylesToDelete++
}
}
Write-Host " Стилей для удаления: $stylesToDelete" -ForegroundColor Gray
Write-Host " Стилей для сохранения: $($StyleNames.Count)" -ForegroundColor Gray
# ИЗМЕНЕНИЕ 2: Более мягкий подход к удалению стилей
# Удаляем только пользовательские стили, не трогая встроенные
foreach ($style in $tempDoc.Styles) {
$styleName = $style.NameLocal
if ($StyleNames -notcontains $styleName) {
# Пытаемся удалить только если стиль не встроенный
if (-not $style.BuiltIn) {
try {
$style.Delete()
$deletedStyles++
Write-Verbose " Удален стиль: '$styleName'"
} catch {
$failedToDelete++
Write-Verbose " Не удалось удалить стиль '$styleName': $_"
}
} else {
Write-Verbose " Пропущен встроенный стиль: '$styleName'"
}
} else {
$keptStyles++
Write-Host " ✓ Сохранен стиль: '$styleName'" -ForegroundColor Green
}
}
Write-Host " Результат: удалено $deletedStyles, сохранено $keptStyles, не удалось удалить $failedToDelete стилей" -ForegroundColor Gray
Write-Host " Сохранение изменений во временном файле..." -ForegroundColor Gray
# ИЗМЕНЕНИЕ 3: Используем Save() вместо SaveAs2() для избежания проблем с форматом
try {
$tempDoc.Save()
Write-Host " ✓ Изменения сохранены" -ForegroundColor Green
} catch {
Write-Warning "Не удалось сохранить изменения в временном файле: $_"
Write-Host " Продолжаем без сохранения изменений..." -ForegroundColor Yellow
}
Write-Host ""
Write-Host "8. Копирование стилей в целевой документ..." -ForegroundColor Yellow
# ИЗМЕНЕНИЕ 4: Альтернативный метод копирования стилей
# Если CopyStylesFromTemplate не работает, пробуем другой подход
try {
Write-Host " Попытка 1: Использование CopyStylesFromTemplate..." -ForegroundColor Gray
$targetDoc.CopyStylesFromTemplate($tempDoc.FullName)
Write-Host " ✓ Метод CopyStylesFromTemplate выполнен" -ForegroundColor Green
} catch {
Write-Warning "CopyStylesFromTemplate не сработал: $_"
Write-Host " Попытка 2: Использование AttachedTemplate..." -ForegroundColor Gray
try {
# Временно подключаем документ как шаблон
$originalTemplate = $targetDoc.AttachedTemplate
$targetDoc.AttachedTemplate = $tempDoc.FullName
$targetDoc.UpdateStyles()
# Восстанавливаем оригинальный шаблон
$targetDoc.AttachedTemplate = $originalTemplate
Write-Host " ✓ Стили обновлены через AttachedTemplate" -ForegroundColor Green
} catch {
Write-Warning "AttachedTemplate не сработал: $_"
# ИЗМЕНЕНИЕ 5: Последний резервный вариант - копирование стилей по одному
Write-Host " Попытка 3: Копирование стилей по одному..." -ForegroundColor Gray
$copiedCount = 0
foreach ($styleName in $StyleNames) {
try {
# Находим стиль в исходном документе
$sourceStyle = $null
foreach ($style in $sourceDoc.Styles) {
if ($style.NameLocal -eq $styleName) {
$sourceStyle = $style
break
}
}
if ($sourceStyle) {
# Проверяем, существует ли стиль в целевом документе
$targetStyle = $null
foreach ($style in $targetDoc.Styles) {
if ($style.NameLocal -eq $styleName) {
$targetStyle = $style
break
}
}
if (-not $targetStyle) {
# Создаем новый стиль в целевом документе
$targetStyle = $targetDoc.Styles.Add($styleName, $sourceStyle.Type)
}
# Копируем свойства стиля
$targetStyle.Font.Name = $sourceStyle.Font.Name
$targetStyle.Font.Size = $sourceStyle.Font.Size
$targetStyle.Font.Bold = $sourceStyle.Font.Bold
$targetStyle.Font.Italic = $sourceStyle.Font.Italic
$targetStyle.Font.Color = $sourceStyle.Font.Color
if ($sourceStyle.Type -eq 1) { # wdStyleTypeParagraph
$targetStyle.ParagraphFormat.Alignment = $sourceStyle.ParagraphFormat.Alignment
$targetStyle.ParagraphFormat.LeftIndent = $sourceStyle.ParagraphFormat.LeftIndent
$targetStyle.ParagraphFormat.RightIndent = $sourceStyle.ParagraphFormat.RightIndent
$targetStyle.ParagraphFormat.SpaceBefore = $sourceStyle.ParagraphFormat.SpaceBefore
$targetStyle.ParagraphFormat.SpaceAfter = $sourceStyle.ParagraphFormat.SpaceAfter
$targetStyle.ParagraphFormat.LineSpacing = $sourceStyle.ParagraphFormat.LineSpacing
}
$copiedCount++
Write-Host " ✓ Скопирован стиль: '$styleName'" -ForegroundColor Green
}
} catch {
Write-Warning " Не удалось скопировать стиль '$styleName': $_"
}
}
if ($copiedCount -gt 0) {
Write-Host " ✓ Скопировано стилей: $copiedCount из $($StyleNames.Count)" -ForegroundColor Green
} else {
throw "Не удалось скопировать ни одного стиля"
}
}
}
# Проверяем наличие скопированных стилей
Write-Host ""
Write-Host "9. Проверка результата копирования..." -ForegroundColor Yellow
$successCount = 0
foreach ($styleName in $StyleNames) {
$found = $false
foreach ($style in $targetDoc.Styles) {
if ($style.NameLocal -eq $styleName) {
$found = $true
$successCount++
Write-Host " ✓ Стиль '$styleName' присутствует в целевом документе" -ForegroundColor Green
break
}
}
if (-not $found) {
Write-Host " ⚠ Стиль '$styleName' не найден в целевом документе" -ForegroundColor Yellow
}
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Green
Write-Host "✓ Операция завершена успешно!" -ForegroundColor Green
Write-Host " Скопировано стилей: $successCount из $($StyleNames.Count)" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
}
catch {
Write-Host ""
Write-Host "========================================" -ForegroundColor Red
Write-Host "❌ ОШИБКА!" -ForegroundColor Red
Write-Host "========================================" -ForegroundColor Red
Write-Error "Детали ошибки: $($_.Exception.Message)"
Write-Verbose "Stack trace: $($_.ScriptStackTrace)"
if ($_.Exception.InnerException) {
Write-Verbose "Inner exception: $($_.Exception.InnerException.Message)"
}
}
finally {
Write-Host ""
Write-Host "10. Очистка ресурсов..." -ForegroundColor Yellow
# Закрытие временного документа
if ($tempDoc) {
Write-Host " Закрытие временного документа..." -ForegroundColor Gray
try {
$tempDoc.Close($false)
Write-Host " ✓ Временный документ закрыт" -ForegroundColor Green
} catch {
Write-Host " ⚠ Ошибка при закрытии временного документа: $_" -ForegroundColor Yellow
}
Release-ComObject ([ref]$tempDoc)
}
# Закрытие целевого документа с сохранением
if ($targetDoc) {
Write-Host " Сохранение и закрытие целевого документа..." -ForegroundColor Gray
try {
$targetDoc.Close($true)
Write-Host " ✓ Целевой документ сохранен и закрыт" -ForegroundColor Green
} catch {
Write-Host " ⚠ Ошибка при закрытии целевого документа: $_" -ForegroundColor Yellow
}
Release-ComObject ([ref]$targetDoc)
}
# Закрытие документа-донор без сохранения
if ($sourceDoc) {
Write-Host " Закрытие документа-донора..." -ForegroundColor Gray
try {
$sourceDoc.Close($false)
Write-Host " ✓ Документ-донор закрыт" -ForegroundColor Green
} catch {
Write-Host " ⚠ Ошибка при закрытии документа-донора: $_" -ForegroundColor Yellow
}
Release-ComObject ([ref]$sourceDoc)
}
# Завершение Word
if ($wordApp) {
Write-Host " Завершение Microsoft Word..." -ForegroundColor Gray
try {
$wordApp.Quit()
Write-Host " ✓ Word завершен" -ForegroundColor Green
} catch {
Write-Host " ⚠ Ошибка при завершении Word: $_" -ForegroundColor Yellow
}
Release-ComObject ([ref]$wordApp)
}
# Удаление временного файла
if ($tempPath -and (Test-Path $tempPath)) {
Write-Host " Удаление временного файла..." -ForegroundColor Gray
try {
Remove-Item $tempPath -ErrorAction Stop
Write-Host " ✓ Временный файл удален" -ForegroundColor Green
} catch {
Write-Host " ⚠ Не удалось удалить временный файл: $_" -ForegroundColor Yellow
Write-Host " Путь: $tempPath" -ForegroundColor Gray
}
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Завершение работы скрипта" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment