Powershell: Найти сопутствующий документ для каждого события

Вопрос или проблема

У меня есть скрипт на 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!

Оцените материал
Добавить комментарий

Капча загружается...