Загрузка данных


#If VBA7 Then
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

Dim FSO As Object
Dim FileFound As Boolean
Dim CurrentFileName As String
Dim CurrentFilePath As String
Dim CurrentFileLocation As String

Dim GlobalCurrentCount As Long
Dim GlobalTotalCount As Long

Sub SmartBatchPrint()
    Dim MainFolderPath As String
    Dim Cell As Range
    Dim TargetNumber As String
    Dim Suffix As String
    Dim AllowPrint As Boolean
    
    ' Динамический массив для путей
    Dim SearchPaths() As String
    Dim PathIndex As Long
    
    Dim WB As Workbook
    Dim WS As Worksheet
    Dim TimeLeft As Double
    
    ' Переменные для поиска листов по содержимому
    Dim Keywords(1 To 5) As String
    Dim KeywordFound(1 To 5) As Boolean
    Dim i As Long
    Dim SheetsPrintedCount As Long
    Dim FoundCell As Range
    
    ' =========================================================================
    ' БЛОК НАСТРОЙКИ КЛЮЧЕВЫХ СЛОВ (Ищутся внутри текста ячеек)
    ' =========================================================================
    Keywords(1) = "ПРОТОКОЛ ИСПЫТАНИЙ"
    Keywords(2) = "ОКОНЧАНИЕ РАСЧЕТНО-СПРАВОЧНЫХ"
    Keywords(3) = "Приложение №1"
    Keywords(4) = "АКТ ИСПЫТАНИЙ"
    Keywords(5) = "ПЕРВИЧНЫЕ ЗАПИСИ"
    ' =========================================================================
    
    ' 1. Базовый путь к главной папке
    MainFolderPath = "C:\Users\vorob\OneDrive\Desktop\Печать\"
    
    ' Динамический массив для путей
    ReDim SearchPaths(1 To 1) ' Укажи здесь общее количество папок
    
    SearchPaths(1) = "X:\2025 год\14. Шум\"
    ' SearchPaths(1) = MainFolderPath & "ИП Якимов\Протоколы\"
    ' SearchPaths(2) = MainFolderPath & "УМВД\Протоколы\Печать\"
    ' SearchPaths(3) = MainFolderPath & "Ягодное\Протокол\Печать\"
    ' SearchPaths(4) = MainFolderPath & "Вятавтодор\"
    ' SearchPaths(5) = "X:\2025 год\01. Атмосфера\"
    
    Suffix = "ШУМ."
    AllowPrint = True
    
    ' Подсчет общего количества работы
    GlobalTotalCount = 0
    For Each Cell In Selection
        If Cell.Value <> "" And Cell.Interior.ColorIndex = xlNone Then
            GlobalTotalCount = GlobalTotalCount + 1
        End If
    Next Cell
    
    If GlobalTotalCount = 0 Then Exit Sub
    
    Set FSO = CreateObject("Scripting.FileSystemObject")
    
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    GlobalCurrentCount = 0
    For Each Cell In Selection
        
        DoEvents
        Application.EnableCancelKey = xlErrorHandler
        On Error GoTo StrictEmergencyStop
        
        If Cell.Value <> "" Then
            If Cell.Interior.ColorIndex <> xlNone Then GoTo SkipCell
            
            GlobalCurrentCount = GlobalCurrentCount + 1
            TargetNumber = Trim(CStr(Cell.Value)) & Suffix
            
            ' Сброс переменных перед поиском нового файла
            FileFound = False
            CurrentFileName = ""
            CurrentFilePath = ""
            CurrentFileLocation = ""
            
            Application.StatusBar = "Старт поиска: " & TargetNumber & "... (" & GlobalCurrentCount & "/" & GlobalTotalCount & ")"
            DoEvents
            
            ' АВТОМАТИЧЕСКИЙ ОБХОД ВСЕХ ПАПОК ИЗ СПИСКА
            For PathIndex = LBound(SearchPaths) To UBound(SearchPaths)
                If Not FileFound Then
                    If FSO.FolderExists(SearchPaths(PathIndex)) Then
                        Call FastSubFolderSearch(SearchPaths(PathIndex), TargetNumber, MainFolderPath)
                    End If
                Else
                    Exit For
                End If
            Next PathIndex
            
            ' Отрисовка результатов поиска
            Application.ScreenUpdating = True
            DoEvents
            
            If FileFound Then
                ' По умолчанию красим в стандартный зеленый
                Cell.Interior.Color = RGB(198, 239, 206)
                
                For TimeLeft = 3# To 0# Step -0.05
                    Application.StatusBar = "Найдено: " & CurrentFileName & " -> Сканирование содержимого листов... (" & Format(TimeLeft, "0.00") & " сек)"
                    DoEvents
                    Sleep 50
                Next TimeLeft
                
                ' Проверка разрешения на печать
                If AllowPrint Then
                    Application.ScreenUpdating = False
                    Set WB = Workbooks.Open(Filename:=CurrentFilePath, UpdateLinks:=0, ReadOnly:=True)
                    
                    ' Сброс флагов найденных ключевых слов для нового файла
                    SheetsPrintedCount = 0
                    For i = 1 To 5
                        KeywordFound(i) = False
                    Next i
                    
                    ' Перебор ключевых слов по порядку приоритета (от 1 до 5)
                    For i = 1 To 5
                        For Each WS In WB.Worksheets
                            
                            ' Ищем ключевое слово ВНУТРИ ячеек листа (по частичному совпадению, без учета регистра)
                            Set FoundCell = Nothing
                            Set FoundCell = WS.Cells.Find(What:=Keywords(i), LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)
                            
                            ' Если фраза найдена в содержимом листа
                            If Not FoundCell Is Nothing Then
                                On Error Resume Next
                                WS.PrintOut
                                On Error GoTo 0
                                KeywordFound(i) = True
                                SheetsPrintedCount = SheetsPrintedCount + 1
                                Exit For ' Нашли лист, содержащий это слово, переходим к следующему ключевому слову
                            End If
                            
                        Next WS
                    Next i
                    
                    WB.Close SaveChanges:=False
                    
                    ' Если нашли и распечатали меньше 5 листов (какой-то текст не был найден)
                    If SheetsPrintedCount < 5 Then
                        Cell.Interior.Color = RGB(158, 213, 97) ' Светло-зеленый для неполного комплекта
                    End If
                Else
                    Application.StatusBar = "Найдено: " & CurrentFileName & " -> Печать пропущена (параметр AllowPrint = False)"
                    Cell.Interior.Color = RGB(226, 211, 120)
                    Sleep 2000
                End If
            Else
                ' Если файл НЕ найден
                Application.StatusBar = "Файл для " & TargetNumber & " НЕ НАЙДЕН! Переходим к следующему..."
                Cell.Interior.Color = RGB(255, 199, 206) ' Красный
                
                DoEvents
                Sleep 2000
                Application.ScreenUpdating = False
            End If
            
        End If
SkipCell:
    Next Cell

    Application.StatusBar = False
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    Exit Sub

StrictEmergencyStop:
    Application.StatusBar = False
    DoEvents
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    MsgBox "Процесс остановлен пользователем!", vbCritical, "Остановка"
End Sub

' Функция поиска
Sub FastSubFolderSearch(ByVal FolderPath As String, ByVal FileNumber As String, ByVal MainPath As String)
    Dim Folder As Object
    Dim SubFolder As Object
    Dim File As Object
    Dim FirstNumInName As String
    
    If FileFound Then Exit Sub
    
    Application.StatusBar = "Ищу " & FileNumber & " в: " & Right(FolderPath, 30) & "... (" & GlobalCurrentCount & "/" & GlobalTotalCount & ")"
    DoEvents
    
    Set Folder = FSO.GetFolder(FolderPath)
    
    For Each File In Folder.Files
        If InStr(1, File.Name, ".xlsx", vbTextCompare) > 0 Or InStr(1, File.Name, ".xls", vbTextCompare) > 0 Then
            FirstNumInName = Split(File.Name, " ")(0)
            
            If StrComp(FirstNumInName, FileNumber, vbTextCompare) = 0 Then
                FileFound = True
                CurrentFileName = File.Name
                CurrentFilePath = File.Path
                CurrentFileLocation = "\" & Replace(File.ParentFolder.Path & "\", MainPath, "", 1, -1, vbTextCompare)
                Exit Sub
            End If
        End If
    Next File
    
    For Each SubFolder In Folder.SubFolders
        If FileFound Then Exit Sub
        Call FastSubFolderSearch(SubFolder.Path & "\", FileNumber, MainPath)
    Next SubFolder
End Sub