简体   繁体   中英

Conditional formatting with udf issues with Office 2016 / Office 365

I have a UDF that checks for the existence of a comment. I use this in CF because I want to colour a cell if 1. The cell is not blank and 2. There is no comment. This has worked just fine with 2007 and 2010 but now I have 2016 and Excel has gone a little bit weird on me.

UDF:

Function HasCmt(Rng As Range) 
    Application.Volatile 

    HasCmt = IIf(Not Rng.Comment Is Nothing, True, False) 

End Function

CF: =AND(NOT(ISBLANK(B6)),HasCmt(B6)=FALSE)

Now when I meet the criteria, the formatting is applied and then goes away again. If I disable Automatic Calculation it behaves normally, until I recalculate. I also get errors upon saving the document. 'Calculation is incomplete...'.

Does anybody know a fix I can apply to my many workbooks I have that use this CF? Did something change in the 2016 Excel offering?

Any help would be greatly appreciated.

Thanks

It seems that any volatile functions in the workbook (or any workbook within the application instance) were generating repeated calculation event calls and the UDF was running on top of itself. Conditional formatting is 'refreshed' on every calculation cycle much as a volatile function is. Using the Application.Volatile method within the UDF itself was further complicating matters.

I wrote several versions of a modified UDF and once I got a stable version, I stripped back the overhead until I had the bare minimum that worked well.

Option Explicit

Function hasComment(rng As Range) As Boolean
    'reports true for non-blank with a comment
    Application.EnableEvents = False
    If Not IsEmpty(rng) Then _
        hasComment = CBool(Not rng.Comment Is Nothing)
    DoEvents
    Application.EnableEvents = True
End Function

Function hasNoComment(rng As Range) As Boolean
    'reports true for non-blank with no comment
    Application.EnableEvents = False
    If Not IsEmpty(rng) Then _
        hasNoComment = Not CBool(Not rng.Comment Is Nothing)
    DoEvents
    Application.EnableEvents = True
End Function

Essentially, the Application.EnableEvents property is temporarily suspended. This restricts volatile functions from retriggering calculation events. The DoEvents function temporarily suspends reiterative execution and allows the application message queue to catch up.

This works well as the primary function within a conditional formatting rule covering several hundred cells on a worksheet containing a few hundred volatile functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM