Forum Discussion

ecovonrein's avatar
ecovonrein
Iron Contributor
Feb 02, 2023

Idea needed to stop cell from calculating to preserve its value

The formula

 

F5 = IF(F4,F5,F6)

 

generates a circular reference when

 

F4 = TRUE.

 

That is a great shame because, while narrowly true, the reference to itself is harmless since the THEN formula does not alter the value in F5.  It would be a neat way of saying "Hang on to what you got when F4 = TRUE, otherwise refresh what you got from F6."

 

Any ideas how to accomplish the preservation of a value outside a VBA macro to Copy/Paste?

 

I have the issue of a model stepping thru time and I want to preserve the result of a plan calculation after that calculation has been turned off by the march of model time.  Or to reactivate it when resetting the model time backwards.


PS:  I don't fancy setting File/Options/Formulas/Enable iterative calculation to 1 (though I suppose that it would do the trick).

  • ecovonrein's avatar
    ecovonrein
    Iron Contributor

    As far as VBA involvement goes, this Module is kind-of cute:

    Option Explicit
    
    Dim liveMap As New Dictionary
    
    Public Sub sweepDictionary(sn As String)
        If liveMap.Exists(sn) Then
            Dim d As Variant
            Set d = liveMap(sn)
        
            Dim k As Variant
            For Each k In d.keys
                Dim addrCache As Variant
                addrCache = Split(d(k), "!")
                Worksheets(addrCache(0)).Range(addrCache(1)) = Range(k)
            Next
        
            liveMap.Remove sn
        End If
    End Sub
    
    Public Function ifCache(aBool As Boolean, thenLive, elseCache) As Variant
        If aBool Then
            If Not liveMap.Exists(thenLive.Parent.Name) Then
                Set liveMap(thenLive.Parent.Name) = New Dictionary
            End If
            
            liveMap(thenLive.Parent.Name)(thenLive.Address) = _
                elseCache.Parent.Name & "!" & elseCache.Address
    
            ifCache = thenLive
        Else
            ifCache = elseCache
        End If
    End Function

    Needs to be augmented by a basic invocation code inside every Worksheet object that wants to use ifCache:

    Private Sub Worksheet_Calculate()
        sweepDictionary Me.Name
    End Sub

    With that scaffolding in place, it is now possible to produce the desired functionality:

     

    G5 = ifCache(F4,F5,F6)

     

    F5 sits in the calculation tree and F6 receives a copy for as long as F4 is TRUE.  G5 receives F5 so long as F4 is TRUE, otherwise F6.

     

    But it does require the spreadsheet receiver to enable VBA.  So if there were a Lambda solution, that would be preferable.

      • PipFinyx's avatar
        PipFinyx
        Copper Contributor
        That is very neat!

        Wondering if this could be a request to MS to add a self reference to a formula without having to turn on iterative calculations - e.g. a function called PREV() which would return the value of the current cell before the calculation. Then

        =IF(F4,F5,F6)

        becomes

        =IF(F4,PREV(),F6)
  • PipFinyx's avatar
    PipFinyx
    Copper Contributor

    I can't see how to do this other than with iterative calculation or VBA.

     

    I originally posted to turn on iterative calculation but I see you don't want to do that! Any specific reason or just nervousness?

    • ecovonrein's avatar
      ecovonrein
      Iron Contributor
      Three reasons: 1) It does not port. You can write spreadsheets like that but you cannot force the user's Excel to be configured in this way. It is an arcane non-default setting few people are familiar with. For good reasons (to follow). 2) It slows down calculations. 3) It makes the detection of accidental circular references trickier.

      I am not a fan.
    • PipFinyx's avatar
      PipFinyx
      Copper Contributor
      This sort of works....

      G25 is where I want my preserved calculation
      F25 is set to Y to calculate, otherwise it won't

      In G25 put
      =LET(zz, INDIRECT("G25"), IF(F25="Y",10/5,zz))

      You still get the error pop-up if you set F25 to N but it preserves the calculation anyway

      • ecovonrein's avatar
        ecovonrein
        Iron Contributor

        Hm ... Not a fan of INDIRECT either. 😉 And no fan of error pop-ups at all. 🙂 Appreciate your input.

Resources