[Libreoffice-commits] core.git: sc/source
Eike Rathke
erack at redhat.com
Wed Jun 20 21:29:12 UTC 2018
sc/source/core/data/formulacell.cxx | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
New commits:
commit eb678c01d35a485b9f79009c126e296d9e811d36
Author: Eike Rathke <erack at redhat.com>
Date: Wed Jun 20 20:00:23 2018 +0200
Prepare for Excel's dirty circular references iteration behaviour
In which either convergence is detected or N iterations are
executed and the result is displayed no matter what. Which would
"do N iteration steps" but never detect non-convergence.
Enable that only with an additional option where the user
specifies s/he doesn't want to be informed of non-convergence
errors.
Change-Id: I3caba0c200e16514e39ea46d7f899afc05a5a2cc
Reviewed-on: https://gerrit.libreoffice.org/56183
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Eike Rathke <erack at redhat.com>
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 661b0940eaf6..2fd26955891c 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1622,12 +1622,15 @@ void ScFormulaCell::Interpret()
}
// Start at 1, init things.
rRecursionHelper.StartIteration();
- // Mark all cells being in iteration.
+ // Mark all cells being in iteration. Reset results to
+ // original values, formula cells have been interpreted
+ // already, discard that step.
for (ScFormulaRecursionList::const_iterator aIter(
rRecursionHelper.GetIterationStart()); aIter !=
rRecursionHelper.GetIterationEnd(); ++aIter)
{
ScFormulaCell* pIterCell = (*aIter).pCell;
+ pIterCell->aResult = (*aIter).aPreviousResult;
pIterCell->bIsIterCell = true;
}
}
@@ -1636,7 +1639,8 @@ void ScFormulaCell::Interpret()
for ( ; rRecursionHelper.GetIteration() <= nIterMax && !rDone;
rRecursionHelper.IncIteration())
{
- rDone = true;
+ rDone = false;
+ bool bFirst = true;
for ( ScFormulaRecursionList::iterator aIter(
rRecursionHelper.GetIterationStart()); aIter !=
rRecursionHelper.GetIterationEnd() &&
@@ -1652,7 +1656,15 @@ void ScFormulaCell::Interpret()
pIterCell->InterpretTail( pDocument->GetNonThreadedContext(), SCITP_FROM_ITERATION);
pDocument->DecInterpretLevel();
}
- rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty();
+ if (bFirst)
+ {
+ rDone = !pIterCell->IsDirtyOrInTableOpDirty();
+ bFirst = false;
+ }
+ else if (rDone)
+ {
+ rDone = !pIterCell->IsDirtyOrInTableOpDirty();
+ }
}
if (rRecursionHelper.IsInReturn())
{
@@ -1687,12 +1699,26 @@ void ScFormulaCell::Interpret()
pIterCell->bIsIterCell = false;
pIterCell->nSeenInIteration = 0;
pIterCell->bRunning = (*aIter).bOldRunning;
+ pIterCell->ResetDirty();
+ // The difference to Excel is that Excel does not
+ // produce an error for non-convergence thus a
+ // delta of 0.001 still works to execute the
+ // maximum number of iterations and display the
+ // results no matter if the result anywhere reached
+ // near delta, but also never indicates whether the
+ // result actually makes sense in case of
+ // non-counter context. Calc does check the delta
+ // in every case. If we wanted to support what
+ // Excel does then add another option "indicate
+ // non-convergence error" (default on) and execute
+ // the following block only if set.
+#if 1
// If one cell didn't converge, all cells of this
// circular dependency don't, no matter whether
// single cells did.
- pIterCell->ResetDirty();
pIterCell->aResult.SetResultError( FormulaError::NoConvergence);
pIterCell->bChanged = true;
+#endif
}
}
// End this iteration and remove entries.
More information about the Libreoffice-commits
mailing list