[Libreoffice-commits] .: Branch 'libreoffice-4-0' - 16 commits - formula/inc formula/source sc/inc sc/qa sc/source sc/util
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Sat Dec 15 15:01:01 PST 2012
formula/inc/formula/compiler.hrc | 8
formula/inc/formula/opcode.hxx | 4
formula/source/core/resource/core_resource.src | 25
formula/source/ui/dlg/parawin.cxx | 45
sc/inc/helpids.h | 4
sc/inc/sc.hrc | 1
sc/inc/scmatrix.hxx | 1
sc/qa/unit/ucalc.cxx | 4
sc/source/core/data/funcdesc.cxx | 58 +
sc/source/core/inc/interpre.hxx | 19
sc/source/core/inc/parclass.hxx | 6
sc/source/core/tool/interpr1.cxx | 1233 ++++++++++++++++---------
sc/source/core/tool/interpr4.cxx | 4
sc/source/core/tool/parclass.cxx | 321 +++---
sc/source/core/tool/scmatrix.cxx | 45
sc/source/filter/excel/excform.cxx | 3
sc/source/filter/excel/xeformula.cxx | 5
sc/source/filter/excel/xicontent.cxx | 4
sc/source/filter/excel/xlformula.cxx | 17
sc/source/filter/inc/xlformula.hxx | 3
sc/source/filter/oox/formulabase.cxx | 19
sc/source/ui/formdlg/dwfunctr.cxx | 10
sc/source/ui/src/scfuncs.src | 162 +++
sc/source/ui/unoobj/appluno.cxx | 8
sc/source/ui/view/cellsh.cxx | 9
sc/util/hidother.src | 10
26 files changed, 1430 insertions(+), 598 deletions(-)
New commits:
commit 789ec89fceb949eee482ecb7731a3d7b1ac0660e
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 23:42:45 2012 +0100
check conditions before checking for matrix fragment
Was omitted in ab0096ed68cdc08906f518d3499a8e1afc5ba80c
Change-Id: If3e1c141f02751ca7e6104ba21c246926fca843d
(cherry picked from commit 63e10bf2383d22a5b3fafd95a688c2389f0076bc)
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 6fbe22d..72c8be3 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -150,15 +150,18 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
case FID_FILL_TO_RIGHT: // fill to left / right
{
bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0);
- bDisable = pDoc->HasSelectedBlockMatrixFragment(
- nCol1, nRow1, nCol1, nRow2, rMark ); // first column
+ if ( !bDisable && bEditable )
+ { // do not damage matrix
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol1, nRow2, rMark ); // first column
+ }
}
break;
case FID_FILL_TO_LEFT:
{
bDisable = (!bSimpleArea) || (nCol1 == MAXCOL && nCol2 == MAXCOL);
if ( !bDisable && bEditable )
- { // Matrix nicht zerreissen
+ { // do not damage matrix
bDisable = pDoc->HasSelectedBlockMatrixFragment(
nCol2, nRow1, nCol2, nRow2, rMark ); // last column
}
commit a3588fefc9d50d7ff51f78859690fc30811259f4
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 23:29:35 2012 +0100
add missing *IFS pieces to Excel filter
These were omitted in ba950a50b0d0863e18ef781214eaaff9a8684790 because
oox/source/xls/formulabase.cxx was moved to
source/filter/oox/formulabase.cxx
AVERAGEIF, AVERAGEIFS, COUNTIFS, SUMIFS
Merged from Apache OO, parts of
http://svn.apache.org/viewvc?rev=1381452&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Daniel Rentz [dr] <daniel.rentz at oracle.com>
Original Committer: Daniel Rentz [dr] <daniel.rentz at oracle.com>
# HG changeset patch
# User Daniel Rentz [dr] <daniel.rentz at oracle.com>
# Date 1299664669 -3600
# Node ID 89feb2fb2947d76a15e2de8bc1def1edf20e4f88
# Parent 1bf6d73db8a4ee709aa4d9d9d827efafc9c611d2
Change-Id: I0756e1da4aa2acaefb86b5813e047b2768c192a1
(cherry picked from commit 9a0bc6d06e30377d2ddf05bf5975dc8c850c8f97)
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index d8a1d26..a6f7e453 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -712,10 +712,10 @@ static const FunctionData saFuncTableOox[] =
{ 0, "CUBESET", 478, NOID, 2, 5, V, { VR, RX, VR }, 0 },
{ 0, "CUBESETCOUNT", 479, NOID, 1, 1, V, { VR }, 0 },
{ 0, "IFERROR", 480, NOID, 2, 2, V, { VO, RO }, 0 },
- { 0, "COUNTIFS", 481, NOID, 2, MX, V, { RO, VR }, FUNCFLAG_PARAMPAIRS },
- { 0, "SUMIFS", 482, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS },
- { 0, "AVERAGEIF", 483, NOID, 2, 3, V, { RO, VR, RO }, 0 },
- { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS }
+ { "COUNTIFS", "COUNTIFS", 481, NOID, 2, MX, V, { RO, VR }, FUNCFLAG_MACROCALL | FUNCFLAG_PARAMPAIRS },
+ { "SUMIFS", "SUMIFS", 482, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_MACROCALL | FUNCFLAG_PARAMPAIRS },
+ { "AVERAGEIF", "AVERAGEIF", 483, NOID, 2, 3, V, { RO, VR, RO }, FUNCFLAG_MACROCALL },
+ { "AVERAGEIFS", "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_MACROCALL | FUNCFLAG_PARAMPAIRS }
};
/** Functions defined by OpenFormula, but not supported by Calc or by Excel. */
@@ -776,8 +776,6 @@ FunctionParamInfoIterator::FunctionParamInfoIterator( const FunctionInfo& rFuncI
mpParamInfoEnd( rFuncInfo.mpParamInfos + FUNCINFO_PARAMINFOCOUNT ),
mbParamPairs( rFuncInfo.mbParamPairs )
{
- OSL_ENSURE( !mbParamPairs || (mpParamInfo + 1 < mpParamInfoEnd),
- "FunctionParamInfoIterator::FunctionParamInfoIterator - expecting at least 2 infos for paired parameters" );
}
bool FunctionParamInfoIterator::isCalcOnlyParam() const
@@ -797,12 +795,12 @@ FunctionParamInfoIterator& FunctionParamInfoIterator::operator++()
// move pointer to next entry, if something explicit follows
if( (mpParamInfo + 1 < mpParamInfoEnd) && (mpParamInfo[ 1 ].meValid != FUNC_PARAM_NONE) )
++mpParamInfo;
- // points to last info, but parameter pairs expected, move to previous info
- else if( mbParamPairs )
- --mpParamInfo;
// if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
else if( isExcelOnlyParam() || isCalcOnlyParam() )
mpParamInfo = 0;
+ // points to last info, but parameter pairs expected, move to previous info
+ else if( mbParamPairs )
+ --mpParamInfo;
// otherwise: repeat last parameter class
}
return *this;
@@ -867,8 +865,7 @@ FunctionProviderImpl::FunctionProviderImpl( FilterType eFilter, BiffType eBiff,
initFuncs( saFuncTableBiff5, STATIC_ARRAY_END( saFuncTableBiff5 ), nMaxParam, bImportFilter );
if( eBiff >= BIFF8 )
initFuncs( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ), nMaxParam, bImportFilter );
- if( eFilter == FILTER_OOXML )
- initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter );
+ initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter );
initFuncs( saFuncTableOdf, STATIC_ARRAY_END( saFuncTableOdf ), nMaxParam, bImportFilter );
}
commit b9e497bff826458970942483cad290d78597ef85
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 22:05:06 2012 +0100
AVERAGEIFS with FUNCFLAG_PARAMPAIRS
Change-Id: I51fa0259df84327db7dd07ae9ed5b109d40b6660
(cherry picked from commit cc036a9b113c76cefba964cdac5a6f941c7a314c)
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index 3a9b742..d8a1d26 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -715,7 +715,7 @@ static const FunctionData saFuncTableOox[] =
{ 0, "COUNTIFS", 481, NOID, 2, MX, V, { RO, VR }, FUNCFLAG_PARAMPAIRS },
{ 0, "SUMIFS", 482, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS },
{ 0, "AVERAGEIF", 483, NOID, 2, 3, V, { RO, VR, RO }, 0 },
- { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, 0 }
+ { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS }
};
/** Functions defined by OpenFormula, but not supported by Calc or by Excel. */
commit 9578d05b9919115eeac2203d7b37746f0ce9540d
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 21:24:22 2012 +0100
EvalMatrix<XorEvaluator> for Xor
Change-Id: Ib0fdf7f8916a9d31fbcbedad925361d0cbe03b10
(cherry picked from commit 98a4e4f2ad405b60484f033570e2d2164656007b)
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 810b8c2..66dcb2f 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -912,6 +912,14 @@ struct OrEvaluator
OrEvaluator() : mbResult(false) {}
};
+struct XorEvaluator
+{
+ bool mbResult;
+ void operate(double fVal) { mbResult ^= (fVal != 0.0); }
+ bool result() const { return mbResult; }
+ XorEvaluator() : mbResult(false) {}
+};
+
// Do not short circuit logical operations, in case there are error values
// these need to be propagated even if the result was determined earlier.
template <typename _Evaluator>
@@ -959,26 +967,7 @@ double ScMatrixImpl::Xor() const
{
// All elements must be of value type.
// True if an odd number of elements have a non-zero value.
- bool bXor = false;
- size_t nRows = maMat.size().row, nCols = maMat.size().column;
- for (size_t i = 0; i < nRows; ++i)
- {
- for (size_t j = 0; j < nCols; ++j)
- {
- mdds::mtm::element_t eType = maMat.get_type(i, j);
- if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
- // assuming a CompareMat this is an error
- return CreateDoubleError(errIllegalArgument);
-
- double fVal = maMat.get_numeric(i, j);
- if (!::rtl::math::isFinite(fVal))
- // DoubleError
- return fVal;
-
- bXor ^= (fVal != 0.0);
- }
- }
- return bXor;
+ return EvalMatrix<XorEvaluator>(maMat);
}
namespace {
commit a971c957757fe8bdf9b7c61b5c27b75b18dd67f5
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 20:46:41 2012 +0100
EvalMatrix: do not short circuit, propagate errors
Change-Id: I3118fb2a4d30e1626a05e9872b34a3c33bd487be
(cherry picked from commit c86a9c4f045dfc8bbcad27cf36f1c6a8178a48a7)
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 259d747..810b8c2 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -296,6 +296,7 @@ void compareMatrix(MatrixImplType& rMat)
double fVal = rMat.get_numeric(i, j);
if (!::rtl::math::isFinite(fVal))
+ /* FIXME: this silently skips an error instead of propagating it! */
continue;
bool b = aComp(fVal);
@@ -897,20 +898,24 @@ namespace {
struct AndEvaluator
{
- bool isBadElem(double fVal) const { return fVal == 0; }
- bool returnOnElem() const { return false; }
- bool returnOnAllElems() const { return true; }
+ bool mbResult;
+ void operate(double fVal) { mbResult &= (fVal != 0.0); }
+ bool result() const { return mbResult; }
+ AndEvaluator() : mbResult(true) {}
};
struct OrEvaluator
{
- bool isBadElem(double fVal) const { return fVal != 0; }
- bool returnOnElem() const { return true; }
- bool returnOnAllElems() const { return false; }
+ bool mbResult;
+ void operate(double fVal) { mbResult |= (fVal != 0.0); }
+ bool result() const { return mbResult; }
+ OrEvaluator() : mbResult(false) {}
};
+// Do not short circuit logical operations, in case there are error values
+// these need to be propagated even if the result was determined earlier.
template <typename _Evaluator>
-bool EvalMatrix(const MatrixImplType& rMat)
+double EvalMatrix(const MatrixImplType& rMat)
{
_Evaluator aEval;
size_t nRows = rMat.size().row, nCols = rMat.size().column;
@@ -928,11 +933,10 @@ bool EvalMatrix(const MatrixImplType& rMat)
// DoubleError
return fVal;
- if (aEval.isBadElem(fVal))
- return aEval.returnOnElem();
+ aEval.operate(fVal);
}
}
- return aEval.returnOnAllElems();
+ return aEval.result();
}
}
commit d305e15265bc6e961bc1244e7cae6e99c2013f13
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 20:25:33 2012 +0100
aString not rString
Change-Id: Idb1f2db3377bbbf71067a27944b2f07865798972
(cherry picked from commit cf309b04a0780c042393bcacf1666ce6053cdc2c)
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 270236b..0b86108 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5540,7 +5540,7 @@ void ScInterpreter::ScCountIf()
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountIf" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
- String rString;
+ String aString;
double fVal = 0.0;
bool bIsString = true;
switch ( GetStackType() )
@@ -5568,11 +5568,11 @@ void ScInterpreter::ScCountIf()
bIsString = false;
}
else
- GetCellString(rString, pCell);
+ GetCellString(aString, pCell);
break;
case CELLTYPE_STRING :
case CELLTYPE_EDIT :
- GetCellString(rString, pCell);
+ GetCellString(aString, pCell);
break;
default:
fVal = 0.0;
@@ -5585,12 +5585,12 @@ void ScInterpreter::ScCountIf()
case svExternalDoubleRef:
{
ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
- rString);
+ aString);
bIsString = ScMatrix::IsNonValueType( nType);
}
break;
case svString:
- rString = GetString();
+ aString = GetString();
break;
default:
{
@@ -5677,7 +5677,7 @@ void ScInterpreter::ScCountIf()
}
else
{
- rParam.FillInExcelSyntax(rString, 0);
+ rParam.FillInExcelSyntax(aString, 0);
sal_uInt32 nIndex = 0;
bool bNumber = pFormatter->IsNumberFormat(
rItem.maString, nIndex, rItem.mfVal);
@@ -5762,7 +5762,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
while (nParamCount > 1 && !nGlobalError)
{
// take criteria
- String rString;
+ String aString;
fVal = 0.0;
bool bIsString = true;
switch ( GetStackType() )
@@ -5788,11 +5788,11 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
bIsString = false;
}
else
- GetCellString(rString, pCell);
+ GetCellString(aString, pCell);
break;
case CELLTYPE_STRING :
case CELLTYPE_EDIT :
- GetCellString(rString, pCell);
+ GetCellString(aString, pCell);
break;
default:
fVal = 0.0;
@@ -5801,12 +5801,12 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
}
break;
case svString:
- rString = GetString();
+ aString = GetString();
break;
case svMatrix :
case svExternalDoubleRef:
{
- ScMatValType nType = GetDoubleOrStringFromMatrix( fVal, rString);
+ ScMatValType nType = GetDoubleOrStringFromMatrix( fVal, aString);
bIsString = ScMatrix::IsNonValueType( nType);
}
break;
@@ -5822,7 +5822,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
bIsString = false;
}
else
- rString = pToken->GetString();
+ aString = pToken->GetString();
}
}
break;
@@ -5928,7 +5928,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
}
else
{
- rParam.FillInExcelSyntax(rString, 0);
+ rParam.FillInExcelSyntax(aString, 0);
sal_uInt32 nIndex = 0;
bool bNumber = pFormatter->IsNumberFormat(
rItem.maString, nIndex, rItem.mfVal);
commit 3d13d51660f9365b05df532d69f253561575c00b
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 20:18:57 2012 +0100
ScInterpreter::IterateParametersIfs() with external references
Added handling of svExternalSingleRef and svExternalDoubleRef for
SUMIFS, AVERAGEIFS and COUNTIFS.
Change-Id: I99bf6860f2bda5a99aeb85d4e4971032b1c7da0d
(cherry picked from commit 470a581bcb7b1ffeecb434560ccd8ef0d1ba6d73)
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index d2bc4a4..270236b 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5804,11 +5804,28 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
rString = GetString();
break;
case svMatrix :
+ case svExternalDoubleRef:
{
ScMatValType nType = GetDoubleOrStringFromMatrix( fVal, rString);
bIsString = ScMatrix::IsNonValueType( nType);
}
break;
+ case svExternalSingleRef:
+ {
+ ScExternalRefCache::TokenRef pToken;
+ PopExternalSingleRef(pToken);
+ if (pToken)
+ {
+ if (pToken->GetType() == svDouble)
+ {
+ fVal = pToken->GetDouble();
+ bIsString = false;
+ }
+ else
+ rString = pToken->GetString();
+ }
+ }
+ break;
default:
{
fVal = GetDouble();
@@ -5848,6 +5865,8 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
nTab2 = nTab1;
break;
case svMatrix:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
pQueryMatrix = PopMatrix();
if (!pQueryMatrix)
@@ -6002,6 +6021,8 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
nMainTab2 = nMainTab1;
break;
case svMatrix:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
pMainMatrix = PopMatrix();
if (!pMainMatrix)
commit c430d6117309c99364857b4470311d0a1b89d7bf
Author: Eike Rathke <erack at redhat.com>
Date: Sat Dec 15 03:51:25 2012 +0100
tabs to spaces
Change-Id: Id832383518af0dd77e401e40512a890265b5d83e
(cherry picked from commit 2a8470dca4726d512a33ac3af4ba140aed86909e)
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index b8fc214..8b0ee14 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -237,10 +237,10 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
String SC_OPCODE_COUNT_EMPTY_CELLS { Text = "COUNTBLANK" ; };
String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; };
String SC_OPCODE_SUM_IF { Text = "SUMIF" ; };
- String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
- String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
- String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
- String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
+ String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
+ String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
+ String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
+ String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; };
String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; };
String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; };
@@ -575,10 +575,10 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
String SC_OPCODE_COUNT_EMPTY_CELLS { Text = "COUNTBLANK" ; };
String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; };
String SC_OPCODE_SUM_IF { Text = "SUMIF" ; };
- String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
- String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
- String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
- String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
+ String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
+ String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
+ String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
+ String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; };
String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; };
String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; };
@@ -1482,22 +1482,22 @@ Resource RID_STRLIST_FUNCTION_NAMES
{
Text [ en-US ] = "SUMIF" ;
};
- String SC_OPCODE_AVERAGE_IF
- {
- Text [ en-US ] = "AVERAGEIF" ;
- };
- String SC_OPCODE_SUM_IFS
- {
- Text [ en-US ] = "SUMIFS" ;
- };
- String SC_OPCODE_AVERAGE_IFS
- {
- Text [ en-US ] = "AVERAGEIFS" ;
- };
- String SC_OPCODE_COUNT_IFS
- {
- Text [ en-US ] = "COUNTIFS" ;
- };
+ String SC_OPCODE_AVERAGE_IF
+ {
+ Text [ en-US ] = "AVERAGEIF" ;
+ };
+ String SC_OPCODE_SUM_IFS
+ {
+ Text [ en-US ] = "SUMIFS" ;
+ };
+ String SC_OPCODE_AVERAGE_IFS
+ {
+ Text [ en-US ] = "AVERAGEIFS" ;
+ };
+ String SC_OPCODE_COUNT_IFS
+ {
+ Text [ en-US ] = "COUNTIFS" ;
+ };
String SC_OPCODE_LOOKUP
{
Text [ en-US ] = "LOOKUP" ;
commit 5a706356f23d35e699d696b58b7e30a313945bb7
Author: Marina Plakalovic <makkica at openoffice.org>
Date: Sat Dec 15 03:41:47 2012 +0100
calcishmakkica: #i114428# merge some XOR related code
Merged from Apache OO with adaptions, parts of
http://svn.apache.org/viewvc?rev=1381446&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Marina Plakalovic <makkica at openoffice.org>
Original Committer: Eike Rathke [er] <eike.rathke at oracle.com>
# HG changeset patch
# User Eike Rathke [er] <eike.rathke at oracle.com>
# Date 1284060031 -7200
# Node ID 528da6bfd0daed4355d745590d5ac3a319b08fb4
# Parent 237cb91dd986ff11eb100cc631206cda102e91f7
Change-Id: If456792f23429a80582a48b022d268e6179316a1
(cherry picked from commit 07df025a730be05d087559b939858260df003b97)
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index c552eb1..b8fc214 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -385,6 +385,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
String SC_OPCODE_GREATER_EQUAL { Text = ">=" ; };
String SC_OPCODE_AND { Text = "AND" ; };
String SC_OPCODE_OR { Text = "OR" ; };
+ String SC_OPCODE_XOR { Text = "XOR" ; };
String SC_OPCODE_INTERSECT { Text = "!" ; };
String SC_OPCODE_UNION { Text = "~" ; };
String SC_OPCODE_RANGE { Text = ":" ; };
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 84d3e5a..bf1f15f 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -340,6 +340,7 @@ public:
double And() const; // logical AND of all matrix values, or NAN
double Or() const; // logical OR of all matrix values, or NAN
+ double Xor() const; // logical XOR of all matrix values, or NAN
IterateResult Sum(bool bTextAsZero) const;
IterateResult SumSquare(bool bTextAsZero) const;
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 43109e1..d2bc4a4 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1435,7 +1435,9 @@ void ScInterpreter::ScXor()
bHaveValue = true;
nRes ^= ( GetCellValue( aAdr, pCell ) != 0.0 );
}
- // else: Xcl raises no error here
+ /* TODO: set error? Excel doesn't have XOR, but
+ * doesn't set an error in this case for AND and
+ * OR. */
}
}
break;
@@ -1471,11 +1473,12 @@ void ScInterpreter::ScXor()
if ( pMat )
{
bHaveValue = true;
- double fVal = pMat->Or();
+ double fVal = pMat->Xor();
sal_uInt16 nErr = GetDoubleErrorValue( fVal );
if ( nErr )
{
SetError( nErr );
+ nRes = 0;
}
else
nRes ^= ( fVal != 0.0 );
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index cad0ab0..259d747 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -376,6 +376,7 @@ public:
void CompareGreaterEqual();
double And() const;
double Or() const;
+ double Xor() const;
ScMatrix::IterateResult Sum(bool bTextAsZero) const;
ScMatrix::IterateResult SumSquare(bool bTextAsZero) const;
@@ -950,6 +951,32 @@ double ScMatrixImpl::Or() const
return EvalMatrix<OrEvaluator>(maMat);
}
+double ScMatrixImpl::Xor() const
+{
+ // All elements must be of value type.
+ // True if an odd number of elements have a non-zero value.
+ bool bXor = false;
+ size_t nRows = maMat.size().row, nCols = maMat.size().column;
+ for (size_t i = 0; i < nRows; ++i)
+ {
+ for (size_t j = 0; j < nCols; ++j)
+ {
+ mdds::mtm::element_t eType = maMat.get_type(i, j);
+ if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
+ // assuming a CompareMat this is an error
+ return CreateDoubleError(errIllegalArgument);
+
+ double fVal = maMat.get_numeric(i, j);
+ if (!::rtl::math::isFinite(fVal))
+ // DoubleError
+ return fVal;
+
+ bXor ^= (fVal != 0.0);
+ }
+ }
+ return bXor;
+}
+
namespace {
struct SumOp
@@ -1376,6 +1403,11 @@ double ScMatrix::Or() const
return pImpl->Or();
}
+double ScMatrix::Xor() const
+{
+ return pImpl->Xor();
+}
+
ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero) const
{
return pImpl->Sum(bTextAsZero);
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index 1080cc9..1b68b2e 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -2696,7 +2696,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 3 // Description of Parameter 1
{
- Text [ en-US ] = "Logical value 1, logical value 2, ... are 1 to 30 conditions to be tested and which returns either TRUE or FALSE." ;
+ Text [ en-US ] = "Logical value 1, logical value 2, ... are 1 to 30 conditions to be tested and which return either TRUE or FALSE." ;
};
};
// -=*# Resource for function UND #*=-
commit be42c9c1087e18554940525231305a2c7e699acc
Author: Daniel Rentz [dr] <daniel.rentz at oracle.com>
Date: Sat Dec 15 00:57:00 2012 +0100
calcishmakkica: #i117283# support new functions in Excel filters
AVERAGEIF, AVERAGEIFS, COUNTIFS, SUMIFS
Merged from Apache OO with adaptions.
http://svn.apache.org/viewvc?rev=1381452&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Daniel Rentz [dr] <daniel.rentz at oracle.com>
Original Committer: Daniel Rentz [dr] <daniel.rentz at oracle.com>
# HG changeset patch
# User Daniel Rentz [dr] <daniel.rentz at oracle.com>
# Date 1299664669 -3600
# Node ID 89feb2fb2947d76a15e2de8bc1def1edf20e4f88
# Parent 1bf6d73db8a4ee709aa4d9d9d827efafc9c611d2
Change-Id: Ia70075284c5921faea58cae986e4e5eb090b1fab
(cherry picked from commit ba950a50b0d0863e18ef781214eaaff9a8684790)
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 822f8d1..b66b507 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -191,7 +191,8 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s
TokenId nMerk0;
const sal_Bool bRangeName = eFT == FT_RangeName;
const sal_Bool bSharedFormula = eFT == FT_SharedFormula;
- const sal_Bool bRNorSF = bRangeName || bSharedFormula;
+ const sal_Bool bConditional = eFT == FT_CondFormat;
+ const sal_Bool bRNorSF = bRangeName || bSharedFormula || bConditional;
ScSingleRefData aSRD;
ScComplexRefData aCRD;
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
index bc66024..d450dfe 100644
--- a/sc/source/filter/excel/xeformula.cxx
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -202,11 +202,14 @@ void XclExpFuncData::IncParamInfoIdx()
if( mpParamInfo )
{
// move pointer to next entry, if something explicit follows
- if( (static_cast<size_t>(mpParamInfo - mrFuncInfo.mpParamInfos + 1) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
+ if( (static_cast< size_t >( mpParamInfo - mrFuncInfo.mpParamInfos + 1 ) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
++mpParamInfo;
// if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
mpParamInfo = 0;
+ // points to last info, but parameter pairs expected, move to previous info
+ else if( mrFuncInfo.IsParamPairs() )
+ --mpParamInfo;
// otherwise: repeat last parameter class
}
}
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index f35f530..7e09fb4 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -744,7 +744,7 @@ void XclImpValidationManager::ReadDV( XclImpStream& rStrm )
{
const ScTokenArray* pTokArr = 0;
rFmlaConv.Reset();
- rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+ rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_CondFormat );
// formula converter owns pTokArr -> create a copy of the token array
if( pTokArr )
xTokArr1.reset( pTokArr->Clone() );
@@ -763,7 +763,7 @@ void XclImpValidationManager::ReadDV( XclImpStream& rStrm )
{
const ScTokenArray* pTokArr = 0;
rFmlaConv.Reset();
- rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_RangeName );
+ rFmlaConv.Convert( pTokArr, rStrm, nLen, false, FT_CondFormat );
// formula converter owns pTokArr -> create a copy of the token array
if( pTokArr )
xTokArr2.reset( pTokArr->Clone() );
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index 24c8adb..58b3aa9 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -355,6 +355,19 @@ static const XclFunctionInfo saFuncTable_8[] =
{ ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
};
+/** Functions new in OOXML. */
+static const XclFunctionInfo saFuncTable_Oox[] =
+{
+ { ocCountIfs, NOID, 2, MX, V, { RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
+ { ocCountIfs, 255, 3, MX, V, { RO_E, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
+ { ocSumIfs, NOID, 3, MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
+ { ocSumIfs, 255, 4, MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
+ { ocAverageIf, NOID, 2, 3, V, { RO, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
+ { ocAverageIf, 255, 3, 4, V, { RO_E, RO, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
+ { ocAverageIfs, NOID, 3, MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) },
+ { ocAverageIfs, 255, 4, MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) }
+};
+
#define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \
{ opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \
{ opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }
@@ -420,6 +433,7 @@ XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot )
(this->*pFillFunc)( saFuncTable_5, STATIC_ARRAY_END( saFuncTable_5 ) );
if( eBiff >= EXC_BIFF8 )
(this->*pFillFunc)( saFuncTable_8, STATIC_ARRAY_END( saFuncTable_8 ) );
+ (this->*pFillFunc)( saFuncTable_Oox, STATIC_ARRAY_END( saFuncTable_Oox ) );
(this->*pFillFunc)( saFuncTable_Odf, STATIC_ARRAY_END( saFuncTable_Odf ) );
}
@@ -453,7 +467,8 @@ void XclFunctionProvider::FillXclFuncMap( const XclFunctionInfo* pBeg, const Xcl
{
if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_EXPORTONLY ) )
{
- maXclFuncMap[ pIt->mnXclFunc ] = pIt;
+ if( pIt->mnXclFunc != NOID )
+ maXclFuncMap[ pIt->mnXclFunc ] = pIt;
if( pIt->IsMacroFunc() )
maXclMacroNameMap[ pIt->GetMacroFuncName() ] = pIt;
}
diff --git a/sc/source/filter/inc/xlformula.hxx b/sc/source/filter/inc/xlformula.hxx
index 62c93b6..7768769 100644
--- a/sc/source/filter/inc/xlformula.hxx
+++ b/sc/source/filter/inc/xlformula.hxx
@@ -284,6 +284,7 @@ const size_t EXC_FUNCINFO_PARAMINFO_COUNT = 5; /// Number of parameter
const sal_uInt8 EXC_FUNCFLAG_VOLATILE = 0x01; /// Result is volatile (e.g. NOW() function).
const sal_uInt8 EXC_FUNCFLAG_IMPORTONLY = 0x02; /// Only used in import filter.
const sal_uInt8 EXC_FUNCFLAG_EXPORTONLY = 0x04; /// Only used in export filter.
+const sal_uInt8 EXC_FUNCFLAG_PARAMPAIRS = 0x08; /// Optional parameters are expected to appear in pairs.
// selected function IDs
const sal_uInt16 EXC_FUNCID_IF = 1;
@@ -314,6 +315,8 @@ struct XclFunctionInfo
/** Returns true, if the function is volatile. */
inline bool IsVolatile() const { return ::get_flag( mnFlags, EXC_FUNCFLAG_VOLATILE ); }
+ /** Returns true, if optional parameters are expected to appear in pairs. */
+ inline bool IsParamPairs() const { return ::get_flag( mnFlags, EXC_FUNCFLAG_PARAMPAIRS ); }
/** Returns true, if the function parameter count is fixed. */
inline bool IsFixedParamCount() const { return (mnXclFunc != EXC_FUNCID_EXTERNCALL) && (mnMinParamCount == mnMaxParamCount); }
/** Returns true, if the function is simulated by a macro call. */
commit 5d5ab4368a0ad0d520ca1728282d9fbb8d9f32bd
Author: Eike Rathke [er] <eike.rathke at oracle.com>
Date: Sat Dec 15 00:28:26 2012 +0100
calcishmakkica: init vars
Merged from Apache OO.
http://svn.apache.org/viewvc?rev=1381450&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Eike Rathke [er] <eike.rathke at oracle.com>
Original Committer: Eike Rathke [er] <eike.rathke at oracle.com>
# HG changeset patch
# User Eike Rathke [er] <eike.rathke at oracle.com>
# Date 1298043566 -3600
# Node ID 346e0beefed21519bbb6545bccfea022dd75ed66
# Parent 2416febcae5c81a24b40439f09f91e40a686b911
Change-Id: I5c2b6f9a34336a734bd96e067ec57a2f58d4488c
(cherry picked from commit 65721e490a753178c9e90dbe9eecb70124d94117)
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 435a509..43109e1 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5600,12 +5600,12 @@ void ScInterpreter::ScCountIf()
size_t nRefInList = 0;
while (nParam-- > 0)
{
- SCCOL nCol1;
- SCROW nRow1;
- SCTAB nTab1;
- SCCOL nCol2;
- SCROW nRow2;
- SCTAB nTab2;
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ SCCOL nCol2 = 0;
+ SCROW nRow2 = 0;
+ SCTAB nTab2 = 0;
ScMatrixRef pQueryMatrix;
switch ( GetStackType() )
{
@@ -5819,12 +5819,12 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
// take range
nParam = 1;
nRefInList = 0;
- SCCOL nCol1;
- SCROW nRow1;
- SCTAB nTab1;
- SCCOL nCol2;
- SCROW nRow2;
- SCTAB nTab2;
+ SCCOL nCol1 = 0;
+ SCROW nRow1 = 0;
+ SCTAB nTab1 = 0;
+ SCCOL nCol2 = 0;
+ SCROW nRow2 = 0;
+ SCTAB nTab2 = 0;
ScMatrixRef pQueryMatrix;
switch ( GetStackType() )
{
@@ -5973,12 +5973,12 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
nParam = 1;
nRefInList = 0;
bool bNull = true;
- SCCOL nMainCol1;
- SCROW nMainRow1;
- SCTAB nMainTab1;
- SCCOL nMainCol2;
- SCROW nMainRow2;
- SCTAB nMainTab2;
+ SCCOL nMainCol1 = 0;
+ SCROW nMainRow1 = 0;
+ SCTAB nMainTab1 = 0;
+ SCCOL nMainCol2 = 0;
+ SCROW nMainRow2 = 0;
+ SCTAB nMainTab2 = 0;
ScMatrixRef pMainMatrix;
switch ( GetStackType() )
{
commit 5885fb33c383005af0ec72fb79b6b1af2375b8f4
Author: Eike Rathke [er] <eike.rathke at oracle.com>
Date: Sat Dec 15 00:28:26 2012 +0100
calcishmakkica: WaE wntmsci12
Merged from Apache OO.
http://svn.apache.org/viewvc?rev=1381449&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Eike Rathke [er] <eike.rathke at oracle.com>
Original Committer: Eike Rathke [er] <eike.rathke at oracle.com>
# HG changeset patch
# User Eike Rathke [er] <eike.rathke at oracle.com>
# Date 1297940971 -3600
# Node ID 2416febcae5c81a24b40439f09f91e40a686b911
# Parent 0d84fd3534ea7cda60f795f7dc5d99db58d8cc6e
Change-Id: I46835f0cef9bf83b76e7501a5291f7724b23f871
(cherry picked from commit f28cafdc1d637ffb1409fa104e867ffcf00580f4)
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 7d7b867..435a509 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -6067,8 +6067,8 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
{
if (pResMat->GetDouble( nCol, nRow) == nQueryCount)
{
- aAdr.SetCol( nCol + nMainCol1);
- aAdr.SetRow( nRow + nMainRow1);
+ aAdr.SetCol( static_cast<SCCOL>(nCol) + nMainCol1);
+ aAdr.SetRow( static_cast<SCROW>(nRow) + nMainRow1);
ScBaseCell* pCell = GetCell( aAdr );
if ( HasCellValueData(pCell) )
{
commit d38c4abc5329ca673aef205ca704c965382301f7
Author: Eike Rathke [er] <eike.rathke at oracle.com>
Date: Sat Dec 15 00:06:28 2012 +0100
calcishmakkica: #i90269# #i95144# #i101466#
* For SUMIFS, AVERAGEIFS and COUNTIFS:
* All ranges must be of same dimension and size.
* Bail out if error encountered for any parameter, without calculating
remaining parameters.
* Adapted ScParameterClassification to cope with paired repeated parameters.
* In function resource have a trailing blank for repeated parameters so the
number is appended with a blank between.
Merged from Apache OO with adaptions.
http://svn.apache.org/viewvc?rev=1381448&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Eike Rathke [er] <eike.rathke at oracle.com>
Original Committer: Eike Rathke [er] <eike.rathke at oracle.com>
# HG changeset patch
# User Eike Rathke [er] <eike.rathke at oracle.com>
# Date 1288820521 -3600
# Node ID 79da8a1033b663c919f0dc48799f70256bffa497
# Parent 02cf226fcde498f6fd926d45df497e9fb412fe0f
Change-Id: Ica4faa4e7a46cd5f480cb898785daa51a50ec23b
(cherry picked from commit 9d73ad60be888fd83551367712eb9c1f12f838ce)
diff --git a/sc/source/core/inc/parclass.hxx b/sc/source/core/inc/parclass.hxx
index 6037038..b2500ff 100644
--- a/sc/source/core/inc/parclass.hxx
+++ b/sc/source/core/inc/parclass.hxx
@@ -98,7 +98,7 @@ private:
const static sal_Int32 nMaxParams = 7;
Type nParam[nMaxParams];
- bool bRepeatLast;
+ sal_uInt8 nRepeatLast;
};
// SUNWS7 needs a forward declared friend, otherwise members of the outer
@@ -159,11 +159,11 @@ private:
return 0;
}
- /** Whether last parameter type is repeated. */
+ /** Whether last parameter types are repeated. */
static inline bool HasRepeatParameters( OpCode eOp)
{
return eOp <= SC_OPCODE_LAST_OPCODE_ID
- && pData[eOp].aData.bRepeatLast;
+ && pData[eOp].aData.nRepeatLast > 0;
}
#endif // OSL_DEBUG_LEVEL
};
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 8e59245..7d7b867 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5753,6 +5753,8 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
double fCount = 0.0;
short nParam = 1;
size_t nRefInList = 0;
+ SCCOL nDimensionCols = 0;
+ SCROW nDimensionRows = 0;
while (nParamCount > 1 && !nGlobalError)
{
@@ -5811,6 +5813,9 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
}
}
+ if (nGlobalError)
+ continue; // and bail out, no need to evaluate other arguments
+
// take range
nParam = 1;
nRefInList = 0;
@@ -5860,28 +5865,32 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
SetError( errIllegalParameter);
}
if ( nTab1 != nTab2 )
+ SetError( errIllegalArgument);
+
+ // All reference ranges must be of same dimension and size.
+ if (!nDimensionCols)
+ nDimensionCols = nCol2 - nCol1 + 1;
+ if (!nDimensionRows)
+ nDimensionRows = nRow2 - nRow1 + 1;
+ if ((nDimensionCols != (nCol2 - nCol1 + 1)) || (nDimensionRows != (nRow2 - nRow1 + 1)))
+ SetError ( errIllegalArgument);
+
+ // recalculate matrix values
+ if (nGlobalError == 0)
{
- SetError( errIllegalParameter);
- }
- // initialize temporary result matrix
- if (!pResMat)
- {
- SCSIZE nResC, nResR;
- nResC = nCol2 - nCol1 + 1;
- nResR = nRow2 - nRow1 + 1;
- pResMat = GetNewMat(nResC, nResR);
+ // initialize temporary result matrix
if (!pResMat)
{
- SetError( errIllegalParameter);
- }
- else
- {
- pResMat->FillDouble( 0.0, 0, 0, nResC-1, nResR-1);
+ SCSIZE nResC, nResR;
+ nResC = nCol2 - nCol1 + 1;
+ nResR = nRow2 - nRow1 + 1;
+ pResMat = GetNewMat(nResC, nResR);
+ if (!pResMat)
+ SetError( errIllegalParameter);
+ else
+ pResMat->FillDouble( 0.0, 0, 0, nResC-1, nResR-1);
}
- }
- // recalculate matrix values
- if (nGlobalError == 0)
- {
+
ScQueryParam rParam;
rParam.nRow1 = nRow1;
rParam.nRow2 = nRow2;
@@ -5952,13 +5961,12 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
}
}
}
- else
- {
- SetError( errIllegalParameter);
- }
nParamCount -= 2;
}
+ if (nGlobalError)
+ return 0; // bail out
+
// main range - only for AVERAGEIFS and SUMIFS
if (nParamCount == 1)
{
@@ -6011,9 +6019,15 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
SetError( errIllegalParameter);
}
if ( nMainTab1 != nMainTab2 )
- {
- SetError( errIllegalParameter);
- }
+ SetError( errIllegalArgument);
+
+ // All reference ranges must be of same dimension and size.
+ if ((nDimensionCols != (nMainCol2 - nMainCol1 + 1)) || (nDimensionRows != (nMainRow2 - nMainRow1 + 1)))
+ SetError ( errIllegalArgument);
+
+ if (nGlobalError)
+ return 0; // bail out
+
// end-result calculation
ScAddress aAdr;
aAdr.SetTab( nMainTab1 );
@@ -6084,7 +6098,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
++fCount;
}
}
- //
+
switch( eFunc )
{
case ifSUMIFS: fRes = ::rtl::math::approxAdd( fSum, fMem ); break;
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
index d3ca7f9..ebdbb4a 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -42,151 +42,154 @@
* - OpCodes not specified at all will have at least one and only parameters of
* type Value, no check is done on the count of parameters => no Bounds type
* is returned.
- * - For OpCodes with a variable number of parameters the type of the last
- * parameter specified determines the type of all following parameters.
+ * - For OpCodes with a variable number of parameters the type(s) of the last
+ * repeated parameter(s) specified determine(s) the type(s) of all following
+ * parameters.
*/
const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
{
+ // { OpCode, {{ Type, ... }, nRepeatLast }},
+
// IF() and CHOOSE() are somewhat special, since the ScJumpMatrix is
// created inside those functions and ConvertMatrixParameters() is not
// called for them.
- { ocIf, {{ Array, Reference, Reference }, false }},
- { ocChose, {{ Array, Reference }, true }},
+ { ocIf, {{ Array, Reference, Reference }, 0 }},
+ { ocChose, {{ Array, Reference }, 1 }},
// Other specials.
- { ocOpen, {{ Bounds }, false }},
- { ocClose, {{ Bounds }, false }},
- { ocSep, {{ Bounds }, false }},
- { ocNoName, {{ Bounds }, false }},
- { ocErrCell, {{ Bounds }, false }},
- { ocStop, {{ Bounds }, false }},
- { ocUnion, {{ Reference, Reference }, false }},
- { ocRange, {{ Reference, Reference }, false }},
+ { ocOpen, {{ Bounds }, 0 }},
+ { ocClose, {{ Bounds }, 0 }},
+ { ocSep, {{ Bounds }, 0 }},
+ { ocNoName, {{ Bounds }, 0 }},
+ { ocErrCell, {{ Bounds }, 0 }},
+ { ocStop, {{ Bounds }, 0 }},
+ { ocUnion, {{ Reference, Reference }, 0 }},
+ { ocRange, {{ Reference, Reference }, 0 }},
// Functions with Value parameters only but not in resource.
- { ocBackSolver, {{ Value, Value, Value }, false }},
- { ocTableOp, {{ Value, Value, Value, Value, Value }, false }},
+ { ocBackSolver, {{ Value, Value, Value }, 0 }},
+ { ocTableOp, {{ Value, Value, Value, Value, Value }, 0 }},
// Operators and functions.
- { ocAdd, {{ Array, Array }, false }},
- { ocAmpersand, {{ Array, Array }, false }},
- { ocAnd, {{ Reference }, true }},
- { ocAreas, {{ Reference }, false }},
- { ocAveDev, {{ Reference }, true }},
- { ocAverage, {{ Reference }, true }},
- { ocAverageA, {{ Reference }, true }},
- { ocAverageIf, {{ Reference, Value, Reference }, false }},
- { ocAverageIfs, {{ Reference, Reference, Value }, true }},
- { ocCell, {{ Value, Reference }, false }},
- { ocColumn, {{ Reference }, false }},
- { ocColumns, {{ Reference }, true }},
- { ocCorrel, {{ ForceArray, ForceArray }, false }},
- { ocCount, {{ Reference }, true }},
- { ocCount2, {{ Reference }, true }},
- { ocCountEmptyCells, {{ Reference }, false }},
- { ocCountIf, {{ Reference, Value }, false }},
- { ocCountIfs, {{ Reference, Value }, true }},
- { ocCovar, {{ ForceArray, ForceArray }, false }},
- { ocDBAverage, {{ Reference, Reference, Reference }, false }},
- { ocDBCount, {{ Reference, Reference, Reference }, false }},
- { ocDBCount2, {{ Reference, Reference, Reference }, false }},
- { ocDBGet, {{ Reference, Reference, Reference }, false }},
- { ocDBMax, {{ Reference, Reference, Reference }, false }},
- { ocDBMin, {{ Reference, Reference, Reference }, false }},
- { ocDBProduct, {{ Reference, Reference, Reference }, false }},
- { ocDBStdDev, {{ Reference, Reference, Reference }, false }},
- { ocDBStdDevP, {{ Reference, Reference, Reference }, false }},
- { ocDBSum, {{ Reference, Reference, Reference }, false }},
- { ocDBVar, {{ Reference, Reference, Reference }, false }},
- { ocDBVarP, {{ Reference, Reference, Reference }, false }},
- { ocDevSq, {{ Reference }, true }},
- { ocDiv, {{ Array, Array }, false }},
- { ocEqual, {{ Array, Array }, false }},
- { ocForecast, {{ Value, ForceArray, ForceArray }, false }},
- { ocFrequency, {{ Reference, Reference }, false }},
- { ocFTest, {{ ForceArray, ForceArray }, false }},
- { ocGeoMean, {{ Reference }, true }},
- { ocGCD, {{ Reference }, true }},
- { ocGreater, {{ Array, Array }, false }},
- { ocGreaterEqual, {{ Array, Array }, false }},
- { ocGrowth, {{ Reference, Reference, Reference, Value }, false }},
- { ocHarMean, {{ Reference }, true }},
- { ocHLookup, {{ Value, Reference, Value, Value }, false }},
- { ocIRR, {{ Reference, Value }, false }},
- { ocIndex, {{ Reference, Value, Value, Value }, false }},
- { ocIntercept, {{ ForceArray, ForceArray }, false }},
- { ocIntersect, {{ Reference, Reference }, false }},
- { ocIsRef, {{ Reference }, false }},
- { ocLCM, {{ Reference }, true }},
- { ocKurt, {{ Reference }, true }},
- { ocLarge, {{ Reference, Value }, false }},
- { ocLess, {{ Array, Array }, false }},
- { ocLessEqual, {{ Array, Array }, false }},
- { ocLookup, {{ Value, ReferenceOrForceArray, ReferenceOrForceArray }, false }},
- { ocMatch, {{ Value, Reference, Reference }, false }},
- { ocMatDet, {{ ForceArray }, false }},
- { ocMatInv, {{ ForceArray }, false }},
- { ocMatMult, {{ ForceArray, ForceArray }, false }},
- { ocMatTrans, {{ Array }, false }}, // strange, but Xcl doesn't force MatTrans array
- { ocMatValue, {{ Reference, Value, Value }, false }},
- { ocMax, {{ Reference }, true }},
- { ocMaxA, {{ Reference }, true }},
- { ocMedian, {{ Reference }, true }},
- { ocMin, {{ Reference }, true }},
- { ocMinA, {{ Reference }, true }},
- { ocMIRR, {{ Reference, Value, Value }, false }},
- { ocModalValue, {{ ForceArray }, true }},
- { ocMul, {{ Array, Array }, false }},
- { ocMultiArea, {{ Reference }, true }},
- { ocNPV, {{ Value, Reference }, true }},
- { ocNeg, {{ Array }, false }},
- { ocNegSub, {{ Array }, false }},
- { ocNot, {{ Array }, false }},
- { ocNotEqual, {{ Array, Array }, false }},
- { ocOffset, {{ Reference, Value, Value, Value, Value }, false }},
- { ocOr, {{ Reference }, true }},
- { ocPearson, {{ ForceArray, ForceArray }, false }},
- { ocPercentile, {{ Reference, Value }, false }},
- { ocPercentrank, {{ Reference, Value }, false }},
- { ocPow, {{ Array, Array }, false }},
- { ocPower, {{ Array, Array }, false }},
- { ocProb, {{ ForceArray, ForceArray, Value, Value }, false }},
- { ocProduct, {{ Reference }, true }},
- { ocQuartile, {{ Reference, Value }, false }},
- { ocRank, {{ Value, Reference, Value }, false }},
- { ocRGP, {{ Reference, Reference, Value, Value }, false }},
- { ocRKP, {{ Reference, Reference, Value, Value }, false }},
- { ocRow, {{ Reference }, false }},
- { ocRows, {{ Reference }, true }},
- { ocRSQ, {{ ForceArray, ForceArray }, false }},
- { ocSchiefe, {{ Reference }, true }},
- { ocSlope, {{ ForceArray, ForceArray }, false }},
- { ocSmall, {{ Reference, Value }, false }},
- { ocStDev, {{ Reference }, true }},
- { ocStDevA, {{ Reference }, true }},
- { ocStDevP, {{ Reference }, true }},
- { ocStDevPA, {{ Reference }, true }},
- { ocSTEYX, {{ ForceArray, ForceArray }, false }},
- { ocSub, {{ Array, Array }, false }},
- { ocSubTotal, {{ Value, Reference }, true }},
- { ocSum, {{ Reference }, true }},
- { ocSumIf, {{ Reference, Value, Reference }, false }},
- { ocSumIfs, {{ Reference, Reference, Value }, true }},
- { ocSumProduct, {{ ForceArray }, true }},
- { ocSumSQ, {{ Reference }, true }},
- { ocSumX2MY2, {{ ForceArray, ForceArray }, false }},
- { ocSumX2DY2, {{ ForceArray, ForceArray }, false }},
- { ocSumXMY2, {{ ForceArray, ForceArray }, false }},
- { ocTable, {{ Reference }, false }},
- { ocTables, {{ Reference }, true }},
- { ocTrend, {{ Reference, Reference, Reference, Value }, false }},
- { ocTrimMean, {{ Reference, Value }, false }},
- { ocTTest, {{ ForceArray, ForceArray, Value, Value }, false }},
- { ocVar, {{ Reference }, true }},
- { ocVarA, {{ Reference }, true }},
- { ocVarP, {{ Reference }, true }},
- { ocVarPA, {{ Reference }, true }},
- { ocVLookup, {{ Value, Reference, Value, Value }, false }},
- { ocXor, {{ Reference }, true }},
- { ocZTest, {{ Reference, Value, Value }, false }},
+ { ocAdd, {{ Array, Array }, 0 }},
+ { ocAmpersand, {{ Array, Array }, 0 }},
+ { ocAnd, {{ Reference }, 1 }},
+ { ocAreas, {{ Reference }, 0 }},
+ { ocAveDev, {{ Reference }, 1 }},
+ { ocAverage, {{ Reference }, 1 }},
+ { ocAverageA, {{ Reference }, 1 }},
+ { ocAverageIf, {{ Reference, Value, Reference }, 0 }},
+ { ocAverageIfs, {{ Reference, Reference, Value }, 2 }},
+ { ocCell, {{ Value, Reference }, 0 }},
+ { ocColumn, {{ Reference }, 0 }},
+ { ocColumns, {{ Reference }, 1 }},
+ { ocCorrel, {{ ForceArray, ForceArray }, 0 }},
+ { ocCount, {{ Reference }, 1 }},
+ { ocCount2, {{ Reference }, 1 }},
+ { ocCountEmptyCells, {{ Reference }, 0 }},
+ { ocCountIf, {{ Reference, Value }, 0 }},
+ { ocCountIfs, {{ Reference, Value }, 2 }},
+ { ocCovar, {{ ForceArray, ForceArray }, 0 }},
+ { ocDBAverage, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBCount, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBCount2, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBGet, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBMax, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBMin, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBProduct, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBStdDev, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBStdDevP, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBSum, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBVar, {{ Reference, Reference, Reference }, 0 }},
+ { ocDBVarP, {{ Reference, Reference, Reference }, 0 }},
+ { ocDevSq, {{ Reference }, 1 }},
+ { ocDiv, {{ Array, Array }, 0 }},
+ { ocEqual, {{ Array, Array }, 0 }},
+ { ocForecast, {{ Value, ForceArray, ForceArray }, 0 }},
+ { ocFrequency, {{ Reference, Reference }, 0 }},
+ { ocFTest, {{ ForceArray, ForceArray }, 0 }},
+ { ocGeoMean, {{ Reference }, 1 }},
+ { ocGCD, {{ Reference }, 1 }},
+ { ocGreater, {{ Array, Array }, 0 }},
+ { ocGreaterEqual, {{ Array, Array }, 0 }},
+ { ocGrowth, {{ Reference, Reference, Reference, Value }, 0 }},
+ { ocHarMean, {{ Reference }, 1 }},
+ { ocHLookup, {{ Value, Reference, Value, Value }, 0 }},
+ { ocIRR, {{ Reference, Value }, 0 }},
+ { ocIndex, {{ Reference, Value, Value, Value }, 0 }},
+ { ocIntercept, {{ ForceArray, ForceArray }, 0 }},
+ { ocIntersect, {{ Reference, Reference }, 0 }},
+ { ocIsRef, {{ Reference }, 0 }},
+ { ocLCM, {{ Reference }, 1 }},
+ { ocKurt, {{ Reference }, 1 }},
+ { ocLarge, {{ Reference, Value }, 0 }},
+ { ocLess, {{ Array, Array }, 0 }},
+ { ocLessEqual, {{ Array, Array }, 0 }},
+ { ocLookup, {{ Value, ReferenceOrForceArray, ReferenceOrForceArray }, 0 }},
+ { ocMatch, {{ Value, Reference, Reference }, 0 }},
+ { ocMatDet, {{ ForceArray }, 0 }},
+ { ocMatInv, {{ ForceArray }, 0 }},
+ { ocMatMult, {{ ForceArray, ForceArray }, 0 }},
+ { ocMatTrans, {{ Array }, 0 }}, // strange, but Xcl doesn't force MatTrans array
+ { ocMatValue, {{ Reference, Value, Value }, 0 }},
+ { ocMax, {{ Reference }, 1 }},
+ { ocMaxA, {{ Reference }, 1 }},
+ { ocMedian, {{ Reference }, 1 }},
+ { ocMin, {{ Reference }, 1 }},
+ { ocMinA, {{ Reference }, 1 }},
+ { ocMIRR, {{ Reference, Value, Value }, 0 }},
+ { ocModalValue, {{ ForceArray }, 1 }},
+ { ocMul, {{ Array, Array }, 0 }},
+ { ocMultiArea, {{ Reference }, 1 }},
+ { ocNPV, {{ Value, Reference }, 1 }},
+ { ocNeg, {{ Array }, 0 }},
+ { ocNegSub, {{ Array }, 0 }},
+ { ocNot, {{ Array }, 0 }},
+ { ocNotEqual, {{ Array, Array }, 0 }},
+ { ocOffset, {{ Reference, Value, Value, Value, Value }, 0 }},
+ { ocOr, {{ Reference }, 1 }},
+ { ocPearson, {{ ForceArray, ForceArray }, 0 }},
+ { ocPercentile, {{ Reference, Value }, 0 }},
+ { ocPercentrank, {{ Reference, Value }, 0 }},
+ { ocPow, {{ Array, Array }, 0 }},
+ { ocPower, {{ Array, Array }, 0 }},
+ { ocProb, {{ ForceArray, ForceArray, Value, Value }, 0 }},
+ { ocProduct, {{ Reference }, 1 }},
+ { ocQuartile, {{ Reference, Value }, 0 }},
+ { ocRank, {{ Value, Reference, Value }, 0 }},
+ { ocRGP, {{ Reference, Reference, Value, Value }, 0 }},
+ { ocRKP, {{ Reference, Reference, Value, Value }, 0 }},
+ { ocRow, {{ Reference }, 0 }},
+ { ocRows, {{ Reference }, 1 }},
+ { ocRSQ, {{ ForceArray, ForceArray }, 0 }},
+ { ocSchiefe, {{ Reference }, 1 }},
+ { ocSlope, {{ ForceArray, ForceArray }, 0 }},
+ { ocSmall, {{ Reference, Value }, 0 }},
+ { ocStDev, {{ Reference }, 1 }},
+ { ocStDevA, {{ Reference }, 1 }},
+ { ocStDevP, {{ Reference }, 1 }},
+ { ocStDevPA, {{ Reference }, 1 }},
+ { ocSTEYX, {{ ForceArray, ForceArray }, 0 }},
+ { ocSub, {{ Array, Array }, 0 }},
+ { ocSubTotal, {{ Value, Reference }, 1 }},
+ { ocSum, {{ Reference }, 1 }},
+ { ocSumIf, {{ Reference, Value, Reference }, 0 }},
+ { ocSumIfs, {{ Reference, Reference, Value }, 2 }},
+ { ocSumProduct, {{ ForceArray }, 1 }},
+ { ocSumSQ, {{ Reference }, 1 }},
+ { ocSumX2MY2, {{ ForceArray, ForceArray }, 0 }},
+ { ocSumX2DY2, {{ ForceArray, ForceArray }, 0 }},
+ { ocSumXMY2, {{ ForceArray, ForceArray }, 0 }},
+ { ocTable, {{ Reference }, 0 }},
+ { ocTables, {{ Reference }, 1 }},
+ { ocTrend, {{ Reference, Reference, Reference, Value }, 0 }},
+ { ocTrimMean, {{ Reference, Value }, 0 }},
+ { ocTTest, {{ ForceArray, ForceArray, Value, Value }, 0 }},
+ { ocVar, {{ Reference }, 1 }},
+ { ocVarA, {{ Reference }, 1 }},
+ { ocVarP, {{ Reference }, 1 }},
+ { ocVarPA, {{ Reference }, 1 }},
+ { ocVLookup, {{ Value, Reference, Value, Value }, 0 }},
+ { ocXor, {{ Reference }, 1 }},
+ { ocZTest, {{ Reference, Value, Value }, 0 }},
// Excel doubts:
// ocN, ocT: Excel says (and handles) Reference, error? This means no
// position dependent SingleRef if DoubleRef, and no array calculation,
@@ -194,10 +197,10 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
// for ocN (position dependent intersection worked before but array
// didn't). No specifics in ODFF, so the general rule applies. Gnumeric
// does the same.
- { ocN, {{ Value }, false }},
- { ocT, {{ Value }, false }},
+ { ocN, {{ Value }, 0 }},
+ { ocT, {{ Value }, 0 }},
// The stopper.
- { ocNone, {{ Bounds }, false } }
+ { ocNone, {{ Bounds }, 0 } }
};
ScParameterClassification::RunData * ScParameterClassification::pData = NULL;
@@ -229,18 +232,19 @@ void ScParameterClassification::Init()
#endif
memcpy( &(pRun->aData), &(pRaw->aData), sizeof(CommonData));
// fill 0-initialized fields with real values
- if ( pRun->aData.bRepeatLast )
+ if ( pRun->aData.nRepeatLast )
{
- Type eLast = Unknown;
for ( sal_Int32 j=0; j < CommonData::nMaxParams; ++j )
{
if ( pRun->aData.nParam[j] )
- {
- eLast = pRun->aData.nParam[j];
pRun->nMinParams = sal::static_int_cast<sal_uInt8>( j+1 );
- }
+ else if (j >= pRun->aData.nRepeatLast)
+ pRun->aData.nParam[j] = pRun->aData.nParam[j - pRun->aData.nRepeatLast];
else
- pRun->aData.nParam[j] = eLast;
+ {
+ OSL_TRACE( "bad classification: eOp %d, repeated param %d negative offset", pRaw->eOp, j);
+ pRun->aData.nParam[j] = Unknown;
+ }
}
}
else
@@ -301,15 +305,23 @@ ScParameterClassification::Type ScParameterClassification::GetParameterType(
}
if ( 0 <= (short)eOp && eOp <= SC_OPCODE_LAST_OPCODE_ID )
{
+ sal_uInt8 nRepeat;
+ Type eType;
if ( nParameter < CommonData::nMaxParams )
+ eType = pData[eOp].aData.nParam[nParameter];
+ else if ( (nRepeat = pData[eOp].aData.nRepeatLast) > 0 )
{
- Type eT = pData[eOp].aData.nParam[nParameter];
- return eT == Unknown ? Value : eT;
+ // The usual case is 1 repeated parameter, we don't need to
+ // calculate that on each call.
+ sal_uInt16 nParam = (nRepeat > 1 ?
+ (pData[eOp].nMinParams -
+ ((nParameter - pData[eOp].nMinParams) % nRepeat)) :
+ pData[eOp].nMinParams);
+ return pData[eOp].aData.nParam[nParam];
}
- else if ( pData[eOp].aData.bRepeatLast )
- return pData[eOp].aData.nParam[CommonData::nMaxParams-1];
else
- return Bounds;
+ eType = Bounds;
+ return eType == Unknown ? Value : eType;
}
return Unknown;
}
@@ -410,12 +422,12 @@ void ScParameterClassification::MergeArgumentsFromFunctionResource()
if ( nArgs >= PAIRED_VAR_ARGS )
{
nArgs -= PAIRED_VAR_ARGS - 2;
- pRun->aData.bRepeatLast = true;
+ pRun->aData.nRepeatLast = 2;
}
else if ( nArgs >= VAR_ARGS )
{
nArgs -= VAR_ARGS - 1;
- pRun->aData.bRepeatLast = true;
+ pRun->aData.nRepeatLast = 1;
}
if ( nArgs > CommonData::nMaxParams )
{
@@ -425,15 +437,15 @@ void ScParameterClassification::MergeArgumentsFromFunctionResource()
aBuf.append(": ");
aBuf.append(sal_Int32(nArgs));
OSL_FAIL( aBuf.getStr());
- nArgs = CommonData::nMaxParams;
- pRun->aData.bRepeatLast = true;
+ nArgs = CommonData::nMaxParams - 1;
+ pRun->aData.nRepeatLast = 1;
}
pRun->nMinParams = static_cast< sal_uInt8 >( nArgs );
for ( sal_Int32 j=0; j < nArgs; ++j )
{
pRun->aData.nParam[j] = Value;
}
- if ( pRun->aData.bRepeatLast )
+ if ( pRun->aData.nRepeatLast )
{
for ( sal_Int32 j = nArgs; j < CommonData::nMaxParams; ++j )
{
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index b24b0b1..1080cc9 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -42,7 +42,9 @@
*
* Number of parameters. VAR_ARGS if variable number, or
* VAR_ARGS+number if number of fixed parameters and variable
- * arguments following.
+ * arguments following. Or PAIRED_VAR_ARGS if variable number of
+ * paired parameters, or PAIRED_VAR_ARGS+number if number of fixed
+ * parameters and variable paired arguments following.
*
* For every parameter:
*
@@ -2995,7 +2997,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 4 // Name of Parameter 2
{
- Text [ en-US ] = "range" ;
+ Text [ en-US ] = "range " ;
};
String 5 // Description of Parameter 2
{
@@ -3003,7 +3005,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 6 // Name of Parameter 3
{
- Text [ en-US ] = "criteria" ;
+ Text [ en-US ] = "criteria " ;
};
String 7 // Description of Parameter 3
{
@@ -3036,7 +3038,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 4 // Name of Parameter 2
{
- Text [ en-US ] = "range" ;
+ Text [ en-US ] = "range " ;
};
String 5 // Description of Parameter 2
{
@@ -3044,7 +3046,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 6 // Name of Parameter 3
{
- Text [ en-US ] = "criteria" ;
+ Text [ en-US ] = "criteria " ;
};
String 7 // Description of Parameter 3
{
@@ -3069,7 +3071,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 2 // Name of Parameter 1
{
- Text [ en-US ] = "range" ;
+ Text [ en-US ] = "range " ;
};
String 3 // Description of Parameter 1
{
@@ -3077,7 +3079,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 4 // Name of Parameter 2
{
- Text [ en-US ] = "criteria" ;
+ Text [ en-US ] = "criteria " ;
};
String 5 // Description of Parameter 2
{
commit 69ae7b2a9a752faaa282a8fd5d38fce41ab2193a
Author: Marina Plakalovic <makkica at openoffice.org>
Date: Fri Dec 14 23:40:18 2012 +0100
calcishmakkica: #i90269# #i95144# #i101466# implement SUMIFS, AVERAGEIFS, COUNTIFS
Merged from Apache OO with adaptions.
http://svn.apache.org/viewvc?rev=1381447&view=rev
Original Apache OO committer: Andrew Rist <arist at apache.org>
Original Author: Marina Plakalovic <makkica at openoffice.org>
Original Committer: Eike Rathke [er] <eike.rathke at oracle.com>
# HG changeset patch
# User Eike Rathke [er] <eike.rathke at oracle.com>
# Date 1288810126 -3600
# Node ID 02cf226fcde498f6fd926d45df497e9fb412fe0f
# Parent 528da6bfd0daed4355d745590d5ac3a319b08fb4
Change-Id: I08754653cd2ff20536ad3e9f260f747cb127ccdd
(cherry picked from commit f2cb873631b8b21b54a55beaba532f4bd616a9c6)
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index 9ae1c18..582e3a5 100644
--- a/formula/inc/formula/compiler.hrc
+++ b/formula/inc/formula/compiler.hrc
@@ -393,8 +393,11 @@
#define SC_OPCODE_GET_DATEDIF 400
#define SC_OPCODE_XOR 401
#define SC_OPCODE_AVERAGE_IF 402
-#define SC_OPCODE_STOP_2_PAR 403
-#define SC_OPCODE_LAST_OPCODE_ID 403 /* last OpCode */
+#define SC_OPCODE_SUM_IFS 403
+#define SC_OPCODE_AVERAGE_IFS 404
+#define SC_OPCODE_COUNT_IFS 405
+#define SC_OPCODE_STOP_2_PAR 406
+#define SC_OPCODE_LAST_OPCODE_ID 405 /* last OpCode */
/*** Internal ***/
#define SC_OPCODE_INTERNAL_BEGIN 9999
diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx
index 046d25b..cd1831b 100644
--- a/formula/inc/formula/opcode.hxx
+++ b/formula/inc/formula/opcode.hxx
@@ -274,7 +274,10 @@ enum OpCodeEnum
ocCountEmptyCells = SC_OPCODE_COUNT_EMPTY_CELLS,
ocCountIf = SC_OPCODE_COUNT_IF,
ocSumIf = SC_OPCODE_SUM_IF,
- ocAverageIf = SC_OPCODE_AVERAGE_IF,
+ ocAverageIf = SC_OPCODE_AVERAGE_IF,
+ ocSumIfs = SC_OPCODE_SUM_IFS,
+ ocAverageIfs = SC_OPCODE_AVERAGE_IFS,
+ ocCountIfs = SC_OPCODE_COUNT_IFS,
ocLookup = SC_OPCODE_LOOKUP,
ocVLookup = SC_OPCODE_V_LOOKUP,
ocHLookup = SC_OPCODE_H_LOOKUP,
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index 1c165d0..c552eb1 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -238,6 +238,9 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; };
String SC_OPCODE_SUM_IF { Text = "SUMIF" ; };
String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
+ String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
+ String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
+ String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; };
String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; };
String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; };
@@ -572,6 +575,9 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; };
String SC_OPCODE_SUM_IF { Text = "SUMIF" ; };
String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
+ String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
+ String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
+ String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; };
String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; };
String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; };
@@ -1479,6 +1485,18 @@ Resource RID_STRLIST_FUNCTION_NAMES
{
Text [ en-US ] = "AVERAGEIF" ;
};
+ String SC_OPCODE_SUM_IFS
+ {
+ Text [ en-US ] = "SUMIFS" ;
+ };
+ String SC_OPCODE_AVERAGE_IFS
+ {
+ Text [ en-US ] = "AVERAGEIFS" ;
+ };
+ String SC_OPCODE_COUNT_IFS
+ {
+ Text [ en-US ] = "COUNTIFS" ;
+ };
String SC_OPCODE_LOOKUP
{
Text [ en-US ] = "LOOKUP" ;
diff --git a/formula/source/ui/dlg/parawin.cxx b/formula/source/ui/dlg/parawin.cxx
index d51f4dc..23d8ec8 100644
--- a/formula/source/ui/dlg/parawin.cxx
+++ b/formula/source/ui/dlg/parawin.cxx
@@ -30,6 +30,7 @@
#include "ForResId.hrc"
#define VAR_ARGS 30
+#define PAIRED_VAR_ARGS (VAR_ARGS + VAR_ARGS)
namespace formula
{
//============================================================================
@@ -109,7 +110,7 @@ void ParaWin::UpdateArgDesc( sal_uInt16 nArg )
aArgName += ' ';
aArgName += (pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
}
- else
+ else if ( nArgs < PAIRED_VAR_ARGS )
{
sal_uInt16 nFix = nArgs - VAR_ARGS;
sal_uInt16 nPos = ( nArg < nFix ? nArg : nFix );
@@ -123,6 +124,24 @@ void ParaWin::UpdateArgDesc( sal_uInt16 nArg )
aArgName += (nArg > nFix || pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
}
+ else
+ {
+ sal_uInt16 nFix = nArgs - PAIRED_VAR_ARGS;
+ sal_uInt16 nPos;
+ if ( nArg < nFix )
+ nPos = nArg;
+ else
+ nPos = nFix + ( (nArg-nFix) % 2);
+ sal_uInt16 nRealArg = (nPos < aVisibleArgMapping.size() ?
+ aVisibleArgMapping[nPos] : aVisibleArgMapping.back());
+ aArgDesc = pFuncDesc->getParameterDescription(nRealArg);
+ aArgName = pFuncDesc->getParameterName(nRealArg);
+ if ( nArg >= nFix )
+ aArgName += String::CreateFromInt32((nArg-nFix)/2 + 1);
+ aArgName += ' ';
+
+ aArgName += (nArg > (nFix+1) || pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
+ }
SetArgumentDesc(aArgDesc);
SetArgumentText(aArgName);
@@ -142,7 +161,7 @@ void ParaWin::UpdateArgInput( sal_uInt16 nOffset, sal_uInt16 i )
SetArgName (i,pFuncDesc->getParameterName(nRealArg));
}
}
- else
+ else if ( nArgs < PAIRED_VAR_ARGS)
{
sal_uInt16 nFix = nArgs - VAR_ARGS;
sal_uInt16 nPos = ( nArg < nFix ? nArg : nFix );
@@ -160,6 +179,28 @@ void ParaWin::UpdateArgInput( sal_uInt16 nOffset, sal_uInt16 i )
else
SetArgName( i, pFuncDesc->getParameterName(nRealArg) );
}
+ else
+ {
+ sal_uInt16 nFix = nArgs - PAIRED_VAR_ARGS;
+ sal_uInt16 nPos;
+ if ( nArg < nFix )
+ nPos = nArg;
+ else
+ nPos = nFix + ( (nArg-nFix) % 2);
+ sal_uInt16 nRealArg = (nPos < aVisibleArgMapping.size() ?
+ aVisibleArgMapping[nPos] : aVisibleArgMapping.back());
+ SetArgNameFont( i,
+ (nArg > (nFix+1) || pFuncDesc->isParameterOptional(nRealArg)) ?
+ aFntLight : aFntBold );
+ if ( nArg >= nFix )
+ {
+ String aArgName( pFuncDesc->getParameterName(nRealArg) );
+ aArgName += String::CreateFromInt32((nArg-nFix)/2 + 1);
+ SetArgName( i, aArgName );
+ }
+ else
+ SetArgName( i, pFuncDesc->getParameterName(nRealArg) );
+ }
if(nArg<nArgs) SetArgVal(i,aParaArray[nArg]);
}
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index 6615183..2e2aa4c 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -446,6 +446,9 @@
#define HID_FUNC_PRODUKT "SC_HID_FUNC_PRODUKT"
#define HID_FUNC_SUMMEWENN "SC_HID_FUNC_SUMMEWENN"
#define HID_FUNC_AVERAGEIF "SC_HID_FUNC_AVERAGEIF"
+#define HID_FUNC_SUMIFS "SC_HID_FUNC_SUMIFS"
+#define HID_FUNC_AVERAGEIFS "SC_HID_FUNC_AVERAGEIFS"
+#define HID_FUNC_COUNTIFS "SC_HID_FUNC_COUNTIFS"
#define HID_FUNC_ZAEHLENWENN "SC_HID_FUNC_ZAEHLENWENN"
#define HID_FUNC_WURZEL "SC_HID_FUNC_WURZEL"
#define HID_FUNC_ZUFALLSZAHL "SC_HID_FUNC_ZUFALLSZAHL"
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 2849c9f..9eaf61f 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -28,6 +28,7 @@
#include "helpids.h"
#define VAR_ARGS 30 // variable Parameter in scfuncs.src
+#define PAIRED_VAR_ARGS (VAR_ARGS + VAR_ARGS)
// areas
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index aed60e7..55b8b9c 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -3972,6 +3972,7 @@ void Test::testFunctionLists()
"ATAN2",
"ATANH",
"AVERAGEIF",
+ "AVERAGEIFS",
"BITAND",
"BITLSHIFT",
"BITOR",
@@ -3987,6 +3988,7 @@ void Test::testFunctionLists()
"COTH",
"COUNTBLANK",
"COUNTIF",
+ "COUNTIFS",
"CSC",
"CSCH",
"DEGREES",
@@ -4022,6 +4024,7 @@ void Test::testFunctionLists()
"SUBTOTAL",
"SUM",
"SUMIF",
+ "SUMIFS",
"SUMSQ",
"TAN",
"TANH",
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
index e34dd20..32500ee 100644
--- a/sc/source/core/data/funcdesc.cxx
+++ b/sc/source/core/data/funcdesc.cxx
@@ -84,7 +84,10 @@ ScFuncDesc::~ScFuncDesc()
void ScFuncDesc::Clear()
{
sal_uInt16 nArgs = nArgCount;
- if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1;
+ if (nArgs >= PAIRED_VAR_ARGS)
+ nArgs -= PAIRED_VAR_ARGS - 2;
+ else if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
if (nArgs)
{
for (sal_uInt16 i=0; i<nArgs; i++ )
@@ -147,7 +150,7 @@ void ScFuncDesc::Clear()
aSig.getLength() >= 2)
aSig.setLength(aSig.getLength() - 2);
}
- else
+ else if ( nArgCount < PAIRED_VAR_ARGS)
{
sal_uInt16 nFix = nArgCount - VAR_ARGS;
for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
@@ -172,6 +175,34 @@ void ScFuncDesc::Clear()
aSig.append(sep);
aSig.appendAscii(" ... ");
}
+ else
+ {
+ sal_uInt16 nFix = nArgCount - PAIRED_VAR_ARGS;
+ for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
+ {
+ if (!pDefArgFlags[nArg].bSuppress)
+ {
+ aSig.append(*(ppDefArgNames[nArg]));
+ aSig.append(sep);
+ aSig.appendAscii( " " );
+ }
+ }
+
+ aSig.append(*(ppDefArgNames[nFix]));
+ aSig.append(sal_Unicode('1'));
+ aSig.appendAscii( ", " );
+ aSig.append(*(ppDefArgNames[nFix+1]));
+ aSig.append(sal_Unicode('1'));
+ aSig.append(sep);
+ aSig.appendAscii( " " );
+ aSig.append(*(ppDefArgNames[nFix]));
+ aSig.append(sal_Unicode('2'));
+ aSig.appendAscii( ", " );
+ aSig.append(*(ppDefArgNames[nFix+1]));
+ aSig.append(sal_Unicode('2'));
+ aSig.append(sep);
+ aSig.appendAscii( " ... " );
+ }
}
return aSig.makeStringAndClear();
@@ -243,7 +274,9 @@ sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
return nArgCount;
sal_uInt16 nArgs = nArgCount;
- if (nArgs >= VAR_ARGS)
+ if (nArgs >= PAIRED_VAR_ARGS)
+ nArgs -= PAIRED_VAR_ARGS - 2;
+ else if (nArgs >= VAR_ARGS)
nArgs -= VAR_ARGS - 1;
sal_uInt16 nCount = nArgs;
for (sal_uInt16 i=0; i < nArgs; ++i)
@@ -251,7 +284,9 @@ sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
if (pDefArgFlags[i].bSuppress)
--nCount;
}
- if (nArgCount >= VAR_ARGS)
+ if (nArgCount >= PAIRED_VAR_ARGS)
+ nCount += PAIRED_VAR_ARGS - 2;
+ else if (nArgCount >= VAR_ARGS)
nCount += VAR_ARGS - 1;
return nCount;
}
@@ -295,7 +330,9 @@ void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArgumen
_rArguments.reserve( nArgCount);
sal_uInt16 nArgs = nArgCount;
- if (nArgs >= VAR_ARGS)
+ if (nArgs >= PAIRED_VAR_ARGS)
+ nArgs -= PAIRED_VAR_ARGS - 2;
+ else if (nArgs >= VAR_ARGS)
nArgs -= VAR_ARGS - 1;
for (sal_uInt16 i=0; i < nArgs; ++i)
{
@@ -809,7 +846,9 @@ ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
pDesc->sHelpId = ReadByteStringRes();
pDesc->nArgCount = GetNum();
sal_uInt16 nArgs = pDesc->nArgCount;
- if (nArgs >= VAR_ARGS)
+ if (nArgs >= PAIRED_VAR_ARGS)
+ nArgs -= PAIRED_VAR_ARGS - 2;
+ else if (nArgs >= VAR_ARGS)
nArgs -= VAR_ARGS - 1;
if (nArgs)
{
@@ -835,7 +874,12 @@ ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
sal_uInt16 nParam = GetNum();
if (nParam < nArgs)
{
- if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
+ if (pDesc->nArgCount >= PAIRED_VAR_ARGS && nParam >= nArgs-2)
+ {
+ OSL_TRACE( "ScFuncRes: PAIRED_VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d >= arg %d-2",
+ aRes.GetId(), (int)nParam, (int)nArgs);
+ }
+ else if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
{
OSL_TRACE( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
aRes.GetId(), (int)nParam, (int)nArgs);
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 1c408f8..762b818 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -74,6 +74,13 @@ enum ScIterFuncIf
ifAVERAGEIF // Conditional average
};
+enum ScIterFuncIfs
+{
+ ifSUMIFS, // Multi-Conditional sum
+ ifAVERAGEIFS, // Multi-Conditional average
+ ifCOUNTIFS // Multi-Conditional count
+};
+
struct FormulaTokenRef_less
{
bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
@@ -483,6 +490,10 @@ double IterateParametersIf( ScIterFuncIf );
void ScCountIf();
void ScSumIf();
void ScAverageIf();
+double IterateParametersIfs( ScIterFuncIfs );
+void ScSumIfs();
+void ScAverageIfs();
+void ScCountIfs();
void ScCountEmptyCells();
void ScLookup();
void ScHLookup();
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index a27c367..8e59245 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5728,6 +5728,392 @@ void ScInterpreter::ScCountIf()
}
}
+double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
+{
+ sal_uInt8 nParamCount = GetByte();
+ sal_uInt8 nQueryCount = nParamCount / 2;
+
+ bool bCheck;
+ if ( eFunc == ifCOUNTIFS )
+ bCheck = (nParamCount >= 2) && (nParamCount % 2 == 0);
+ else
+ bCheck = (nParamCount >= 3) && (nParamCount % 2 == 1);
+
+ if ( !bCheck )
+ {
+ SetError( errParameterExpected);
+ }
+ else
+ {
+ ScMatrixRef pResMat;
+ double fVal = 0.0;
+ double fSum = 0.0;
+ double fMem = 0.0;
+ double fRes = 0.0;
+ double fCount = 0.0;
+ short nParam = 1;
+ size_t nRefInList = 0;
+
+ while (nParamCount > 1 && !nGlobalError)
+ {
+ // take criteria
+ String rString;
+ fVal = 0.0;
+ bool bIsString = true;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ return 0;
+
+ ScBaseCell* pCell = GetCell( aAdr );
+ switch ( GetCellType( pCell ) )
+ {
+ case CELLTYPE_VALUE :
+ fVal = GetCellValue( aAdr, pCell );
+ bIsString = false;
+ break;
+ case CELLTYPE_FORMULA :
+ if( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ bIsString = false;
+ }
+ else
+ GetCellString(rString, pCell);
+ break;
+ case CELLTYPE_STRING :
+ case CELLTYPE_EDIT :
+ GetCellString(rString, pCell);
+ break;
+ default:
+ fVal = 0.0;
+ bIsString = false;
+ }
+ }
+ break;
+ case svString:
+ rString = GetString();
+ break;
+ case svMatrix :
+ {
+ ScMatValType nType = GetDoubleOrStringFromMatrix( fVal, rString);
+ bIsString = ScMatrix::IsNonValueType( nType);
+ }
+ break;
+ default:
+ {
+ fVal = GetDouble();
+ bIsString = false;
+ }
+ }
+
+ // take range
+ nParam = 1;
+ nRefInList = 0;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCTAB nTab1;
+ SCCOL nCol2;
+ SCROW nRow2;
+ SCTAB nTab2;
+ ScMatrixRef pQueryMatrix;
+ switch ( GetStackType() )
+ {
+ case svRefList :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ }
+ break;
+ case svDoubleRef :
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ break;
+ case svSingleRef :
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nCol2 = nCol1;
+ nRow2 = nRow1;
+ nTab2 = nTab1;
+ break;
+ case svMatrix:
+ {
+ pQueryMatrix = PopMatrix();
+ if (!pQueryMatrix)
+ {
+ SetError( errIllegalParameter);
+ }
+ nCol1 = 0;
+ nRow1 = 0;
+ nTab1 = 0;
+ SCSIZE nC, nR;
+ pQueryMatrix->GetDimensions( nC, nR);
+ nCol2 = static_cast<SCCOL>(nC - 1);
+ nRow2 = static_cast<SCROW>(nR - 1);
+ nTab2 = 0;
+ }
+ break;
+ default:
+ SetError( errIllegalParameter);
+ }
+ if ( nTab1 != nTab2 )
+ {
+ SetError( errIllegalParameter);
+ }
+ // initialize temporary result matrix
+ if (!pResMat)
+ {
+ SCSIZE nResC, nResR;
+ nResC = nCol2 - nCol1 + 1;
+ nResR = nRow2 - nRow1 + 1;
+ pResMat = GetNewMat(nResC, nResR);
+ if (!pResMat)
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list