diff -upr old/sc/source/core/tool/interpr1.cxx new/sc/source/core/tool/interpr1.cxx --- old/sc/source/core/tool/interpr1.cxx 2008-02-25 10:02:14.000000000 +0800 +++ new/sc/source/core/tool/interpr1.cxx 2008-05-06 16:08:04.000000000 +0800 @@ -113,6 +113,121 @@ void ScInterpreter::ScIfJump() xNew = (*aMapIter).second; else { + if( ( nCols == 1 || nRows == 1 ) && nJumpCount >= 2 ) + { + const ScToken* pThenToken = NULL; + const ScToken* pElseToken = NULL; + SCSIZE nThenCols = 0, nThenRows = 0; + SCSIZE nElseCols = 0, nElseRows = 0; + USHORT i = 0; + for ( ScToken* t = rArr.FirstRPN(); t; t = rArr.NextRPN() ) + { + if ( i > 1 ) + { + OpCode eOp = t->GetOpCode(); + if ( eOp == ocPush ) + { + if ( !pThenToken ) + pThenToken = t; + else + pElseToken = t; + } + } + i++; + } + if ( pThenToken ) + { + switch ( pThenToken->GetType() ) + { + case svMatrix: + { + const ScMatrix* pThenMat = pThenToken->GetMatrix(); + if ( pThenMat ) + pThenMat->GetDimensions( nThenCols, nThenRows ); + } + break; + case svDoubleRef: + { + ScRange aRange; + DoubleRefToRange( pThenToken->GetDoubleRef(), aRange); + nThenCols = aRange.aEnd.Col() - aRange.aStart.Col() + 1; + nThenRows = aRange.aEnd.Row() - aRange.aStart.Row() + 1; + } + break; + default: + ; //nothing + } + } + if ( pElseToken ) + { + switch ( pElseToken->GetType() ) + { + case svMatrix: + { + const ScMatrix* pElseMat = pElseToken->GetMatrix(); + if ( pElseMat ) + pElseMat->GetDimensions( nElseCols, nElseRows ); + } + break; + case svDoubleRef: + { + ScRange aRange; + DoubleRefToRange( pElseToken->GetDoubleRef(), aRange); + nElseCols = aRange.aEnd.Col() - aRange.aStart.Col() + 1; + nElseRows = aRange.aEnd.Row() - aRange.aStart.Row() + 1; + } + break; + default: + ; //nothing + } + } + if ( (nThenCols > 1 && nThenRows > 1) || + (nElseCols > 1 && nElseRows > 1) ) + { + if ( nCols == 1 && nRows == 1 ) + { + bool bTrue = false; + ScMatValType nType = 0; + const ScMatrixValue* pMatVal = pMat->Get( 0, 0, nType); + bool bIsValue = ScMatrix::IsValueType( nType ); + if ( bIsValue ) + { + bIsValue = ::rtl::math::isFinite( pMatVal->fVal ); + bTrue = bIsValue && (pMatVal->fVal != 0.0); + } + if ( bTrue ) + { // TRUE + if ( nThenCols > 1 && nThenRows > 1 ) + { + nCols = nThenCols; + nRows = nThenRows; + } + else + { + nCols = nElseCols; + nRows = nElseRows; + } + } + else + { // ELSE + if ( nElseCols > 1 && nElseRows > 1 ) + { + nCols = nElseCols; + nRows = nElseRows; + } + else + { + nCols = nThenCols; + nRows = nThenRows; + } + } + } + else if ( nCols == 1 ) + nCols = nThenCols > nElseCols? nThenCols:nElseCols; + else + nRows = nThenRows > nElseRows? nThenRows:nElseRows; + } + } ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows ); for ( SCSIZE nC=0; nC < nCols; ++nC ) { @@ -416,14 +531,20 @@ bool ScInterpreter::JumpMatrix( short nS nGlobalError = 0; pResMat->PutDouble( fVal, nC, nR ); } - else if ( nCol > static_cast(aRange.aEnd.Col()) || - nRow > static_cast(aRange.aEnd.Row())) + else if (( nCol > static_cast(aRange.aEnd.Col()) || + nRow > static_cast(aRange.aEnd.Row())) && + (aRange.aEnd.Col() != aRange.aStart.Col() && + aRange.aEnd.Row() != aRange.aStart.Row())) { fVal = CreateDoubleError( errNoValue ); pResMat->PutDouble( fVal, nC, nR ); } else { + if (aRange.aEnd.Col() == aRange.aStart.Col()) + nCol = aRange.aStart.Col(); + else if (aRange.aEnd.Row() == aRange.aStart.Row()) + nRow = aRange.aStart.Row(); rAdr.SetCol( static_cast(nCol) ); rAdr.SetRow( static_cast(nRow) ); ScBaseCell* pCell = GetCell( rAdr ); @@ -475,7 +596,8 @@ bool ScInterpreter::JumpMatrix( short nS { SCSIZE nCols, nRows; pMat->GetDimensions( nCols, nRows ); - if ( nCols <= nC || nRows <= nR ) + if (( nCols <= nC || nRows <= nR ) && + ( nCols != 1 && nRows != 1 )) { fVal = CreateDoubleError( errNoValue ); pResMat->PutDouble( fVal, nC, nR ); diff -upr old/sc/source/core/tool/interpr5.cxx new/sc/source/core/tool/interpr5.cxx --- old/sc/source/core/tool/interpr5.cxx 2008-02-25 10:03:26.000000000 +0800 +++ new/sc/source/core/tool/interpr5.cxx 2008-05-06 16:09:08.000000000 +0800 @@ -1167,11 +1167,19 @@ ScMatrixRef ScInterpreter::MatAdd(ScMatr SCSIZE i, j; pMat1->GetDimensions(nC1, nR1); pMat2->GetDimensions(nC2, nR2); - if (nC1 < nC2) + if ( nC1 == 1 ) + nMinC = nC2; + else if ( nC2 == 1 ) + nMinC = nC1; + else if (nC1 < nC2) nMinC = nC1; else nMinC = nC2; - if (nR1 < nR2) + if ( nR1 == 1 ) + nMinR = nR2; + else if ( nR2 == 1 ) + nMinR = nR1; + else if (nR1 < nR2) nMinR = nR1; else nMinR = nR2; @@ -3825,7 +3833,8 @@ void ScInterpreter::ScMatRef() pMat->GetDimensions( nCl, nRw ); SCSIZE nC = static_cast(aPos.Col() - aAdr.Col()); SCSIZE nR = static_cast(aPos.Row() - aAdr.Row()); - if (nC < nCl && nR < nRw) + if ((nC < nCl && nR < nRw) || ( nCl == 1 && nRw == 1 ) || + ( nCl == 1 && nR < nRw ) || ( nRw == 1 && nC < nCl )) { ScMatValType nMatValType; const ScMatrixValue* pMatVal = pMat->Get( nC, nR, nMatValType); diff -upr old/sc/source/core/tool/scmatrix.cxx new/sc/source/core/tool/scmatrix.cxx --- old/sc/source/core/tool/scmatrix.cxx 2007-06-13 17:08:20.000000000 +0800 +++ new/sc/source/core/tool/scmatrix.cxx 2008-05-06 16:09:56.000000000 +0800 @@ -413,6 +413,21 @@ double ScMatrix::GetDouble(SCSIZE nC, SC { if (ValidColRow( nC, nR)) return GetDouble( CalcOffset( nC, nR) ); + else if (( nColCount == 1 && nR < nRowCount ) || + ( nRowCount == 1 && nC < nColCount )|| + ( nColCount == 1 && nRowCount == 1 )) + { + if ( nColCount == 1 && nRowCount == 1 ) + { + nC = 0; + nR = 0; + } + else if ( nColCount == 1 ) + nC = 0; + else + nR = 0; + return GetDouble( CalcOffset( nC, nR) ); + } else { DBG_ERRORFILE("ScMatrix::GetDouble: dimension error"); @@ -495,6 +510,26 @@ const ScMatrixValue* ScMatrix::Get(SCSIZ nType = SC_MATVAL_VALUE; return &pMat[nIndex]; } + else if (( nColCount == 1 && nR < nRowCount ) || + ( nRowCount == 1 && nC < nColCount )|| + ( nColCount == 1 && nRowCount == 1 )) + { + if ( nColCount == 1 && nRowCount == 1 ) + { + nC = 0; + nR = 0; + } + else if ( nColCount == 1 ) + nC = 0; + else + nR = 0; + SCSIZE nIndex = CalcOffset( nC, nR); + if (mnValType) + nType = mnValType[nIndex]; + else + nType = SC_MATVAL_VALUE; + return &pMat[nIndex]; + } else DBG_ERRORFILE("ScMatrix::Get: dimension error"); nType = SC_MATVAL_EMPTY;