From 6fc21353bb30e71e2fc4d47394bf7ec2e704a454 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Fri, 14 Jun 2024 13:20:31 +0500 Subject: [PATCH] tdf#68034: set the variable cell to value temporarily if needed Change-Id: I35fed710862ed87c477686e26bc8c82379c5e5a2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168854 Reviewed-by: Xisco Fauli Reviewed-by: Mike Kaganski Tested-by: Xisco Fauli Tested-by: Jenkins --- sc/source/core/data/documen4.cxx | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index 61f493b8d6fa..76c1cafb0310 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -80,11 +80,10 @@ bool ScDocument::Solver(SCCOL nFCol, SCROW nFRow, SCTAB nFTab, double fTargetVal = 0.0; { CellType eFType = GetCellType(nFCol, nFRow, nFTab); - CellType eVType = GetCellType(nVCol, nVRow, nVTab); // #i108005# convert target value to number using default format, // as previously done in ScInterpreter::GetDouble sal_uInt32 nFIndex = 0; - if ( eFType == CELLTYPE_FORMULA && eVType == CELLTYPE_VALUE && + if ( eFType == CELLTYPE_FORMULA && FetchTable(nVTab) && ValidColRow(nVCol, nVRow) && GetFormatTable()->IsNumberFormat( sValStr, nFIndex, fTargetVal ) ) { ScAddress aFormulaAdr( nFCol, nFRow, nFTab ); @@ -94,28 +93,30 @@ bool ScDocument::Solver(SCCOL nFCol, SCROW nFRow, SCTAB nFTab, if (pFormula) { bool bDoneIteration = false; - ScAddress aValueAdr( nVCol, nVRow, nVTab ); - double* pVCell = GetValueCell( aValueAdr ); - - ScRange aVRange( aValueAdr, aValueAdr ); // for SetDirty - // Original value to be restored later if necessary - double fSaveVal = *pVCell; + const ScAddress aValueAdr(nVCol, nVRow, nVTab); + const ScRange aVRange(aValueAdr, aValueAdr); // for SetDirty const sal_uInt16 nMaxIter = 100; const double fEps = 1E-10; const double fDelta = 1E-6; - double fBestX, fXPrev; - double fBestF, fFPrev; - fBestX = fXPrev = fSaveVal; + double fXPrev = GetValue(aValueAdr); + double fBestX = fXPrev; + + // Original value to be restored later if necessary + const ScCellValue aSaveVal(GetRefCellValue(aValueAdr)); + const bool changeCellType = aSaveVal.getType() != CELLTYPE_VALUE; + if (changeCellType) + SetValue(aValueAdr, fXPrev); + double* pVCell = GetValueCell(aValueAdr); pFormula->Interpret(); bool bError = ( pFormula->GetErrCode() != FormulaError::NONE ); // bError always corresponds with fF - fFPrev = pFormula->GetValue() - fTargetVal; + double fFPrev = pFormula->GetValue() - fTargetVal; - fBestF = fabs( fFPrev ); + double fBestF = fabs( fFPrev ); if ( fBestF < fDelta ) bDoneIteration = true; @@ -238,7 +239,10 @@ bool ScDocument::Solver(SCCOL nFCol, SCROW nFRow, SCTAB nFTab, { nX = fBestX; } - *pVCell = fSaveVal; + if (changeCellType) + aSaveVal.commit(*this, aValueAdr); + else + *pVCell = aSaveVal.getDouble(); SetDirty( aVRange, false ); pFormula->Interpret(); }