Forum Discussion
ecovonrein
Feb 02, 2023Iron Contributor
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).
- ecovonreinIron 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.
- ecovonreinIron Contributor
In case anyone ever finds here, I tidied and tightened up the earlier VBA code. Test sheet attached.
- PipFinyxCopper ContributorThat 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)
- PipFinyxCopper 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?
- ecovonreinIron ContributorThree 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. - PipFinyxCopper ContributorThis 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- ecovonreinIron Contributor
Hm ... Not a fan of INDIRECT either. 😉 And no fan of error pop-ups at all. 🙂 Appreciate your input.