VBA: сравнение отдельных ячеек между целыми строками - PullRequest
0 голосов
/ 06 февраля 2020

Я работал с условным форматированием и думал, как это будет выглядеть, если его заменить на «ручное» сравнение в VBA.

Допустим, я хочу сравнить ячейки между строкой 1 и строкой 2, то есть я сравниваю A1 с A2, B1 с B2 и c. Когда значение в строке 2 больше, я хочу выделить это в строке 2.

enter image description here Если я не хочу делать это с условным форматированием, как я могу go об этом? Нужно ли l oop через клетки сравнивать или есть способ сделать это без al oop? С al oop это должно выглядеть так:

Option Explicit

Sub Testing()
    Dim ws As Worksheet
    Dim i As Long
    Dim rng As Range

    Set ws = ThisWorkbook.ActiveSheet
    Set rng = ws.Range("A2:E2")

    For i = 1 To rng.Count
        If ws.Cells(2, i).Value > ws.Cells(1, i).Value Then
            ws.Cells(2, i).Interior.ColorIndex = 44
        End If
    Next
End Sub

Есть ли способ использовать меньше кода для достижения того же результата? Мне просто интересно, не знаю ли я о каком-нибудь более умном альтернативном способе go по этому поводу.

1 Ответ

2 голосов
/ 06 февраля 2020

«Есть ли способ использовать меньше кода для достижения того же результата?»

Не рекомендуется по нескольким причинам, но это может быть сделано в одну строку:

With Sheet1
    .Range(Join(Filter(.[IF(A2:E2>A1:E1,CHAR(COLUMN(A2:E2)+64)&2,"%")], "%", False), ",")).Interior.ColorIndex = 44
End With

Почему эта работа:

  • .[IF(A2:E2>A1:E1,CHAR(COLUMN(A2:E2)+64)&2,"%")] сокращенно для метода Application.Evaluate , Все, что находится между .[..] - это, по сути, Worksheet.Function, где VBA достаточно умен, чтобы знать, что я хочу вернуть массив результатов. . перед этим будет означать Sheet1. Результирующий массив> {"A2","B2","%","%","E2"}

  • Filter функция (на самом деле не известна) будет принимать этот массив и выводить результирующий массив, отфильтровывая "%" ценности. Следовательно, параметр FALSE. Результирующий массив> {"A2","B2","E2"}

  • Тогда функция Join объединит этот массив в строку, используя "," в качестве разделителя. Скорее, basi c, что приводит к "A2,B2,E2"

  • Это, в свою очередь, является действительным Range.Address, который мы можем использовать со ссылкой Range(...). Получив наш объект Range, мы можем установить его свойство Interior с предполагаемым значением ColorIndex.


Почему я не рекомендую рекомендовать this:

  • Несмотря на то, что читаемость уже может быть проблемой, .[..] не принимает переменные, что означает, что динамический массив c необходимо будет записать с помощью метода .Evaluate(..), включая переменные, дополнительные кавычки и т. д. c. добавляя к проблемам с читабельностью.

  • Хотя VBA достаточно умен, чтобы признать, что нам нужен возвращаемый массив, это может стать sluggi sh на большом Range объекте. Маленький, как в примере, не представляет никаких проблем, хотя адрес

  • Range может содержать не более 255 символов. Массивы большего размера означают большие строки, что означает большее изменение, которое в какой-то момент будет возвращать ошибку.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...