Excel VBA для выделения определенного текста работает в Excel 2010, но не в Excel 2019 (выделение перемещается при редактировании ячейки или при переносе текста)

У меня есть документ Excel для списка моей музыкальной коллекции, и я попытался включить новую функцию для выделения определенных альбомов в соответствии с определенными критериями (выпущенными до определенного года, в или после определенного года...). Идея заключалась в том, чтобы просто изменить цвет шрифта года (ов) для альбомов, которые соответствовали указанным критериям. Я написал и позаимствовал фрагменты кода vba для создания подпрограммы Highlighter. Я работал с документом в Excel 2019 и пробовал 4 или 5 различных подходов - ВСЕ, КАЗАЛСЯ, выделяли неправильную часть текстовых строк (хотя это не совсем так - пожалуйста, читайте дальше - на самом деле речь идет о переносе текста и редактировании ячеек).

Каждая группа, для которой у меня есть музыка, имеет одну ячейку Excel, содержащую список всех выпущенных альбомов этой группы (который обновляется запросами API на веб-сайт MusicBrainz). Каждый альбом находится на отдельной строке в этой единственной ячейке (дополнительно с символом вертикальной черты «|» в качестве разделителя перед окончательным возвратом каретки vbCrLf. Моя цель — просто изменить цвет шрифта для года, если он совпадает — например, если я указать «выделить альбомы, выпущенные в 2022 году», то подпрограмма должна изменить цвет шрифта строки «2022» во всех ячейках альбомов на листе.

Поскольку многие группы имеют длинный список альбомов, мне нравится иметь фиксированную высоту строки для всего листа. Я НЕ хочу переноса текста и неравномерной высоты строк. Таким образом, способ просмотреть весь список альбомов — использовать F2, чтобы открыть ячейку для редактирования.

ПРИМЕР ТЕКСТОВОЙ СТРОКИ В ОДНОЙ ЯЧЕЙКЕ для всех альбомов конкретной группы (после каждой вертикальной черты стоит возврат каретки, а также после первой закрывающей квадратной скобки): [4 альбома] [01] Elements of Persuasion : 29 марта 2005 г. | [02] Статический импульс: 2010-07-16 | [03] Непостоянный резонанс: 26 июля 2013 г. | [04] Красивый оттенок серого: 20 мая 2022 г. |

В приведенном выше образце текста я хотел изменить «2022» для четвертого альбома в списке и сделать его красным.

Как указано, я пробовал разные варианты, но каждый раз, когда я входил в ячейку (для редактирования), Excel, казалось, выделял неправильную часть текста. Я подумал, что это может быть из-за возврата каретки... и попытался заменить их на разные символы... все безрезультатно. Но, наконец, я понял, что Excel выделял правильную часть текстовой строки, НО только тогда, когда ячейка была закрыта для редактирования.

Наконец, я попробовал еще раз на другом компьютере (не моем) с Excel 2010, и код работал абсолютно идеально. Я мог открыть ячейки для редактирования, и та же самая часть строки, которая была окрашена в красный цвет, оставалась красной. Теперь я снова за своим компьютером (Excel 2019), и код, который вчера прекрасно работал, теперь снова не работает. Теперь я также понял, что если включено обтекание текстом, выделение также перемещается - точно так же, как если бы я использовал F2.

Извините за многословное объяснение/вопрос, но... есть ли какая-то разница между Excel 2010 и 2019, из-за которой все это происходит? Есть ли решение? Почему при входе в ячейку для редактирования содержимого (этот метод я выбрал для визуализации этих конкретных ячеек) цветной текст должен двигаться? Есть ли способ избежать «перемещения» Excel выделенного текста, когда я нажимаю F2 для редактирования (и тем самым просмотра) содержимого ячейки? Обтекание текстом также смещает выделенный текст... Есть ли способ избежать этого? По-видимому, это происходит только в Excel 2019 или, возможно, правильно работает только в Excel 2010.

Вот 2 изображения, так что легко увидеть разницу (красным цветом отмечены все года >= "2000":
При редактировании содержимого ячейки

Не редактировать содержимое ячейки:

Мой код для подпрограммы Highlighter ниже

Sub Highlighter()   
    Dim TextRange  As Range
    Dim HighlighterValues As Range
    Dim r As Range
    Dim BottomRow As Integer   
        MUSIC.Select   '  MUSIC is the name of the worksheet where the bands and albums are listed
        Range("B6").Select
        ActiveCell.SpecialCells(xlLastCell).Select
        Selection.End(xlUp).Select
        BottomRow = ActiveCell.Row
        Range("B6").Select
        
        Set TextRange = MUSIC.Range("h6:h" & BottomRow)
        TextRange.Font.ColorIndex = xlAutomatic ' ie. set all to black first
        Set HighlighterValues = SETTINGS.Range("k2:k63") ' list holding the years to highlight
        fontColor = 3 ' red
        
        For Each r In HighlighterValues ' go through all of the values marked to be highlighted
            partOfText = r.Text
            If partOfText <> "" And partOfText <> 0 Then
                For Each part In TextRange
                lenOfPart = Len(part)
                lenPartOfText = Len(partOfText)
                For i = 1 To lenOfPart
                    TempStr = Mid(part, i, lenPartOfText)
                    If TempStr = partOfText Then
                     part.Characters(Start:=i, Length:=lenPartOfText).Font.ColorIndex = fontColor
                    End If
                Next i
                Next part
            End If
        
        Next r
End Sub

Большое спасибо за любую помощь!!

Обычно разрыв строки в ячейке — это vbLf (Alt+Enter) — если у вас действительно есть vbCRLf, то, возможно, начните с замены всех на «vbLf». Сказав это, я не смог воспроизвести проблему.

Tim Williams 30.09.2022 18:08

Тим, большое спасибо за ваш ответ. Вместо этого я заменил vbCRLF на vbLfs, и вы абсолютно правы! Это сработало. После всего этого очень легко исправить. Спасибо большое за твою помощь. Мне по-прежнему кажется совершенно странным, что Excel 2010 отлично справился с vbCRLfs, а более новая версия - нет... но неважно. Теперь он работает отлично. Не могу отблагодарить вас достаточно! Как тут проголосовать? Извините за спасибо - это мой первый вопрос...

SteveH 02.10.2022 15:52

Приятно слышать, что вы исправили это. Опубликовал мой комментарий как ответ, так что не стесняйтесь принять его, нажав на галочку рядом с ним.

Tim Williams 02.10.2022 18:47
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
3
138
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обычно разрыв строки в ячейке — это vbLf (Alt+Enter) — если у вас действительно есть vbCrLf, то, возможно, начните с замены всех на vbLf.

Сказав это, я не смог воспроизвести проблему (мой тестовый код ниже), поэтому, возможно, это что-то конкретное для ваших данных.

Sub Highlighter()
    Dim TextRange  As Range
    Dim HighlighterValues As Range
    Dim r As Range
    Dim arrText, arrHV, rwTxt As Long, rwHL As Long, fontcolor As Long, v As String, s As String
    
    MUSIC.Select   '  MUSIC is the name of the worksheet where the bands and albums are listed
    Set TextRange = MUSIC.Range("h6:h" & MUSIC.Cells(Rows.Count, "B").End(xlUp).Row)
    TextRange.Font.ColorIndex = xlAutomatic ' ie. set all to black first
    arrText = TextRange.Value 'get as an array
    
    arrHV = SETTINGS.Range("k2:k63").Value
    
    fontcolor = vbRed ' red
    Application.ScreenUpdating = False
    For rwTxt = 1 To UBound(arrText, 1)   'loop the album lists
        v = arrText(rwTxt, 1)
        For rwHL = 1 To UBound(arrHV, 1)  'loop the search terms
            s = arrHV(rwHL, 1)
            If Len(s) > 0 Then
                If InStr(1, v, s, vbTextCompare) > 0 Then
                    HilightAll TextRange.Cells(rwTxt), s, fontcolor
                End If
            End If
        Next rwHL
    Next rwTxt
End Sub

'Hilite all instances of `txt` in range `c` with RGB color `clr`
Sub HilightAll(c As Range, txt As String, clr As Long)
    Dim pos As Long, i As Long, s
    s = c.Value
    i = 1
    Do
        pos = InStr(i, s, txt, vbTextCompare)
        If pos = 0 Then Exit Do
        c.Characters(pos, Len(txt)).Font.Color = clr
        i = pos + 1
    Loop
End Sub

Другие вопросы по теме