Вопрос или проблема
У меня есть скрипт на PowerShell для извлечения и последующего отображения пути к поддерживающему документу для ряда событий, но он работает не так, как ожидалось.
Документ существует, я указал правильный путь, но скрипт отказывается сделать тот ряд с зеленым выделением рядом с путем к файлу. Пожалуйста, помогите мне с этим.
Пример для понимания контекста: событие имеет дату, номер документа и имя партнера. В папке с документами есть документ с таким названием: год месяц день_FF последние 4 цифры номера документа_ИМЯ ПАРТНЕР (обычно первое слово).
$MainFolder = "ПапкаСДокументами"
$ExcelFilePath = "EXCEL.xlsx"
$SheetName = "Лист1"
$StartRow = 1
$EndRow = 2
$ExcelApp = New-Object -ComObject Excel.Application
$ExcelApp.Visible = $true
$Workbook = $ExcelApp.Workbooks.Open($ExcelFilePath)
$Worksheet = $Workbook.Sheets.Item($SheetName)
$FolderPaths = Get-ChildItem -Path $MainFolder -Recurse -Directory | ForEach-Object { $_.FullName }
$FoundFiles = @{}
Function Search-PDF {
param (
[Parameter(Mandatory=$true)]
[string[]]$FolderPaths,
[Parameter(Mandatory=$true)]
[string]$DocNumber,
[Parameter(Mandatory=$true)]
[datetime]$DocDate,
[Parameter(Mandatory=$true)]
[string]$Partner
)
$FormattedDate = $DocDate.ToString("yyyy MM dd")
$LastTwo = $DocNumber.Substring([Math]::Max(0, $DocNumber.Length - 2))
$LastThree = $DocNumber.Substring([Math]::Max(0, $DocNumber.Length - 3))
$LastFour = $DocNumber.Substring([Math]::Max(0, $DocNumber.Length - 4))
$SearchNumbers = @($LastTwo, $LastThree, $LastFour)
$PartnerWords = $Partner -split ' '
foreach ($FolderPath in $FolderPaths) {
Get-ChildItem -Path $FolderPath -Filter "*.pdf" | ForEach-Object {
$FileName = $_.Name
$NumberMatch = $false
foreach ($Num in $SearchNumbers) {
if ($FileName -match "\b${Num}\b") {
$NumberMatch = $true
break
}
}
if ($NumberMatch) {
if ($FileName -match $FormattedDate) {
$PartnerMatch = $false
foreach ($Word in $PartnerWords) {
if ($FileName -match [regex]::Escape($Word)) {
$PartnerMatch = $true
break
}
}
if ($PartnerMatch) {
return $_.FullName
}
}
}
}
}
return $null
}
for ($Row = $StartRow; $Row -le $EndRow; $Row++) {
try {
$DocDate = $Worksheet.Cells.Item($Row, 1).Text
$DocType = $Worksheet.Cells.Item($Row, 2).Text
$DocNumber = $Worksheet.Cells.Item($Row, 3).Text
$Partner = $Worksheet.Cells.Item($Row, 11).Text
$DocDate = [datetime]::ParseExact($DocDate, "dd.MM.yyyy", $null)
if (-not $DocNumber -or -not $Partner) {
continue
}
$FoundFilePath = Search-PDF -FolderPaths $FolderPaths -DocNumber $DocNumber -DocDate $DocDate -Partner $Partner
if ($FoundFilePath) {
$FileName = [System.IO.Path]::GetFileName($FoundFilePath)
$Valid = $false
if ($FileName -match $FormattedDate -and
($FileName -match "\b${DocNumber}\b") -and
($FileName -match [regex]::Escape($Partner))) {
$Valid = $true
}
if ($Valid) {
$Worksheet.Cells.Item($Row, 5).Value = $FoundFilePath
$Worksheet.Rows.Item($Row).Interior.Color = [System.Drawing.Color]::FromArgb(144, 238, 144).ToArgb()
$FoundFiles[$FoundFilePath] = $true
}
else {
$Worksheet.Cells.Item($Row, 5).Value = "Файл найден, но не соответствует критериям."
$Worksheet.Rows.Item($Row).Interior.Color = [System.Drawing.Color]::FromArgb(255, 99, 71).ToArgb()
}
}
else {
$Worksheet.Cells.Item($Row, 5).Value = "Поддерживающий документ не найден."
$Worksheet.Rows.Item($Row).Interior.Color = [System.Drawing.Color]::FromArgb(255, 99, 71).ToArgb()
}
Write-Host "Сохранение файла после обработки строки $Row"
$Workbook.Save()
}
catch {
Write-Host "Ошибка при обработке строки ${Row}: ${_}"
$Workbook.Save()
}
}
$Workbook.Save()
$Workbook.Close()
$ExcelApp.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Worksheet) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelApp) | Out-Null
Write-Output "Скрипт выполнен успешно."
Когда я его запускаю, я не получаю никаких ошибок, он проверяет строку за строкой, но, даже если документ существует в выбранной папке, он отказывается их находить.
Ответ или решение
Решение проблемы поиска поддерживающих документов с помощью PowerShell
Проблема, с которой вы столкнулись при использовании скрипта PowerShell для поиска поддерживающих документов, может быть вызвана несколькими факторами. Мы детально проанализируем ваш скрипт, укажем возможные недочёты и предложим пути их решения.
1. Убедитесь в правильности формата имени файла
Формат имени файла важен и должен строго соответствовать шаблону, который вы описали: годы, месяц, день + последние 4 цифры номера документа + имя партнера. Прежде всего, проверьте код, который форматирует дату и подбирает последние цифры номера документа.
Рекомендации:
-
Убедитесь, что переменная
$FormattedDate
формируется правильно, используя следующий код:$FormattedDate = $DocDate.ToString("yyyy MM dd")
-
Также проверьте, что вы правильно извлекаете последние 2, 3 и 4 цифры из номера документа. Возможно, следует использовать более универсальный подход к извлечению цифр:
$LastFour = $DocNumber.Substring($DocNumber.Length - 4, 4)
2. Проверка на наличия соответствия
Ваша функция Search-PDF
осуществляет поиск по некоторым критериям. Проверьте, что логику поиска по имени файла реализована корректно. В частности, убедитесь, что проверка на совпадение выполняется для всех трех параметров: дата, номер документа и имя партнера.
Проверка:
-
Убедитесь, что условие для проверки совпадения с именем файла выглядит так:
if ($FileName -match [regex]::Escape($LastFour) -and $FileName -match $FormattedDate -and $FileName -match [regex]::Escape($Partner)) { return $_.FullName }
По возможности добавьте отладочный вывод в местах, где происходит проверка на соответствие, чтобы видеть, какие имена файлов вы сравниваете.
3. Значения в Excel
Убедитесь, что значения, которые вы получаете из Excel, полностью соответствуют формату, который вы ожидаете. Иногда в Excel могут быть лишние пробелы или неопознанные символы.
Рекомендация:
-
Используйте метод
.Trim()
для очистки строк перед их обработкой:$DocNumber = $Worksheet.Cells.Item($Row, 3).Text.Trim() $Partner = $Worksheet.Cells.Item($Row, 11).Text.Trim()
4. Упрощение кода для отладки
Для более легкой отладки и понимания работы вашего скрипта можно временно упростить логику проверки, выводя больше информации по каждому шагу:
Write-Host "Inspecting file: $_.FullName"
Write-Host "Comparing with - Date: $FormattedDate, Number: $LastFour, Partner: $Partner"
Это позволит вам видеть, какие именно файлы оцениваются, и что проверяется.
5. Сохранение и закрытие Excel
Попробуйте перенести логические блоки, относящиеся к сохранению и закрытию файла Excel, в отдельный блок, чтобы гарантировать правильное выполнение:
finally {
$Workbook.Save()
$Workbook.Close()
$ExcelApp.Quit()
}
Заключение
С учетом всех вышеперечисленных рекомендаций, попробуйте отладить и выполнить ваш скрипт ещё раз. Подходите к каждой части кода с проверкой и обдуманностью, чтобы убедиться, что вы не пропустили ни одной детали. Как только вы исправите недочеты, ваш скрипт должен корректно находить и отображать путь к поддерживающим документам, соответствующим критериям.
Если вам потребуется дальнейшая помощь, не стесняйтесь обращаться за поддержкой. Успехов в вашей работе с PowerShell!