Рецепт

Перенести заливку строк из старой книги в новую

Новая книга покупок без цветов, а в старой строки уже размечены заливкой — нужно перенести разметку по совпадению значения.

Макрос запускается из новой книги. Ищет лист с тем же именем в старой; если нет — спрашивает имя. Строка считается цветной, если Interior не белый и не «без заливки» (ColorIndex xlNone / -4142). По первому цветному значению в строке делается Find xlWhole в новой книге, красится вся строка. Каждую старую строку обрабатывайте один раз — иначе одна строка перекрасит несколько находок. Find помнит LookAt и LookIn: задавайте их явно. Пустые цветные ячейки пропускайте: искать нечего. Старую книгу закрывайте без сохранения. Это не копирование формата ячейка-в-ячейку, а перенос метки строки.

Код

Sub TransferColorsFromOldFile()
    Dim wbOld As Workbook, wbNew As Workbook
    Dim wsNew As Worksheet, wsOld As Worksheet
    Dim oldFilePath As Variant
    Dim sheetName As String
    Dim found As Range
    Dim processedRows As Object
    Dim i As Long, j As Long, lastRow As Long
    Dim colorValue As Long, searchValue As String

    Set wbNew = ThisWorkbook
    Set wsNew = wbNew.ActiveSheet
    sheetName = wsNew.Name

    oldFilePath = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", , "Выберите СТАРУЮ книгу (с цветами)")
    If oldFilePath = False Then Exit Sub

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Set wbOld = Workbooks.Open(oldFilePath)

    On Error Resume Next
    Set wsOld = wbOld.Sheets(sheetName)
    On Error GoTo 0
    Do While wsOld Is Nothing
        sheetName = InputBox("В старом файле нет листа '" & wsNew.Name & "'." & vbCrLf & _
                             "Введите имя листа:", "Имя листа")
        If Len(sheetName) = 0 Then GoTo CleanUp
        On Error Resume Next
        Set wsOld = wbOld.Sheets(sheetName)
        On Error GoTo 0
        If wsOld Is Nothing Then MsgBox "Лист не найден. Попробуйте снова.", vbExclamation
    Loop

    Set processedRows = CreateObject("Scripting.Dictionary")
    lastRow = wsOld.UsedRange.Rows.Count
    For i = 1 To lastRow
        For j = 1 To 70
            If wsOld.Cells(i, j).Interior.ColorIndex <> xlNone And _
               wsOld.Cells(i, j).Interior.ColorIndex <> -4142 And _
               wsOld.Cells(i, j).Interior.Color <> 16777215 Then
                If Not processedRows.Exists(i) Then
                    processedRows.Add i, i
                    searchValue = Trim$(CStr(wsOld.Cells(i, j).Value))
                    If Len(searchValue) > 0 Then
                        Set found = wsNew.Cells.Find(What:=searchValue, LookIn:=xlValues, LookAt:=xlWhole)
                        If Not found Is Nothing Then
                            wsNew.Rows(found.Row).Interior.Color = wsOld.Cells(i, j).Interior.Color
                        End If
                    End If
                End If
                Exit For
            End If
        Next j
    Next i

    If processedRows.Count > 0 Then
        wbNew.Save
        MsgBox "Обработано строк: " & processedRows.Count, vbInformation
    Else
        MsgBox "Цветных строк на листе не найдено.", vbExclamation
    End If

CleanUp:
    If Not wbOld Is Nothing Then wbOld.Close SaveChanges:=False
    Application.ScreenUpdating = True
    Application.EnableEvents = True
End Sub

Связанные члены API