Автоматический расчет Excel VBA UDF, связанных со свойствами ячейки

Я написал UDF для подсчета ячеек определенного цвета и с определенными LineStyles, я публикую всю функцию:

Function CountTime(rData As Range, cellRefColor As Range) As Variant    

    Dim indRefColor As Long
    Dim cellCurrent As Range
    Dim cntRes As Variant

    Application.Volatile

    cntRes = 0
    indRefColor = cellRefColor.Cells(1, 1).Interior.Color
    For Each cellCurrent In rData
        If indRefColor = cellCurrent.Interior.Color Then
            cntRes = cntRes + 1
        End If
        If cellCurrent.Borders(xlDiagonalUp).LineStyle <> xlNone Then
            cntRes = cntRes + 0.5
        End If
    Next cellCurrent

    CountTime = cntRes
End Function

Теперь у меня проблема в том, что формула не рассчитывается автоматически, когда одна из ячеек в rData изменились ли его свойства цвета или линии. я добавил Application.Volatileи я также попытался вызвать расчет Worksheet_Change sub, однако это не работает, так как Excel, похоже, не рассматривает изменение цвета как изменение ячейки / рабочего листа.

Есть ли способ заставить ячейку вычислять и обновлять автоматически, когда пользователь изменяет свойства цвета или линии ячейки в rData?

РЕДАКТИРОВАТЬ - РЕШЕНО Большое спасибо ignotus, обходной путь ChangeSelection достаточно хорош для моих целей. Не думал об этом. И фоновая информация также удобна, большое спасибо.

2 ответа

Решение

Я не думаю, что это возможно, но вполне справедливым решением было бы пересчитать, когда вы покидаете ячейку или меняете ее:

Private Sub Worksheet_Change(ByVal Target As Range)
    Me.Calculate
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Me.Calculate
End Sub

Или, в качестве альтернативы, поместите кнопку на листе, который вызывает Me.Calculate

К вашему сведению: что такое Me? Источник

Me ссылается на родительский объект, из которого "сидит" код. Если вы пишете в модуле Sheet, Me будет ссылаться на этот конкретный лист.

С помощью Me это удобно, потому что нам не нужно беспокоиться об изменении имени листа, и это также делает его немного легким для будущих читателей кода, поскольку им не нужно помнить, что "Основная пользовательская форма" - это пользовательская форма, над которой мы сейчас работаем. Вы можете применить те же методы к Me что вы сможете применить к объекту, если вы дадите полное имя.

В пределах Sheet1 moduleследующие строки идентичны по назначению:

Worksheets("Sheet1").Range("A1").Select
Me.Range("A1").Select

Если ваша функция выполняется очень быстро (скажем, менее 50 мс), вы можете вызвать ее из обработчика событий Private Sub Worksheet_SelectionChange(ByVal Target As Range); пользователи не заметят, что это происходит. Еще одна проблема с этим решением будет, когда пользователь меняет формат и сразу же покидает лист. Затем, если вы хотите, чтобы произошел повторный вызов, вы можете, возможно, использовать Private Sub Worksheet_Deactivate() запустить его. Существуют и другие возможности, ни пуленепробиваемые, ни удаленно простые.

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