2000-09-18 23:16:46 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* $RCSfile: interpr1.cxx,v $
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2008-01-29 14:22:31 +00:00
|
|
|
* $Revision: 1.55 $
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2008-01-29 14:22:31 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2008-01-29 15:22:31 $
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:44:38 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-07-21 10:31:53 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_sc.hxx"
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
// INCLUDE ---------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "scitems.hxx"
|
|
|
|
#include <svx/langitem.hxx>
|
2001-03-08 10:57:21 +00:00
|
|
|
#include <svx/algitem.hxx>
|
2000-11-20 09:31:47 +00:00
|
|
|
#include <unotools/textsearch.hxx>
|
2000-09-18 23:16:46 +00:00
|
|
|
#include <svtools/zforlist.hxx>
|
2001-03-08 10:57:21 +00:00
|
|
|
#include <svtools/zformat.hxx>
|
2006-12-19 12:17:39 +00:00
|
|
|
#include <tools/urlobj.hxx>
|
2000-09-18 23:16:46 +00:00
|
|
|
#include <unotools/charclass.hxx>
|
2001-03-08 10:57:21 +00:00
|
|
|
#include <sfx2/docfile.hxx>
|
|
|
|
#include <sfx2/printer.hxx>
|
2001-03-14 15:02:54 +00:00
|
|
|
#include <unotools/collatorwrapper.hxx>
|
2001-07-11 14:28:50 +00:00
|
|
|
#ifndef _UNOTOOLS_TRANSLITERATIONWRAPPER_HXX
|
|
|
|
#include <unotools/transliterationwrapper.hxx>
|
|
|
|
#endif
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
2004-11-15 15:35:15 +00:00
|
|
|
#include <vector>
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
#include "interpre.hxx"
|
|
|
|
#include "patattr.hxx"
|
|
|
|
#include "global.hxx"
|
|
|
|
#include "document.hxx"
|
|
|
|
#include "dociter.hxx"
|
|
|
|
#include "cell.hxx"
|
|
|
|
#include "scmatrix.hxx"
|
|
|
|
#include "docoptio.hxx"
|
|
|
|
#include "globstr.hrc"
|
2001-03-08 10:57:21 +00:00
|
|
|
#include "attrib.hxx"
|
2004-03-08 10:47:52 +00:00
|
|
|
#include "jumpmatrix.hxx"
|
2007-07-24 08:23:19 +00:00
|
|
|
#include "cellkeytranslator.hxx"
|
2007-09-27 12:53:45 +00:00
|
|
|
#include "lookupcache.hxx"
|
2008-01-29 07:02:08 +00:00
|
|
|
#include "rangenam.hxx"
|
2000-09-18 23:16:46 +00:00
|
|
|
|
2004-03-08 10:47:52 +00:00
|
|
|
#define SC_DOUBLE_MAXVALUE 1.7e307
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 )
|
|
|
|
IMPL_FIXEDMEMPOOL_NEWDEL( ScErrorStack, 8, 4 )
|
|
|
|
IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 )
|
|
|
|
|
|
|
|
ScTokenStack* ScInterpreter::pGlobalStack = NULL;
|
|
|
|
ScErrorStack* ScInterpreter::pGlobalErrorStack = NULL;
|
|
|
|
BOOL ScInterpreter::bGlobalStackInUse = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Funktionen
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIfJump()
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
const short* pJump = pCur->GetJump();
|
|
|
|
short nJumpCount = pJump[ 0 ];
|
2004-03-08 10:47:52 +00:00
|
|
|
MatrixDoubleRefToMatrix();
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
{
|
2005-03-29 12:32:52 +00:00
|
|
|
ScTokenRef xNew;
|
|
|
|
ScTokenMatrixMap::const_iterator aMapIter;
|
2004-03-08 10:47:52 +00:00
|
|
|
// DoubleError handled by JumpMatrix
|
|
|
|
pMat->SetErrorInterpreter( NULL);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows );
|
|
|
|
if ( nCols == 0 || nRows == 0 )
|
|
|
|
SetIllegalParameter();
|
2005-03-29 12:32:52 +00:00
|
|
|
else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
|
|
|
|
pCur)) != pTokenMatrixMap->end()))
|
|
|
|
xNew = (*aMapIter).second;
|
2004-03-08 10:47:52 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for ( SCSIZE nC=0; nC < nCols; ++nC )
|
2004-03-08 10:47:52 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for ( SCSIZE nR=0; nR < nRows; ++nR )
|
2004-03-08 10:47:52 +00:00
|
|
|
{
|
|
|
|
double fVal;
|
|
|
|
bool bTrue;
|
2004-10-22 06:58:58 +00:00
|
|
|
ScMatValType nType = 0;
|
|
|
|
const ScMatrixValue* pMatVal = pMat->Get( nC, nR,
|
|
|
|
nType);
|
2007-06-13 08:07:39 +00:00
|
|
|
bool bIsValue = ScMatrix::IsValueType( nType);
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( bIsValue )
|
|
|
|
{
|
|
|
|
fVal = pMatVal->fVal;
|
|
|
|
bIsValue = ::rtl::math::isFinite( fVal );
|
|
|
|
bTrue = bIsValue && (fVal != 0.0);
|
|
|
|
if ( bTrue )
|
|
|
|
fVal = 1.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bTrue = false;
|
|
|
|
fVal = 0.0;
|
|
|
|
}
|
|
|
|
if ( bTrue )
|
|
|
|
{ // TRUE
|
|
|
|
if( nJumpCount >= 2 )
|
|
|
|
{ // THEN path
|
|
|
|
pJumpMat->SetJump( nC, nR, fVal,
|
|
|
|
pJump[ 1 ],
|
|
|
|
pJump[ nJumpCount ]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // no parameter given for THEN
|
|
|
|
pJumpMat->SetJump( nC, nR, fVal,
|
|
|
|
pJump[ nJumpCount ],
|
|
|
|
pJump[ nJumpCount ]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // FALSE
|
|
|
|
if( nJumpCount == 3 && bIsValue )
|
|
|
|
{ // ELSE path
|
|
|
|
pJumpMat->SetJump( nC, nR, fVal,
|
|
|
|
pJump[ 2 ],
|
|
|
|
pJump[ nJumpCount ]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // no parameter given for ELSE,
|
|
|
|
// or DoubleError
|
|
|
|
pJumpMat->SetJump( nC, nR, fVal,
|
|
|
|
pJump[ nJumpCount ],
|
|
|
|
pJump[ nJumpCount ]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-29 12:32:52 +00:00
|
|
|
xNew = new ScJumpMatrixToken( pJumpMat );
|
|
|
|
GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type(
|
|
|
|
pCur, xNew));
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
2005-03-29 12:32:52 +00:00
|
|
|
PushTempToken( xNew);
|
|
|
|
// set endpoint of path for main code line
|
|
|
|
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if ( GetBool() )
|
|
|
|
{ // TRUE
|
|
|
|
if( nJumpCount >= 2 )
|
|
|
|
{ // THEN path
|
|
|
|
aCode.Jump( pJump[ 1 ], pJump[ nJumpCount ] );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // no parameter given for THEN
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
PushInt(1);
|
|
|
|
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // FALSE
|
|
|
|
if( nJumpCount == 3 )
|
|
|
|
{ // ELSE path
|
|
|
|
aCode.Jump( pJump[ 2 ], pJump[ nJumpCount ] );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // no parameter given for ELSE
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
PushInt(0);
|
|
|
|
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScChoseJump()
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
const short* pJump = pCur->GetJump();
|
|
|
|
short nJumpCount = pJump[ 0 ];
|
2004-03-08 10:47:52 +00:00
|
|
|
MatrixDoubleRefToMatrix();
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
{
|
2005-03-29 12:32:52 +00:00
|
|
|
ScTokenRef xNew;
|
|
|
|
ScTokenMatrixMap::const_iterator aMapIter;
|
2004-03-08 10:47:52 +00:00
|
|
|
// DoubleError handled by JumpMatrix
|
|
|
|
pMat->SetErrorInterpreter( NULL);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows );
|
|
|
|
if ( nCols == 0 || nRows == 0 )
|
|
|
|
SetIllegalParameter();
|
2005-03-29 12:32:52 +00:00
|
|
|
else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
|
|
|
|
pCur)) != pTokenMatrixMap->end()))
|
|
|
|
xNew = (*aMapIter).second;
|
2004-03-08 10:47:52 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for ( SCSIZE nC=0; nC < nCols; ++nC )
|
2004-03-08 10:47:52 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for ( SCSIZE nR=0; nR < nRows; ++nR )
|
2004-03-08 10:47:52 +00:00
|
|
|
{
|
|
|
|
double fVal;
|
2004-10-22 06:58:58 +00:00
|
|
|
ScMatValType nType;
|
|
|
|
const ScMatrixValue* pMatVal = pMat->Get( nC, nR,
|
|
|
|
nType);
|
2007-06-13 08:07:39 +00:00
|
|
|
bool bIsValue = ScMatrix::IsValueType( nType);
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( bIsValue )
|
|
|
|
{
|
|
|
|
fVal = pMatVal->fVal;
|
|
|
|
bIsValue = ::rtl::math::isFinite( fVal );
|
|
|
|
if ( bIsValue )
|
|
|
|
{
|
|
|
|
fVal = ::rtl::math::approxFloor( fVal);
|
|
|
|
if ( (fVal < 1) || (fVal >= nJumpCount))
|
|
|
|
{
|
|
|
|
bIsValue = FALSE;
|
|
|
|
fVal = CreateDoubleError(
|
|
|
|
errIllegalArgument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( errNoValue);
|
|
|
|
}
|
|
|
|
if ( bIsValue )
|
|
|
|
{
|
|
|
|
pJumpMat->SetJump( nC, nR, fVal,
|
|
|
|
pJump[ (short)fVal ],
|
|
|
|
pJump[ nJumpCount ]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pJumpMat->SetJump( nC, nR, fVal,
|
|
|
|
pJump[ nJumpCount ],
|
|
|
|
pJump[ nJumpCount ]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-29 12:32:52 +00:00
|
|
|
xNew = new ScJumpMatrixToken( pJumpMat );
|
|
|
|
GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type(
|
|
|
|
pCur, xNew));
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
2005-03-29 12:32:52 +00:00
|
|
|
PushTempToken( xNew);
|
|
|
|
// set endpoint of path for main code line
|
|
|
|
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
double nJumpIndex = ::rtl::math::approxFloor( GetDouble() );
|
|
|
|
if ((nJumpIndex >= 1) && (nJumpIndex < nJumpCount))
|
|
|
|
aCode.Jump( pJump[ (short) nJumpIndex ], pJump[ nJumpCount ] );
|
|
|
|
else
|
|
|
|
SetError(errIllegalArgument);
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-08 10:47:52 +00:00
|
|
|
bool ScInterpreter::JumpMatrix( short nStackLevel )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
pJumpMatrix = pStack[sp-nStackLevel]->GetJumpMatrix();
|
|
|
|
ScMatrixRef pResMat = pJumpMatrix->GetResultMatrix();
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( nStackLevel == 2 )
|
|
|
|
{
|
|
|
|
if ( aCode.HasStacked() )
|
|
|
|
aCode.Pop(); // pop what Jump() pushed
|
|
|
|
else
|
2008-01-29 14:22:31 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
DBG_ERRORFILE( "ScInterpreter::JumpMatrix: pop goes the weasel" );
|
2008-01-29 14:22:31 +00:00
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
|
|
|
|
if ( !pResMat )
|
|
|
|
{
|
|
|
|
Pop();
|
|
|
|
SetError( errUnknownStackVariable );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pJumpMatrix->GetPos( nC, nR );
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
{
|
|
|
|
double fVal = GetDouble();
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( nGlobalError );
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
{
|
|
|
|
const String& rStr = GetString();
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
pResMat->PutDouble( CreateDoubleError( nGlobalError),
|
|
|
|
nC, nR);
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pResMat->PutString( rStr, nC, nR );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svSingleRef:
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
pResMat->PutDouble( CreateDoubleError( nGlobalError),
|
|
|
|
nC, nR);
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_NONE:
|
|
|
|
case CELLTYPE_NOTE:
|
|
|
|
pResMat->PutEmpty( nC, nR );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if ( HasCellValueData( pCell ) )
|
|
|
|
{
|
|
|
|
double fVal = GetCellValue( aAdr, pCell);
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError(
|
|
|
|
nGlobalError);
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
String aStr;
|
|
|
|
GetCellString( aStr, pCell );
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
pResMat->PutDouble( CreateDoubleError(
|
|
|
|
nGlobalError), nC, nR);
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pResMat->PutString( aStr, nC, nR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
{ // upper left plus offset within matrix
|
|
|
|
double fVal;
|
|
|
|
ScRange aRange;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
ScAddress& rAdr = aRange.aStart;
|
|
|
|
ULONG nCol = (ULONG)rAdr.Col() + nC;
|
|
|
|
ULONG nRow = (ULONG)rAdr.Row() + nR;
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( nGlobalError );
|
|
|
|
nGlobalError = 0;
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
else if ( nCol > static_cast<ULONG>(aRange.aEnd.Col()) ||
|
|
|
|
nRow > static_cast<ULONG>(aRange.aEnd.Row()))
|
2004-03-08 10:47:52 +00:00
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( errNoValue );
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
rAdr.SetCol( static_cast<SCCOL>(nCol) );
|
|
|
|
rAdr.SetRow( static_cast<SCROW>(nRow) );
|
2004-03-08 10:47:52 +00:00
|
|
|
ScBaseCell* pCell = GetCell( rAdr );
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_NONE:
|
|
|
|
case CELLTYPE_NOTE:
|
|
|
|
pResMat->PutEmpty( nC, nR );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if ( HasCellValueData( pCell ) )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
double fCellVal = GetCellValue( rAdr, pCell);
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
fCellVal = CreateDoubleError(
|
2004-03-08 10:47:52 +00:00
|
|
|
nGlobalError);
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
2007-02-27 11:16:06 +00:00
|
|
|
pResMat->PutDouble( fCellVal, nC, nR );
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
String aStr;
|
|
|
|
GetCellString( aStr, pCell );
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
pResMat->PutDouble( CreateDoubleError(
|
|
|
|
nGlobalError), nC, nR);
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pResMat->PutString( aStr, nC, nR );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{ // match matrix offsets
|
|
|
|
double fVal;
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( nGlobalError );
|
|
|
|
nGlobalError = 0;
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
else if ( !pMat )
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( errUnknownVariable );
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows );
|
|
|
|
if ( nCols <= nC || nRows <= nR )
|
|
|
|
{
|
|
|
|
fVal = CreateDoubleError( errNoValue );
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( pMat->IsValue( nC, nR ) )
|
|
|
|
{
|
|
|
|
fVal = pMat->GetDouble( nC, nR );
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
else if ( pMat->IsEmpty( nC, nR ) )
|
|
|
|
pResMat->PutEmpty( nC, nR );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const String& rStr = pMat->GetString( nC, nR );
|
|
|
|
pResMat->PutString( rStr, nC, nR );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
Pop();
|
|
|
|
double fVal = CreateDoubleError( errIllegalArgument);
|
|
|
|
pResMat->PutDouble( fVal, nC, nR );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool bCont = pJumpMatrix->Next( nC, nR );
|
|
|
|
if ( bCont )
|
|
|
|
{
|
|
|
|
double fBool;
|
|
|
|
short nStart, nNext, nStop;
|
|
|
|
pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
|
|
|
|
while ( bCont && nStart == nNext )
|
|
|
|
{ // push all results that have no jump path
|
|
|
|
if ( pResMat )
|
|
|
|
{
|
|
|
|
// a FALSE without path results in an empty path value
|
|
|
|
if ( fBool == 0.0 )
|
|
|
|
pResMat->PutEmptyPath( nC, nR );
|
|
|
|
else
|
|
|
|
pResMat->PutDouble( fBool, nC, nR );
|
|
|
|
}
|
|
|
|
bCont = pJumpMatrix->Next( nC, nR );
|
|
|
|
if ( bCont )
|
|
|
|
pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
|
|
|
|
}
|
|
|
|
if ( bCont && nStart != nNext )
|
|
|
|
{
|
|
|
|
const ScTokenVec* pParams = pJumpMatrix->GetJumpParameters();
|
|
|
|
if ( pParams )
|
|
|
|
{
|
|
|
|
for ( ScTokenVec::const_iterator i = pParams->begin();
|
|
|
|
i != pParams->end(); ++i )
|
|
|
|
{
|
|
|
|
Push( *(*i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aCode.Jump( nStart, nNext, nStop );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !bCont )
|
|
|
|
{ // we're done with it, throw away jump matrix, keep result
|
|
|
|
pJumpMatrix = NULL;
|
|
|
|
Pop();
|
|
|
|
PushMatrix( pResMat );
|
2005-03-29 12:32:52 +00:00
|
|
|
// Remove jump matrix from map and remember result matrix in case it
|
|
|
|
// could be reused in another path of the same condition.
|
|
|
|
if (pTokenMatrixMap)
|
|
|
|
{
|
|
|
|
pTokenMatrixMap->erase( pCur);
|
|
|
|
pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pCur,
|
|
|
|
pStack[sp-1]));
|
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double ScInterpreter::CompareFunc( const ScCompare& rComp )
|
|
|
|
{
|
|
|
|
// Keep DoubleError if encountered
|
2005-01-28 16:20:19 +00:00
|
|
|
// #i40539# if bEmpty is set, bVal/nVal are uninitialized
|
|
|
|
if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
|
2004-03-08 10:47:52 +00:00
|
|
|
return rComp.nVal[0];
|
2005-01-28 16:20:19 +00:00
|
|
|
if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
|
2004-03-08 10:47:52 +00:00
|
|
|
return rComp.nVal[1];
|
|
|
|
|
|
|
|
double fRes = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( rComp.bEmpty[ 0 ] )
|
|
|
|
{
|
|
|
|
if ( rComp.bEmpty[ 1 ] )
|
2004-03-08 10:47:52 +00:00
|
|
|
; // empty cell == empty cell, fRes 0
|
2000-09-18 23:16:46 +00:00
|
|
|
else if( rComp.bVal[ 1 ] )
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
if ( !::rtl::math::approxEqual( rComp.nVal[ 1 ], 0.0 ) )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if ( rComp.nVal[ 1 ] < 0.0 )
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = 1; // empty cell > -x
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = -1; // empty cell < x
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
// else: empty cell == 0.0
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( rComp.pVal[ 1 ]->Len() )
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = -1; // empty cell < "..."
|
|
|
|
// else: empty cell == ""
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( rComp.bEmpty[ 1 ] )
|
|
|
|
{
|
|
|
|
if( rComp.bVal[ 0 ] )
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], 0.0 ) )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if ( rComp.nVal[ 0 ] < 0.0 )
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = -1; // -x < empty cell
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = 1; // x > empty cell
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
// else: empty cell == 0.0
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( rComp.pVal[ 0 ]->Len() )
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = 1; // "..." > empty cell
|
|
|
|
// else: "" == empty cell
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( rComp.bVal[ 0 ] )
|
|
|
|
{
|
|
|
|
if( rComp.bVal[ 1 ] )
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 )
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = -1;
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = 1;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = -1; // number is less than string
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else if( rComp.bVal[ 1 ] )
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = 1; // number is less than string
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pDok->GetDocOptions().IsIgnoreCase())
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = (double) ScGlobal::pCollator->compareString(
|
2001-03-14 15:02:54 +00:00
|
|
|
*rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
fRes = (double) ScGlobal::pCaseCollator->compareString(
|
2001-07-11 14:28:50 +00:00
|
|
|
*rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
return fRes;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-08 10:47:52 +00:00
|
|
|
double ScInterpreter::Compare()
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
String aVal1, aVal2;
|
|
|
|
ScCompare aComp( &aVal1, &aVal2 );
|
|
|
|
for( short i = 1; i >= 0; i-- )
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
aComp.nVal[ i ] = GetDouble();
|
|
|
|
aComp.bVal[ i ] = TRUE;
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
*aComp.pVal[ i ] = GetString();
|
|
|
|
aComp.bVal[ i ] = FALSE;
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
|
|
|
|
{
|
|
|
|
if (HasCellStringData(pCell))
|
|
|
|
{
|
|
|
|
GetCellString(*aComp.pVal[ i ], pCell);
|
|
|
|
aComp.bVal[ i ] = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aComp.nVal[ i ] = GetCellValue( aAdr, pCell );
|
|
|
|
aComp.bVal[ i ] = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aComp.bEmpty[ i ] = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( nGlobalError )
|
|
|
|
return 0;
|
|
|
|
return CompareFunc( aComp );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef ScInterpreter::CompareMat()
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
String aVal1, aVal2;
|
|
|
|
ScCompare aComp( &aVal1, &aVal2 );
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat[2];
|
2000-09-18 23:16:46 +00:00
|
|
|
ScAddress aAdr;
|
|
|
|
for( short i = 1; i >= 0; i-- )
|
|
|
|
{
|
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
aComp.nVal[ i ] = GetDouble();
|
|
|
|
aComp.bVal[ i ] = TRUE;
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
*aComp.pVal[ i ] = GetString();
|
|
|
|
aComp.bVal[ i ] = FALSE;
|
|
|
|
break;
|
|
|
|
case svSingleRef:
|
|
|
|
{
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
|
|
|
|
{
|
|
|
|
if (HasCellStringData(pCell))
|
|
|
|
{
|
|
|
|
GetCellString(*aComp.pVal[ i ], pCell);
|
|
|
|
aComp.bVal[ i ] = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aComp.nVal[ i ] = GetCellValue( aAdr, pCell );
|
|
|
|
aComp.bVal[ i ] = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aComp.bEmpty[ i ] = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
case svMatrix:
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat[ i ] = GetMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat[ i ] )
|
|
|
|
SetError(errIllegalParameter);
|
2004-03-08 10:47:52 +00:00
|
|
|
else
|
|
|
|
pMat[i]->SetErrorInterpreter( NULL);
|
|
|
|
// errors are transported as DoubleError inside matrix
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pResMat = NULL;
|
2000-09-18 23:16:46 +00:00
|
|
|
if( !nGlobalError )
|
|
|
|
{
|
|
|
|
if ( pMat[0] && pMat[1] )
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC0, nC1;
|
|
|
|
SCSIZE nR0, nR1;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat[0]->GetDimensions( nC0, nR0 );
|
|
|
|
pMat[1]->GetDimensions( nC1, nR1 );
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC = Max( nC0, nC1 );
|
|
|
|
SCSIZE nR = Max( nR0, nR1 );
|
2004-03-08 10:47:52 +00:00
|
|
|
pResMat = GetNewMat( nC, nR);
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pResMat )
|
|
|
|
return NULL;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for ( SCSIZE j=0; j<nC; j++ )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for ( SCSIZE k=0; k<nR; k++ )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if ( j < nC0 && j < nC1 && k < nR0 && k < nR1 )
|
|
|
|
{
|
|
|
|
for ( short i=1; i>=0; i-- )
|
|
|
|
{
|
|
|
|
if ( pMat[i]->IsString(j,k) )
|
|
|
|
{
|
|
|
|
aComp.bVal[i] = FALSE;
|
|
|
|
*aComp.pVal[i] = pMat[i]->GetString(j,k);
|
|
|
|
aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aComp.bVal[i] = TRUE;
|
|
|
|
aComp.nVal[i] = pMat[i]->GetDouble(j,k);
|
|
|
|
aComp.bEmpty[i] = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pResMat->PutDouble( CompareFunc( aComp ), j,k );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pResMat->PutString( ScGlobal::GetRscString(STR_NO_VALUE), j,k );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( pMat[0] || pMat[1] )
|
|
|
|
{
|
|
|
|
short i = ( pMat[0] ? 0 : 1);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat[i]->GetDimensions( nC, nR );
|
2004-03-08 10:47:52 +00:00
|
|
|
pResMat = GetNewMat( nC, nR);
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pResMat )
|
|
|
|
return NULL;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE n = nC * nR;
|
|
|
|
for ( SCSIZE j=0; j<n; j++ )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if ( pMat[i]->IsValue(j) )
|
|
|
|
{
|
|
|
|
aComp.bVal[i] = TRUE;
|
|
|
|
aComp.nVal[i] = pMat[i]->GetDouble(j);
|
|
|
|
aComp.bEmpty[i] = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aComp.bVal[i] = FALSE;
|
|
|
|
*aComp.pVal[i] = pMat[i]->GetString(j);
|
|
|
|
aComp.bEmpty[i] = pMat[i]->IsEmpty(j);
|
|
|
|
}
|
|
|
|
pResMat->PutDouble( CompareFunc( aComp ), j );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pResMat;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScEqual()
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = CompareMat();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMat->CompareEqual();
|
|
|
|
PushMatrix( pMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushInt( Compare() == 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScNotEqual()
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = CompareMat();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMat->CompareNotEqual();
|
|
|
|
PushMatrix( pMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushInt( Compare() != 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScLess()
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = CompareMat();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMat->CompareLess();
|
|
|
|
PushMatrix( pMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushInt( Compare() < 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScGreater()
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = CompareMat();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMat->CompareGreater();
|
|
|
|
PushMatrix( pMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushInt( Compare() > 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScLessEqual()
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = CompareMat();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMat->CompareLessEqual();
|
|
|
|
PushMatrix( pMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushInt( Compare() <= 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScGreaterEqual()
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = CompareMat();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( !pMat )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMat->CompareGreaterEqual();
|
|
|
|
PushMatrix( pMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushInt( Compare() >= 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScAnd()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCountMin( nParamCount, 1 ) )
|
|
|
|
{
|
|
|
|
BOOL bHaveValue = FALSE;
|
|
|
|
short nRes = TRUE;
|
|
|
|
while( nParamCount-- )
|
|
|
|
{
|
|
|
|
if ( !nGlobalError )
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble :
|
|
|
|
bHaveValue = TRUE;
|
|
|
|
nRes &= ( PopDouble() != 0.0 );
|
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
Pop();
|
|
|
|
SetError( errNoValue );
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
if ( !nGlobalError )
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( HasCellValueData( pCell ) )
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
|
|
|
nRes &= ( GetCellValue( aAdr, pCell ) != 0.0 );
|
|
|
|
}
|
|
|
|
// else: Xcl setzt hier keinen Fehler
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
{
|
|
|
|
ScRange aRange;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
if ( !nGlobalError )
|
|
|
|
{
|
|
|
|
double fVal;
|
|
|
|
USHORT nErr = 0;
|
|
|
|
ScValueIterator aValIter( pDok, aRange );
|
|
|
|
if ( aValIter.GetFirst( fVal, nErr ) )
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nRes &= ( fVal != 0.0 );
|
|
|
|
} while ( (nErr == 0) &&
|
|
|
|
aValIter.GetNext( fVal, nErr ) );
|
|
|
|
}
|
|
|
|
SetError( nErr );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = GetMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( pMat )
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
2004-03-08 10:47:52 +00:00
|
|
|
double fVal = pMat->And();
|
|
|
|
USHORT nErr = GetDoubleErrorValue( fVal );
|
|
|
|
if ( nErr )
|
|
|
|
{
|
|
|
|
SetError( nErr );
|
|
|
|
nRes = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nRes &= (fVal != 0.0);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
// else: GetMatrix hat errIllegalParameter gesetzt
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
if ( bHaveValue )
|
|
|
|
PushInt( nRes );
|
|
|
|
else
|
|
|
|
SetNoValue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScOr()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCountMin( nParamCount, 1 ) )
|
|
|
|
{
|
|
|
|
BOOL bHaveValue = FALSE;
|
|
|
|
short nRes = FALSE;
|
|
|
|
while( nParamCount-- )
|
|
|
|
{
|
|
|
|
if ( !nGlobalError )
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble :
|
|
|
|
bHaveValue = TRUE;
|
|
|
|
nRes |= ( PopDouble() != 0.0 );
|
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
Pop();
|
|
|
|
SetError( errNoValue );
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
if ( !nGlobalError )
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( HasCellValueData( pCell ) )
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
|
|
|
nRes |= ( GetCellValue( aAdr, pCell ) != 0.0 );
|
|
|
|
}
|
|
|
|
// else: Xcl setzt hier keinen Fehler
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
{
|
|
|
|
ScRange aRange;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
if ( !nGlobalError )
|
|
|
|
{
|
|
|
|
double fVal;
|
|
|
|
USHORT nErr = 0;
|
|
|
|
ScValueIterator aValIter( pDok, aRange );
|
|
|
|
if ( aValIter.GetFirst( fVal, nErr ) )
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nRes |= ( fVal != 0.0 );
|
|
|
|
} while ( (nErr == 0) &&
|
|
|
|
aValIter.GetNext( fVal, nErr ) );
|
|
|
|
}
|
|
|
|
SetError( nErr );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = GetMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( pMat )
|
|
|
|
{
|
|
|
|
bHaveValue = TRUE;
|
2004-03-08 10:47:52 +00:00
|
|
|
double fVal = pMat->Or();
|
|
|
|
USHORT nErr = GetDoubleErrorValue( fVal );
|
|
|
|
if ( nErr )
|
|
|
|
{
|
|
|
|
SetError( nErr );
|
|
|
|
nRes = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nRes |= (fVal != 0.0);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
// else: GetMatrix hat errIllegalParameter gesetzt
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
if ( bHaveValue )
|
|
|
|
PushInt( nRes );
|
|
|
|
else
|
|
|
|
SetNoValue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-23 17:38:10 +00:00
|
|
|
void ScInterpreter::ScNeg()
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-10-22 06:58:58 +00:00
|
|
|
// Simple negation doesn't change current format type to number, keep
|
|
|
|
// current type.
|
|
|
|
nFuncFmtType = nCurFmtType;
|
2001-04-23 17:38:10 +00:00
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svMatrix :
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = GetMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
PushError();
|
|
|
|
else
|
2001-04-23 17:38:10 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2001-04-23 17:38:10 +00:00
|
|
|
pMat->GetDimensions( nC, nR );
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pResMat = GetNewMat( nC, nR);
|
2001-04-23 17:38:10 +00:00
|
|
|
if ( !pResMat )
|
2004-03-08 10:47:52 +00:00
|
|
|
PushError();
|
2001-04-23 17:38:10 +00:00
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCount = nC * nR;
|
|
|
|
for ( SCSIZE j=0; j<nCount; ++j )
|
2001-04-23 17:38:10 +00:00
|
|
|
{
|
2001-04-23 19:25:02 +00:00
|
|
|
if ( pMat->IsValueOrEmpty(j) )
|
2001-04-23 17:38:10 +00:00
|
|
|
pResMat->PutDouble( -pMat->GetDouble(j), j );
|
|
|
|
else
|
|
|
|
pResMat->PutString(
|
|
|
|
ScGlobal::GetRscString( STR_NO_VALUE ), j );
|
|
|
|
}
|
|
|
|
PushMatrix( pResMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PushDouble( -GetDouble() );
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-12 20:32:50 +00:00
|
|
|
void ScInterpreter::ScPercentSign()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_PERCENT;
|
|
|
|
const ScToken* pSaveCur = pCur;
|
|
|
|
BYTE nSavePar = cPar;
|
|
|
|
PushInt( 100 );
|
|
|
|
cPar = 2;
|
|
|
|
ScByteToken aDivOp( ocDiv, cPar );
|
|
|
|
pCur = &aDivOp;
|
|
|
|
ScDiv();
|
|
|
|
pCur = pSaveCur;
|
|
|
|
cPar = nSavePar;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-23 17:38:10 +00:00
|
|
|
void ScInterpreter::ScNot()
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-04-23 17:38:10 +00:00
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
2004-03-08 10:47:52 +00:00
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = GetMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
PushError();
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nC, nR );
|
|
|
|
ScMatrixRef pResMat = GetNewMat( nC, nR);
|
|
|
|
if ( !pResMat )
|
|
|
|
PushError();
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCount = nC * nR;
|
|
|
|
for ( SCSIZE j=0; j<nCount; ++j )
|
2004-03-08 10:47:52 +00:00
|
|
|
{
|
|
|
|
if ( pMat->IsValueOrEmpty(j) )
|
|
|
|
pResMat->PutDouble( (pMat->GetDouble(j) == 0.0), j );
|
|
|
|
else
|
|
|
|
pResMat->PutString(
|
|
|
|
ScGlobal::GetRscString( STR_NO_VALUE ), j );
|
|
|
|
}
|
|
|
|
PushMatrix( pResMat );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PushInt( GetDouble() == 0.0 );
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScPi()
|
|
|
|
{
|
|
|
|
PushDouble(F_PI);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScRandom()
|
|
|
|
{
|
2008-01-29 14:22:31 +00:00
|
|
|
PushDouble((double)rand() / ((double)RAND_MAX+1.0));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScTrue()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
PushInt(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScFalse()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
PushInt(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDeg()
|
|
|
|
{
|
|
|
|
PushDouble((GetDouble() / F_PI) * 180.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScRad()
|
|
|
|
{
|
|
|
|
PushDouble(GetDouble() * (F_PI / 180));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSin()
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
PushDouble(::rtl::math::sin(GetDouble()));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCos()
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
PushDouble(::rtl::math::cos(GetDouble()));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScTan()
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
PushDouble(::rtl::math::tan(GetDouble()));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCot()
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
PushDouble(1.0 / ::rtl::math::tan(GetDouble()));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcSin()
|
|
|
|
{
|
|
|
|
PushDouble(asin(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcCos()
|
|
|
|
{
|
|
|
|
PushDouble(acos(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcTan()
|
|
|
|
{
|
|
|
|
PushDouble(atan(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcCot()
|
|
|
|
{
|
|
|
|
PushDouble((F_PI2) - atan(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSinHyp()
|
|
|
|
{
|
|
|
|
PushDouble(sinh(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCosHyp()
|
|
|
|
{
|
|
|
|
PushDouble(cosh(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScTanHyp()
|
|
|
|
{
|
|
|
|
PushDouble(tanh(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCotHyp()
|
|
|
|
{
|
|
|
|
PushDouble(1.0 / tanh(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcSinHyp()
|
|
|
|
{
|
|
|
|
double nVal = GetDouble();
|
|
|
|
PushDouble(log(nVal + sqrt((nVal * nVal) + 1.0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcCosHyp()
|
|
|
|
{
|
|
|
|
double nVal = GetDouble();
|
|
|
|
if (nVal < 1.0)
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
PushDouble(log(nVal + sqrt((nVal * nVal) - 1.0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcTanHyp()
|
|
|
|
{
|
|
|
|
double nVal = GetDouble();
|
|
|
|
if (fabs(nVal) >= 1.0)
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
PushDouble(0.5 * log((1.0 + nVal) / (1.0 - nVal)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScArcCotHyp()
|
|
|
|
{
|
|
|
|
double nVal = GetDouble();
|
|
|
|
if (fabs(nVal) <= 1.0)
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
PushDouble(0.5 * log((nVal + 1.0) / (nVal - 1.0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScExp()
|
|
|
|
{
|
|
|
|
PushDouble(exp(GetDouble()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSqrt()
|
|
|
|
{
|
|
|
|
double fVal = GetDouble();
|
|
|
|
if (fVal >= 0.0)
|
|
|
|
PushDouble(sqrt(fVal));
|
|
|
|
else
|
|
|
|
SetIllegalArgument();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsEmpty()
|
|
|
|
{
|
|
|
|
short nRes = 0;
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
CellType eCellType = GetCellType( GetCell( aAdr ) );
|
|
|
|
if((eCellType == CELLTYPE_NONE) || (eCellType == CELLTYPE_NOTE))
|
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
break;
|
2004-03-08 10:47:52 +00:00
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
; // nothing
|
|
|
|
else if ( !pJumpMatrix )
|
|
|
|
nRes = pMat->IsEmpty( 0 );
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
|
|
|
nRes = pMat->IsEmpty( nC, nR);
|
|
|
|
// else: FALSE, not empty (which is what Xcl does)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
short ScInterpreter::IsString()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (GetCellErrCode( pCell ) == 0)
|
|
|
|
{
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_STRING :
|
|
|
|
case CELLTYPE_EDIT :
|
|
|
|
nRes = 1;
|
|
|
|
break;
|
|
|
|
case CELLTYPE_FORMULA :
|
|
|
|
nRes = !((ScFormulaCell*)pCell)->IsValue();
|
|
|
|
break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default:
|
|
|
|
; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
PopError();
|
|
|
|
if ( !nGlobalError )
|
|
|
|
nRes = 1;
|
2004-03-08 10:47:52 +00:00
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
; // nothing
|
|
|
|
else if ( !pJumpMatrix )
|
|
|
|
nRes = pMat->IsString(0) && !pMat->IsEmpty(0);
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
|
|
|
nRes = pMat->IsString( nC, nR) && !pMat->IsEmpty( nC, nR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
return nRes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsString()
|
|
|
|
{
|
|
|
|
PushInt( IsString() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsNonString()
|
|
|
|
{
|
|
|
|
PushInt( !IsString() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-27 11:16:06 +00:00
|
|
|
void ScInterpreter::ScIsLogical(UINT16 /* aOldNumType */)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (GetCellErrCode( pCell ) == 0)
|
|
|
|
{
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
ULONG nFormat = GetCellNumberFormat( aAdr, pCell );
|
|
|
|
nRes = ( pFormatter->GetType(nFormat)
|
|
|
|
== NUMBERFORMAT_LOGICAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-03-08 10:47:52 +00:00
|
|
|
case svMatrix:
|
|
|
|
// TODO: we don't have type information for arrays except
|
|
|
|
// numerical/string.
|
|
|
|
// Fall thru
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
if ( !nGlobalError )
|
|
|
|
nRes = ( nCurFmtType == NUMBERFORMAT_LOGICAL );
|
|
|
|
}
|
|
|
|
nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScType()
|
|
|
|
{
|
|
|
|
short nType = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (GetCellErrCode( pCell ) == 0)
|
|
|
|
{
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
2006-05-05 08:34:33 +00:00
|
|
|
case CELLTYPE_NOTE :
|
|
|
|
nType = 1; // empty cell is value (0)
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
case CELLTYPE_STRING :
|
|
|
|
case CELLTYPE_EDIT :
|
|
|
|
nType = 2;
|
|
|
|
break;
|
|
|
|
case CELLTYPE_VALUE :
|
|
|
|
{
|
|
|
|
ULONG nFormat = GetCellNumberFormat( aAdr, pCell );
|
|
|
|
if (pFormatter->GetType(nFormat)
|
|
|
|
== NUMBERFORMAT_LOGICAL)
|
|
|
|
nType = 4;
|
|
|
|
else
|
|
|
|
nType = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CELLTYPE_FORMULA :
|
|
|
|
nType = 8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nType = 16;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
PopError();
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
nType = 16;
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nType = 2;
|
2004-03-08 10:47:52 +00:00
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
PopMatrix();
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
nType = 16;
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nType = 64;
|
|
|
|
// we could return the type of one element if in JumpMatrix or
|
|
|
|
// ForceArray mode, but Xcl doesn't ...
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
if ( nGlobalError )
|
|
|
|
{
|
|
|
|
nType = 16;
|
|
|
|
nGlobalError = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nType = 1;
|
|
|
|
}
|
|
|
|
PushInt( nType );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-08 10:57:21 +00:00
|
|
|
inline BOOL lcl_FormatHasNegColor( const SvNumberformat* pFormat )
|
|
|
|
{
|
|
|
|
return pFormat && pFormat->GetColor( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline BOOL lcl_FormatHasOpenPar( const SvNumberformat* pFormat )
|
|
|
|
{
|
|
|
|
return pFormat && (pFormat->GetFormatstring().Search( '(' ) != STRING_NOTFOUND);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCell()
|
|
|
|
{ // ATTRIBUTE ; [REF]
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if( MustHaveParamCount( nParamCount, 1, 2 ) )
|
|
|
|
{
|
|
|
|
ScAddress aCellPos( aPos );
|
|
|
|
BOOL bError = FALSE;
|
|
|
|
if( nParamCount == 2 )
|
|
|
|
bError = !PopDoubleRefOrSingleRef( aCellPos );
|
|
|
|
String aInfoType( GetString() );
|
|
|
|
if( bError || nGlobalError )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
String aFuncResult;
|
2001-03-08 10:57:21 +00:00
|
|
|
ScBaseCell* pCell = GetCell( aCellPos );
|
|
|
|
|
2007-07-24 08:23:19 +00:00
|
|
|
ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::pLocale, ocCell);
|
2001-03-08 10:57:21 +00:00
|
|
|
|
|
|
|
// *** ADDRESS INFO ***
|
|
|
|
if( aInfoType.EqualsAscii( "COL" ) )
|
|
|
|
{ // column number (1-based)
|
|
|
|
PushInt( aCellPos.Col() + 1 );
|
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "ROW" ) )
|
|
|
|
{ // row number (1-based)
|
|
|
|
PushInt( aCellPos.Row() + 1 );
|
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "SHEET" ) )
|
|
|
|
{ // table number (1-based)
|
|
|
|
PushInt( aCellPos.Tab() + 1 );
|
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "ADDRESS" ) )
|
|
|
|
{ // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW
|
|
|
|
USHORT nFlags = (aCellPos.Tab() == aPos.Tab()) ? (SCA_ABS) : (SCA_ABS_3D);
|
2007-02-27 11:16:06 +00:00
|
|
|
aCellPos.Format( aFuncResult, nFlags, pDok );
|
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "FILENAME" ) )
|
|
|
|
{ // file name and table name: 'FILENAME'#$TABLE
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab = aCellPos.Tab();
|
2001-03-08 10:57:21 +00:00
|
|
|
if( nTab < pDok->GetTableCount() )
|
|
|
|
{
|
|
|
|
if( pDok->GetLinkMode( nTab ) == SC_LINK_VALUE )
|
2007-02-27 11:16:06 +00:00
|
|
|
pDok->GetName( nTab, aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
SfxObjectShell* pShell = pDok->GetDocumentShell();
|
|
|
|
if( pShell && pShell->GetMedium() )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult = (sal_Unicode) '\'';
|
2006-12-19 12:17:39 +00:00
|
|
|
const INetURLObject& rURLObj = pShell->GetMedium()->GetURLObject();
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult += String( rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) );
|
|
|
|
aFuncResult.AppendAscii( "'#$" );
|
2001-03-08 10:57:21 +00:00
|
|
|
String aTabName;
|
|
|
|
pDok->GetName( nTab, aTabName );
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult += aTabName;
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-02-27 11:16:06 +00:00
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "COORD" ) )
|
|
|
|
{ // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
// Yes, passing tab as col is intentional!
|
2007-02-27 11:16:06 +00:00
|
|
|
ScAddress( static_cast<SCCOL>(aCellPos.Tab()), 0, 0 ).Format( aFuncResult, (SCA_COL_ABSOLUTE|SCA_VALID_COL) );
|
|
|
|
aFuncResult += ':';
|
2001-03-08 10:57:21 +00:00
|
|
|
String aCellStr;
|
|
|
|
aCellPos.Format( aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL|SCA_ROW_ABSOLUTE|SCA_VALID_ROW) );
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult += aCellStr;
|
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// *** CELL PROPERTIES ***
|
|
|
|
else if( aInfoType.EqualsAscii( "CONTENTS" ) )
|
|
|
|
{ // contents of the cell, no formatting
|
|
|
|
if( pCell && pCell->HasStringData() )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
GetCellString( aFuncResult, pCell );
|
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
PushDouble( GetCellValue( aCellPos, pCell ) );
|
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "TYPE" ) )
|
|
|
|
{ // b = blank; l = string (label); v = otherwise (value)
|
|
|
|
if( HasCellStringData( pCell ) )
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult = 'l';
|
2001-03-08 10:57:21 +00:00
|
|
|
else
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult = HasCellValueData( pCell ) ? 'v' : 'b';
|
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "WIDTH" ) )
|
|
|
|
{ // column width (rounded off as count of zero characters in standard font and size)
|
|
|
|
Printer* pPrinter = pDok->GetPrinter();
|
|
|
|
MapMode aOldMode( pPrinter->GetMapMode() );
|
|
|
|
Font aOldFont( pPrinter->GetFont() );
|
|
|
|
Font aDefFont;
|
|
|
|
|
|
|
|
pPrinter->SetMapMode( MAP_TWIP );
|
2002-03-11 13:08:12 +00:00
|
|
|
// font color doesn't matter here
|
|
|
|
pDok->GetDefPattern()->GetFont( aDefFont, SC_AUTOCOL_BLACK, pPrinter );
|
2001-03-08 10:57:21 +00:00
|
|
|
pPrinter->SetFont( aDefFont );
|
|
|
|
long nZeroWidth = pPrinter->GetTextWidth( String( '0' ) );
|
|
|
|
pPrinter->SetFont( aOldFont );
|
|
|
|
pPrinter->SetMapMode( aOldMode );
|
|
|
|
int nZeroCount = (int)(pDok->GetColWidth( aCellPos.Col(), aCellPos.Tab() ) / nZeroWidth);
|
|
|
|
PushInt( nZeroCount );
|
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "PREFIX" ) )
|
|
|
|
{ // ' = left; " = right; ^ = centered
|
|
|
|
if( HasCellStringData( pCell ) )
|
|
|
|
{
|
|
|
|
const SvxHorJustifyItem* pJustAttr = (const SvxHorJustifyItem*)
|
|
|
|
pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY );
|
|
|
|
switch( pJustAttr->GetValue() )
|
|
|
|
{
|
|
|
|
case SVX_HOR_JUSTIFY_STANDARD:
|
|
|
|
case SVX_HOR_JUSTIFY_LEFT:
|
2007-02-27 11:16:06 +00:00
|
|
|
case SVX_HOR_JUSTIFY_BLOCK: aFuncResult = '\''; break;
|
|
|
|
case SVX_HOR_JUSTIFY_CENTER: aFuncResult = '^'; break;
|
|
|
|
case SVX_HOR_JUSTIFY_RIGHT: aFuncResult = '"'; break;
|
|
|
|
case SVX_HOR_JUSTIFY_REPEAT: aFuncResult = '\\'; break;
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
}
|
2007-02-27 11:16:06 +00:00
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "PROTECT" ) )
|
|
|
|
{ // 1 = cell locked
|
|
|
|
const ScProtectionAttr* pProtAttr = (const ScProtectionAttr*)
|
|
|
|
pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION );
|
|
|
|
PushInt( pProtAttr->GetProtection() ? 1 : 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
// *** FORMATTING ***
|
|
|
|
else if( aInfoType.EqualsAscii( "FORMAT" ) )
|
|
|
|
{ // specific format code for standard formats
|
|
|
|
ULONG nFormat = pDok->GetNumberFormat( aCellPos );
|
|
|
|
BOOL bAppendPrec = TRUE;
|
|
|
|
USHORT nPrec, nLeading;
|
|
|
|
BOOL bThousand, bIsRed;
|
|
|
|
pFormatter->GetFormatSpecialInfo( nFormat, bThousand, bIsRed, nPrec, nLeading );
|
|
|
|
|
|
|
|
switch( pFormatter->GetType( nFormat ) )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
case NUMBERFORMAT_NUMBER: aFuncResult = (bThousand ? ',' : 'F'); break;
|
|
|
|
case NUMBERFORMAT_CURRENCY: aFuncResult = 'C'; break;
|
|
|
|
case NUMBERFORMAT_SCIENTIFIC: aFuncResult = 'S'; break;
|
|
|
|
case NUMBERFORMAT_PERCENT: aFuncResult = 'P'; break;
|
2001-03-08 10:57:21 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
bAppendPrec = FALSE;
|
|
|
|
switch( pFormatter->GetIndexTableOffset( nFormat ) )
|
|
|
|
{
|
|
|
|
case NF_DATE_SYSTEM_SHORT:
|
|
|
|
case NF_DATE_SYS_DMMMYY:
|
|
|
|
case NF_DATE_SYS_DDMMYY:
|
|
|
|
case NF_DATE_SYS_DDMMYYYY:
|
|
|
|
case NF_DATE_SYS_DMMMYYYY:
|
|
|
|
case NF_DATE_DIN_DMMMYYYY:
|
|
|
|
case NF_DATE_SYS_DMMMMYYYY:
|
2007-02-27 11:16:06 +00:00
|
|
|
case NF_DATE_DIN_DMMMMYYYY: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D1" ) ); break;
|
|
|
|
case NF_DATE_SYS_DDMMM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D2" ) ); break;
|
|
|
|
case NF_DATE_SYS_MMYY: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D3" ) ); break;
|
2001-03-08 10:57:21 +00:00
|
|
|
case NF_DATETIME_SYSTEM_SHORT_HHMM:
|
|
|
|
case NF_DATETIME_SYS_DDMMYYYY_HHMMSS:
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D4" ) ); break;
|
|
|
|
case NF_DATE_DIN_MMDD: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D5" ) ); break;
|
|
|
|
case NF_TIME_HHMMSSAMPM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D6" ) ); break;
|
|
|
|
case NF_TIME_HHMMAMPM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D7" ) ); break;
|
|
|
|
case NF_TIME_HHMMSS: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D8" ) ); break;
|
|
|
|
case NF_TIME_HHMM: aFuncResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D9" ) ); break;
|
|
|
|
default: aFuncResult = 'G';
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( bAppendPrec )
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult += String::CreateFromInt32( nPrec );
|
2001-03-08 10:57:21 +00:00
|
|
|
const SvNumberformat* pFormat = pFormatter->GetEntry( nFormat );
|
|
|
|
if( lcl_FormatHasNegColor( pFormat ) )
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult += '-';
|
2001-03-08 10:57:21 +00:00
|
|
|
if( lcl_FormatHasOpenPar( pFormat ) )
|
2007-02-27 11:16:06 +00:00
|
|
|
aFuncResult.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "()" ) );
|
|
|
|
PushString( aFuncResult );
|
2001-03-08 10:57:21 +00:00
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "COLOR" ) )
|
|
|
|
{ // 1 = negative values are colored, otherwise 0
|
|
|
|
const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) );
|
|
|
|
PushInt( lcl_FormatHasNegColor( pFormat ) ? 1 : 0 );
|
|
|
|
}
|
|
|
|
else if( aInfoType.EqualsAscii( "PARENTHESES" ) )
|
|
|
|
{ // 1 = format string contains a '(' character, otherwise 0
|
|
|
|
const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) );
|
|
|
|
PushInt( lcl_FormatHasOpenPar( pFormat ) ? 1 : 0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalArgument();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
void ScInterpreter::ScIsRef()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
if ( !nGlobalError )
|
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
|
|
|
ScRange aRange;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
if ( !nGlobalError )
|
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsValue()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (GetCellErrCode( pCell ) == 0)
|
|
|
|
{
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_VALUE :
|
|
|
|
nRes = 1;
|
|
|
|
break;
|
|
|
|
case CELLTYPE_FORMULA :
|
|
|
|
nRes = ((ScFormulaCell*)pCell)->IsValue();
|
|
|
|
break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default:
|
|
|
|
; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
Pop();
|
2004-03-08 10:47:52 +00:00
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
; // nothing
|
|
|
|
else if ( !pJumpMatrix )
|
2007-05-10 12:13:55 +00:00
|
|
|
{
|
|
|
|
if (pMat->GetErrorIfNotString( 0 ) == 0)
|
|
|
|
nRes = pMat->IsValue( 0 );
|
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
2007-05-10 12:13:55 +00:00
|
|
|
if (pMat->GetErrorIfNotString( nC, nR) == 0)
|
|
|
|
nRes = pMat->IsValue( nC, nR);
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
if ( !nGlobalError )
|
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsFormula()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
nRes = (GetCellType( GetCell( aAdr ) ) == CELLTYPE_FORMULA);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScFormula()
|
|
|
|
{
|
|
|
|
String aFormula;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_FORMULA :
|
|
|
|
((ScFormulaCell*)pCell)->GetFormula( aFormula );
|
|
|
|
break;
|
|
|
|
default:
|
2007-07-06 11:35:07 +00:00
|
|
|
SetError( NOTAVAILABLE );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Pop();
|
2007-07-06 11:35:07 +00:00
|
|
|
SetError( NOTAVAILABLE );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aFormula );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsNV()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopDoubleRefOrSingleRef( aAdr );
|
2007-07-06 11:35:07 +00:00
|
|
|
if ( nGlobalError == NOTAVAILABLE )
|
2000-09-18 23:16:46 +00:00
|
|
|
nRes = 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
USHORT nErr = GetCellErrCode( pCell );
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = (nErr == NOTAVAILABLE);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-03-08 10:47:52 +00:00
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
; // nothing
|
|
|
|
else if ( !pJumpMatrix )
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = (pMat->GetErrorIfNotString( 0 ) == NOTAVAILABLE);
|
2004-03-08 10:47:52 +00:00
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = (pMat->GetErrorIfNotString( nC, nR) == NOTAVAILABLE);
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
PopError();
|
2007-07-06 11:35:07 +00:00
|
|
|
if ( nGlobalError == NOTAVAILABLE )
|
2000-09-18 23:16:46 +00:00
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsErr()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopDoubleRefOrSingleRef( aAdr );
|
2007-07-06 11:35:07 +00:00
|
|
|
if ( nGlobalError && nGlobalError != NOTAVAILABLE )
|
2000-09-18 23:16:46 +00:00
|
|
|
nRes = 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
USHORT nErr = GetCellErrCode( pCell );
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = (nErr && nErr != NOTAVAILABLE);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-03-08 10:47:52 +00:00
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( nGlobalError || !pMat )
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = ((nGlobalError && nGlobalError != NOTAVAILABLE) || !pMat);
|
2004-03-08 10:47:52 +00:00
|
|
|
else if ( !pJumpMatrix )
|
|
|
|
{
|
2007-05-10 12:13:55 +00:00
|
|
|
USHORT nErr = pMat->GetErrorIfNotString( 0 );
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = (nErr && nErr != NOTAVAILABLE);
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
|
|
|
{
|
2007-05-10 12:13:55 +00:00
|
|
|
USHORT nErr = pMat->GetErrorIfNotString( nC, nR);
|
2007-07-06 11:35:07 +00:00
|
|
|
nRes = (nErr && nErr != NOTAVAILABLE);
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
PopError();
|
2007-07-06 11:35:07 +00:00
|
|
|
if ( nGlobalError && nGlobalError != NOTAVAILABLE )
|
2000-09-18 23:16:46 +00:00
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsError()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
nRes = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( nGlobalError )
|
|
|
|
nRes = 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
nRes = (GetCellErrCode( pCell ) != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-03-08 10:47:52 +00:00
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( nGlobalError || !pMat )
|
|
|
|
nRes = 1;
|
|
|
|
else if ( !pJumpMatrix )
|
2007-05-10 12:13:55 +00:00
|
|
|
nRes = (pMat->GetErrorIfNotString( 0 ) != 0);
|
2004-03-08 10:47:52 +00:00
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
2007-05-10 12:13:55 +00:00
|
|
|
nRes = (pMat->GetErrorIfNotString( nC, nR) != 0);
|
2004-03-08 10:47:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
if ( nGlobalError )
|
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushInt( nRes );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
short ScInterpreter::IsEven()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
short nRes = 0;
|
2007-02-27 11:16:06 +00:00
|
|
|
double fVal = 0.0;
|
2000-09-18 23:16:46 +00:00
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
break;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
USHORT nErr = GetCellErrCode( pCell );
|
|
|
|
if (nErr != 0)
|
|
|
|
SetError(nErr);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_VALUE :
|
|
|
|
fVal = GetCellValue( aAdr, pCell );
|
|
|
|
nRes = 1;
|
2004-03-08 10:47:52 +00:00
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
case CELLTYPE_FORMULA :
|
|
|
|
if( ((ScFormulaCell*)pCell)->IsValue() )
|
|
|
|
{
|
|
|
|
fVal = GetCellValue( aAdr, pCell );
|
|
|
|
nRes = 1;
|
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default:
|
|
|
|
; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDouble:
|
|
|
|
{
|
|
|
|
fVal = PopDouble();
|
|
|
|
nRes = 1;
|
|
|
|
}
|
|
|
|
break;
|
2004-03-08 10:47:52 +00:00
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatrixRef pMat = PopMatrix();
|
|
|
|
if ( !pMat )
|
|
|
|
; // nothing
|
|
|
|
else if ( !pJumpMatrix )
|
|
|
|
{
|
|
|
|
nRes = pMat->IsValue( 0 );
|
|
|
|
if ( nRes )
|
|
|
|
fVal = pMat->GetDouble( 0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCols, nRows, nC, nR;
|
2004-03-08 10:47:52 +00:00
|
|
|
pMat->GetDimensions( nCols, nRows);
|
|
|
|
pJumpMatrix->GetPos( nC, nR);
|
|
|
|
if ( nC < nCols && nR < nRows )
|
|
|
|
{
|
|
|
|
nRes = pMat->IsValue( nC, nR);
|
|
|
|
if ( nRes )
|
|
|
|
fVal = pMat->GetDouble( nC, nR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetError( errNoValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default:
|
|
|
|
; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2004-03-08 10:47:52 +00:00
|
|
|
if ( !nRes )
|
|
|
|
SetError( errIllegalParameter);
|
|
|
|
else
|
2003-03-26 17:07:02 +00:00
|
|
|
nRes = ( fmod( ::rtl::math::approxFloor( fabs( fVal ) ), 2.0 ) < 0.5 );
|
2000-09-18 23:16:46 +00:00
|
|
|
return nRes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsEven()
|
|
|
|
{
|
|
|
|
PushInt( IsEven() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIsOdd()
|
|
|
|
{
|
|
|
|
PushInt( !IsEven() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScN()
|
|
|
|
{
|
|
|
|
USHORT nErr = nGlobalError;
|
|
|
|
nGlobalError = 0;
|
|
|
|
double fVal = GetDouble();
|
2007-07-06 11:35:07 +00:00
|
|
|
if ( nGlobalError == NOTAVAILABLE || nGlobalError == errIllegalArgument )
|
|
|
|
nGlobalError = 0; // N(#NA) and N("text") are ok
|
|
|
|
if ( !nGlobalError && nErr != NOTAVAILABLE )
|
2000-09-18 23:16:46 +00:00
|
|
|
nGlobalError = nErr;
|
|
|
|
PushDouble( fVal );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScTrim()
|
|
|
|
{ // trimmt nicht nur sondern schnibbelt auch doppelte raus!
|
|
|
|
String aVal( GetString() );
|
|
|
|
aVal.EraseLeadingChars();
|
|
|
|
aVal.EraseTrailingChars();
|
|
|
|
String aStr;
|
|
|
|
register const sal_Unicode* p = aVal.GetBuffer();
|
|
|
|
register const sal_Unicode* const pEnd = p + aVal.Len();
|
|
|
|
while ( p < pEnd )
|
|
|
|
{
|
|
|
|
if ( *p != ' ' || p[-1] != ' ' ) // erster kann kein ' ' sein, -1 ist also ok
|
|
|
|
aStr += *p;
|
|
|
|
p++;
|
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScUpper()
|
|
|
|
{
|
|
|
|
String aString = GetString();
|
|
|
|
ScGlobal::pCharClass->toUpper(aString);
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aString);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScPropper()
|
|
|
|
{
|
|
|
|
//2do: what to do with I18N-CJK ?!?
|
|
|
|
String aStr( GetString() );
|
|
|
|
const xub_StrLen nLen = aStr.Len();
|
2007-11-01 15:23:17 +00:00
|
|
|
// #i82487# don't try to write to empty string's BufferAccess
|
|
|
|
// (would crash now that the empty string is const)
|
|
|
|
if ( nLen > 0 )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-11-01 15:23:17 +00:00
|
|
|
String aUpr( ScGlobal::pCharClass->upper( aStr ) );
|
|
|
|
String aLwr( ScGlobal::pCharClass->lower( aStr ) );
|
|
|
|
register sal_Unicode* pStr = aStr.GetBufferAccess();
|
|
|
|
const sal_Unicode* pUpr = aUpr.GetBuffer();
|
|
|
|
const sal_Unicode* pLwr = aLwr.GetBuffer();
|
|
|
|
*pStr = *pUpr;
|
|
|
|
String aTmpStr( 'x' );
|
|
|
|
xub_StrLen nPos = 1;
|
|
|
|
while( nPos < nLen )
|
|
|
|
{
|
|
|
|
aTmpStr.SetChar( 0, pStr[nPos-1] );
|
|
|
|
if ( !ScGlobal::pCharClass->isLetter( aTmpStr, 0 ) )
|
|
|
|
pStr[nPos] = pUpr[nPos];
|
|
|
|
else
|
|
|
|
pStr[nPos] = pLwr[nPos];
|
|
|
|
nPos++;
|
|
|
|
}
|
|
|
|
aStr.ReleaseBufferAccess( nLen );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScLower()
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
String aString( GetString() );
|
2000-09-18 23:16:46 +00:00
|
|
|
ScGlobal::pCharClass->toLower(aString);
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aString);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScLen()
|
|
|
|
{
|
|
|
|
String aStr( GetString() );
|
|
|
|
PushDouble( aStr.Len() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScT()
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
BOOL bValue = FALSE;
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( GetCellErrCode( pCell ) == 0 )
|
|
|
|
{
|
|
|
|
switch ( GetCellType( pCell ) )
|
|
|
|
{
|
|
|
|
case CELLTYPE_VALUE :
|
|
|
|
bValue = TRUE;
|
|
|
|
break;
|
|
|
|
case CELLTYPE_FORMULA :
|
|
|
|
bValue = ((ScFormulaCell*)pCell)->IsValue();
|
|
|
|
break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default:
|
|
|
|
; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( bValue )
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( EMPTY_STRING );
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// wie GetString()
|
|
|
|
GetCellString( aTempStr, pCell );
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aTempStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDouble :
|
|
|
|
{
|
|
|
|
PopError();
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( EMPTY_STRING );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
SetError(errUnknownOpCode);
|
|
|
|
PushInt(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScValue()
|
|
|
|
{
|
2006-05-05 08:34:33 +00:00
|
|
|
String aInputString;
|
2000-09-18 23:16:46 +00:00
|
|
|
double fVal;
|
2006-05-05 08:34:33 +00:00
|
|
|
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
PushDouble( PopDouble() );
|
|
|
|
return;
|
2007-02-27 11:16:06 +00:00
|
|
|
//break;
|
2006-05-05 08:34:33 +00:00
|
|
|
|
|
|
|
case svSingleRef:
|
|
|
|
case svDoubleRef:
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( pCell && pCell->HasStringData() )
|
|
|
|
GetCellString( aInputString, pCell );
|
|
|
|
else if ( pCell && pCell->HasValueData() )
|
|
|
|
{
|
|
|
|
PushDouble( GetCellValue(aAdr, pCell) );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PushDouble(0.0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
|
|
|
|
aInputString);
|
|
|
|
switch (nType)
|
|
|
|
{
|
|
|
|
case SC_MATVAL_EMPTY:
|
|
|
|
fVal = 0.0;
|
|
|
|
// fallthru
|
|
|
|
case SC_MATVAL_VALUE:
|
2007-06-13 08:07:39 +00:00
|
|
|
case SC_MATVAL_BOOLEAN:
|
2006-05-05 08:34:33 +00:00
|
|
|
PushDouble( fVal);
|
|
|
|
return;
|
2007-02-27 11:16:06 +00:00
|
|
|
//break;
|
2006-05-05 08:34:33 +00:00
|
|
|
case SC_MATVAL_STRING:
|
|
|
|
// evaluated below
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetIllegalArgument();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
aInputString = GetString();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_uInt32 nFIndex = 0; // 0 for default locale
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
|
|
|
|
PushDouble(fVal);
|
|
|
|
else
|
|
|
|
SetIllegalArgument();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//2do: this should be a proper unicode string method
|
|
|
|
inline BOOL lcl_ScInterpreter_IsPrintable( sal_Unicode c )
|
|
|
|
{
|
|
|
|
return 0x20 <= c && c != 0x7f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScInterpreter::ScClean()
|
|
|
|
{
|
|
|
|
String aStr( GetString() );
|
|
|
|
for ( xub_StrLen i = 0; i < aStr.Len(); i++ )
|
|
|
|
{
|
|
|
|
if ( !lcl_ScInterpreter_IsPrintable( aStr.GetChar( i ) ) )
|
|
|
|
aStr.Erase(i,1);
|
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCode()
|
|
|
|
{
|
|
|
|
//2do: make it full range unicode?
|
2001-02-21 17:39:37 +00:00
|
|
|
const String& rStr = GetString();
|
|
|
|
PushInt( (sal_uChar) ByteString::ConvertFromUnicode( rStr.GetChar(0), gsl_getSystemTextEncoding() ) );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScChar()
|
|
|
|
{
|
|
|
|
//2do: make it full range unicode?
|
|
|
|
double fVal = GetDouble();
|
|
|
|
if (fVal < 0.0 || fVal >= 256.0)
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
String aStr( '0' );
|
|
|
|
aStr.SetChar( 0, ByteString::ConvertToUnicode( (sal_Char) fVal, gsl_getSystemTextEncoding() ) );
|
|
|
|
PushString( aStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-03 14:49:30 +00:00
|
|
|
/* #i70213# fullwidth/halfwidth conversion provided by
|
|
|
|
* Takashi Nakamoto <bluedwarf@ooo>
|
|
|
|
* erAck: added Excel compatibility conversions as seen in issue's test case. */
|
|
|
|
|
|
|
|
static ::rtl::OUString lcl_convertIntoHalfWidth( const ::rtl::OUString & rStr )
|
|
|
|
{
|
|
|
|
const sal_Unicode *pSrc = rStr.getStr();
|
|
|
|
sal_Int32 nLen = rStr.getLength();
|
|
|
|
::rtl::OUStringBuffer aRes( nLen );
|
|
|
|
|
|
|
|
for (sal_Int32 i=0; i<nLen; i++)
|
|
|
|
{
|
|
|
|
if( pSrc[i] >= 0x30a1 && pSrc[i] <= 0x30aa && (pSrc[i] % 2) == 0 )
|
|
|
|
// katakana a-o
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30a2) / 2 + 0xff71));
|
|
|
|
else if( pSrc[i] >= 0x30a1 && pSrc[i] <= 0x30aa && (pSrc[i] % 2) == 1 )
|
|
|
|
// katakana small a-o
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30a1) / 2 + 0xff67));
|
|
|
|
else if( pSrc[i] >= 0x30ab && pSrc[i] <= 0x30c2 && (pSrc[i] % 2) == 1 )
|
|
|
|
// katakana ka-chi
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30ab) / 2 + 0xff76));
|
|
|
|
else if( pSrc[i] >= 0x30ab && pSrc[i] <= 0x30c2 && (pSrc[i] % 2) == 0 )
|
|
|
|
{
|
|
|
|
// katakana ga-dhi
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30ac) / 2 + 0xff76));
|
|
|
|
aRes.append((sal_Unicode)0xff9e );
|
|
|
|
}
|
|
|
|
else if( pSrc[i] == 0x30c3 )
|
|
|
|
// katakana small tsu
|
|
|
|
aRes.append((sal_Unicode)0xff6f );
|
|
|
|
else if( pSrc[i] >= 0x30c4 && pSrc[i] <= 0x30c9 && (pSrc[i] % 2) == 0 )
|
|
|
|
// katakana tsu-to
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30c4) / 2 + 0xff82));
|
|
|
|
else if( pSrc[i] >= 0x30c4 && pSrc[i] <= 0x30c9 && (pSrc[i] % 2) == 1 )
|
|
|
|
{
|
|
|
|
// katakana du-do
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30c5) / 2 + 0xff82));
|
|
|
|
aRes.append((sal_Unicode)0xff9e );
|
|
|
|
}
|
|
|
|
else if( pSrc[i] >= 0x30ca && pSrc[i] <= 0x30ce )
|
|
|
|
// katakana na-no
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0x30ca + 0xff85));
|
|
|
|
else if( pSrc[i] >= 0x30cf && pSrc[i] <= 0x30dd && (pSrc[i] % 3) == 0 )
|
|
|
|
// katakana ha-ho
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30cf) / 3 + 0xff8a));
|
|
|
|
else if( pSrc[i] >= 0x30cf && pSrc[i] <= 0x30dd && (pSrc[i] % 3) == 1 )
|
|
|
|
{
|
|
|
|
// katakana ba-bo
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30d0) / 3 + 0xff8a));
|
|
|
|
aRes.append((sal_Unicode)0xff9e );
|
|
|
|
}
|
|
|
|
else if( pSrc[i] >= 0x30cf && pSrc[i] <= 0x30dd && (pSrc[i] % 3) == 2 )
|
|
|
|
{
|
|
|
|
// katakana pa-po
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30d1) / 3 + 0xff8a));
|
|
|
|
aRes.append((sal_Unicode)0xff9f );
|
|
|
|
}
|
|
|
|
else if( pSrc[i] >= 0x30de && pSrc[i] <= 0x30e2 )
|
|
|
|
// katakana ma-mo
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0x30de + 0xff8f));
|
|
|
|
else if( pSrc[i] >= 0x30e3 && pSrc[i] <= 0x30e8 && (pSrc[i] % 2) == 0)
|
|
|
|
// katakana ya-yo
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30e4) / 2 + 0xff94));
|
|
|
|
else if( pSrc[i] >= 0x30e3 && pSrc[i] <= 0x30e8 && (pSrc[i] % 2) == 1)
|
|
|
|
// katakana small ya-yo
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0x30e3) / 2 + 0xff6c));
|
|
|
|
else if( pSrc[i] >= 0x30e9 && pSrc[i] <= 0x30ed )
|
|
|
|
// katakana ra-ro
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0x30e9 + 0xff97));
|
|
|
|
else if( pSrc[i] == 0x30ef )
|
|
|
|
// katakana wa
|
|
|
|
aRes.append((sal_Unicode)0xff9c);
|
|
|
|
else if( pSrc[i] == 0x30f2 )
|
|
|
|
// katakana wo
|
|
|
|
aRes.append((sal_Unicode)0xff66);
|
|
|
|
else if( pSrc[i] == 0x30f3 )
|
|
|
|
// katakana nn
|
|
|
|
aRes.append((sal_Unicode)0xff9d);
|
|
|
|
else if( pSrc[i] >= 0xff01 && pSrc[i] <= 0xff5e )
|
|
|
|
// ASCII characters
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0xff01 + 0x0021));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (pSrc[i])
|
|
|
|
{
|
|
|
|
case 0x2015: // HORIZONTAL BAR => HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0xff70); break;
|
|
|
|
case 0x2018: // LEFT SINGLE QUOTATION MARK => GRAVE ACCENT
|
|
|
|
aRes.append((sal_Unicode)0x0060); break;
|
|
|
|
case 0x2019: // RIGHT SINGLE QUOTATION MARK => APOSTROPHE
|
|
|
|
aRes.append((sal_Unicode)0x0027); break;
|
|
|
|
case 0x201d: // RIGHT DOUBLE QUOTATION MARK => QUOTATION MARK
|
|
|
|
aRes.append((sal_Unicode)0x0022); break;
|
|
|
|
case 0x3001: // IDEOGRAPHIC COMMA
|
|
|
|
aRes.append((sal_Unicode)0xff64); break;
|
|
|
|
case 0x3002: // IDEOGRAPHIC FULL STOP
|
|
|
|
aRes.append((sal_Unicode)0xff61); break;
|
|
|
|
case 0x300c: // LEFT CORNER BRACKET
|
|
|
|
aRes.append((sal_Unicode)0xff62); break;
|
|
|
|
case 0x300d: // RIGHT CORNER BRACKET
|
|
|
|
aRes.append((sal_Unicode)0xff63); break;
|
|
|
|
case 0x309b: // KATAKANA-HIRAGANA VOICED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0xff9e); break;
|
|
|
|
case 0x309c: // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0xff9f); break;
|
2007-07-31 15:36:31 +00:00
|
|
|
case 0x30fb: // KATAKANA MIDDLE DOT
|
|
|
|
aRes.append((sal_Unicode)0xff65); break;
|
2007-07-03 14:49:30 +00:00
|
|
|
case 0x30fc: // KATAKANA-HIRAGANA PROLONGED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0xff70); break;
|
|
|
|
case 0xffe5: // FULLWIDTH YEN SIGN => REVERSE SOLIDUS "\"
|
|
|
|
aRes.append((sal_Unicode)0x005c); break;
|
|
|
|
default:
|
|
|
|
aRes.append( pSrc[i] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return aRes.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ::rtl::OUString lcl_convertIntoFullWidth( const ::rtl::OUString & rStr )
|
|
|
|
{
|
|
|
|
const sal_Unicode *pSrc = rStr.getStr();
|
|
|
|
sal_Int32 nLen = rStr.getLength();
|
|
|
|
::rtl::OUStringBuffer aRes( nLen );
|
|
|
|
|
|
|
|
for (sal_Int32 i=0; i<nLen; i++)
|
|
|
|
{
|
|
|
|
if( pSrc[i] == 0x0022 )
|
|
|
|
// QUOTATION MARK => RIGHT DOUBLE QUOTATION MARK
|
|
|
|
// This is an exception to the ASCII range that follows below.
|
|
|
|
aRes.append((sal_Unicode)0x201d);
|
|
|
|
else if( pSrc[i] == 0x005c )
|
|
|
|
// REVERSE SOLIDUS "\", a specialty that gets displayed as a
|
|
|
|
// Yen sign, which is a legacy of code-page 932, see
|
|
|
|
// http://www.microsoft.com/globaldev/DrIntl/columns/019/default.mspx#EED
|
|
|
|
// http://www.microsoft.com/globaldev/reference/dbcs/932.htm
|
|
|
|
// This is an exception to the ASCII range that follows below.
|
|
|
|
aRes.append((sal_Unicode)0xffe5);
|
|
|
|
else if( pSrc[i] == 0x0060 )
|
|
|
|
// GRAVE ACCENT => LEFT SINGLE QUOTATION MARK
|
|
|
|
// This is an exception to the ASCII range that follows below.
|
|
|
|
aRes.append((sal_Unicode)0x2018);
|
|
|
|
else if( pSrc[i] == 0x0027 )
|
|
|
|
// APOSTROPHE => RIGHT SINGLE QUOTATION MARK
|
|
|
|
// This is an exception to the ASCII range that follows below.
|
|
|
|
aRes.append((sal_Unicode)0x2019);
|
|
|
|
else if( pSrc[i] >= 0x0021 && pSrc[i] <= 0x007e )
|
|
|
|
// ASCII characters
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0x0021 + 0xff01));
|
|
|
|
else if( pSrc[i] == 0xff66 )
|
|
|
|
// katakana wo
|
|
|
|
aRes.append((sal_Unicode)0x30f2);
|
|
|
|
else if( pSrc[i] >= 0xff67 && pSrc[i] <= 0xff6b )
|
|
|
|
// katakana small a-o
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff67) * 2 + 0x30a1 ));
|
|
|
|
else if( pSrc[i] >= 0xff6c && pSrc[i] <= 0xff6e )
|
|
|
|
// katakana small ya-yo
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff6c) * 2 + 0x30e3 ));
|
|
|
|
else if( pSrc[i] == 0xff6f )
|
|
|
|
// katakana small tsu
|
|
|
|
aRes.append((sal_Unicode)0x30c3);
|
|
|
|
else if( pSrc[i] >= 0xff71 && pSrc[i] <= 0xff75 )
|
|
|
|
// katakana a-o
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff71) * 2 + 0x30a2));
|
|
|
|
else if( pSrc[i] >= 0xff76 && pSrc[i] <= 0xff81 )
|
|
|
|
{
|
|
|
|
if( (i+1)<nLen && pSrc[i+1] == 0xff9e )
|
|
|
|
{
|
|
|
|
// katakana ga-dsu
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff76) * 2 + 0x30ac));
|
|
|
|
i+=1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// katakana ka-chi
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff76) * 2 + 0x30ab));
|
|
|
|
}
|
|
|
|
else if( pSrc[i] >= 0xff82 && pSrc[i] <= 0xff84 )
|
|
|
|
{
|
|
|
|
if( (i+1)<nLen && pSrc[i+1] == 0xff9e )
|
|
|
|
{
|
|
|
|
// katakana du-do
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff82) * 2 + 0x30c5));
|
|
|
|
i+=1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// katakana tsu-to
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff82) * 2 + 0x30c4));
|
|
|
|
}
|
|
|
|
else if( pSrc[i] >= 0xff85 && pSrc[i] <= 0xff89 )
|
|
|
|
// katakana na-no
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0xff85 + 0x30ca));
|
|
|
|
else if( pSrc[i] >= 0xff8a && pSrc[i] <= 0xff8e )
|
|
|
|
{
|
|
|
|
if( (i+1)<nLen && pSrc[i+1] == 0xff9e )
|
|
|
|
{
|
|
|
|
// katakana ba-bo
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff8a) * 3 + 0x30d0));
|
|
|
|
i+=1;
|
|
|
|
}
|
|
|
|
else if( (i+1)<nLen && pSrc[i+1] == 0xff9f )
|
|
|
|
{
|
|
|
|
// katakana pa-po
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff8a) * 3 + 0x30d1));
|
|
|
|
i+=1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// katakana ha-ho
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff8a) * 3 + 0x30cf));
|
|
|
|
}
|
|
|
|
else if( pSrc[i] >= 0xff8f && pSrc[i] <= 0xff93 )
|
|
|
|
// katakana ma-mo
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0xff8f + 0x30de));
|
|
|
|
else if( pSrc[i] >= 0xff94 && pSrc[i] <= 0xff96 )
|
|
|
|
// katakana ya-yo
|
|
|
|
aRes.append((sal_Unicode)((pSrc[i] - 0xff94) * 2 + 0x30e4));
|
|
|
|
else if( pSrc[i] >= 0xff97 && pSrc[i] <= 0xff9b )
|
|
|
|
// katakana ra-ro
|
|
|
|
aRes.append((sal_Unicode)(pSrc[i] - 0xff97 + 0x30e9));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (pSrc[i])
|
|
|
|
{
|
|
|
|
case 0xff9c: // katakana wa
|
|
|
|
aRes.append((sal_Unicode)0x30ef); break;
|
|
|
|
case 0xff9d: // katakana nn
|
|
|
|
aRes.append((sal_Unicode)0x30f3); break;
|
|
|
|
case 0xff9e: // HALFWIDTH KATAKANA VOICED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0x309b); break;
|
|
|
|
case 0xff9f: // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0x309c); break;
|
|
|
|
case 0xff70: // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
|
|
|
|
aRes.append((sal_Unicode)0x30fc); break;
|
|
|
|
case 0xff61: // HALFWIDTH IDEOGRAPHIC FULL STOP
|
|
|
|
aRes.append((sal_Unicode)0x3002); break;
|
|
|
|
case 0xff62: // HALFWIDTH LEFT CORNER BRACKET
|
|
|
|
aRes.append((sal_Unicode)0x300c); break;
|
|
|
|
case 0xff63: // HALFWIDTH RIGHT CORNER BRACKET
|
|
|
|
aRes.append((sal_Unicode)0x300d); break;
|
|
|
|
case 0xff64: // HALFWIDTH IDEOGRAPHIC COMMA
|
|
|
|
aRes.append((sal_Unicode)0x3001); break;
|
2007-07-31 15:36:31 +00:00
|
|
|
case 0xff65: // HALFWIDTH KATAKANA MIDDLE DOT
|
|
|
|
aRes.append((sal_Unicode)0x30fb); break;
|
2007-07-03 14:49:30 +00:00
|
|
|
default:
|
|
|
|
aRes.append( pSrc[i] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return aRes.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ODFF:
|
|
|
|
* Summary: Converts half-width to full-width ASCII and katakana characters.
|
|
|
|
* Semantics: Conversion is done for half-width ASCII and katakana characters,
|
|
|
|
* other characters are simply copied from T to the result. This is the
|
|
|
|
* complementary function to ASC.
|
|
|
|
* For references regarding halfwidth and fullwidth characters see
|
|
|
|
* http://www.unicode.org/reports/tr11/
|
|
|
|
* http://www.unicode.org/charts/charindex2.html#H
|
|
|
|
* http://www.unicode.org/charts/charindex2.html#F
|
|
|
|
*/
|
|
|
|
void ScInterpreter::ScJis()
|
|
|
|
{
|
|
|
|
if (MustHaveParamCount( GetByte(), 1))
|
|
|
|
PushString( lcl_convertIntoFullWidth( GetString()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ODFF:
|
|
|
|
* Summary: Converts full-width to half-width ASCII and katakana characters.
|
|
|
|
* Semantics: Conversion is done for full-width ASCII and katakana characters,
|
|
|
|
* other characters are simply copied from T to the result. This is the
|
|
|
|
* complementary function to JIS.
|
|
|
|
*/
|
|
|
|
void ScInterpreter::ScAsc()
|
|
|
|
{
|
|
|
|
if (MustHaveParamCount( GetByte(), 1))
|
|
|
|
PushString( lcl_convertIntoHalfWidth( GetString()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
void ScInterpreter::ScMin( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
double nMin = SC_DOUBLE_MAXVALUE;
|
|
|
|
double nVal = 0.0;
|
|
|
|
ScAddress aAdr;
|
|
|
|
ScRange aRange;
|
|
|
|
for (short i = 0; i < nParamCount; i++)
|
|
|
|
{
|
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
case svDouble :
|
|
|
|
{
|
|
|
|
nVal = GetDouble();
|
|
|
|
if (nMin > nVal) nMin = nVal;
|
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
nVal = GetCellValue( aAdr, pCell );
|
|
|
|
CurFmtToFuncFmt();
|
|
|
|
if (nMin > nVal) nMin = nVal;
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero && HasCellStringData( pCell ) )
|
|
|
|
{
|
|
|
|
if ( nMin > 0.0 )
|
|
|
|
nMin = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
|
|
|
USHORT nErr = 0;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
|
|
|
|
if (aValIter.GetFirst(nVal, nErr))
|
|
|
|
{
|
|
|
|
if (nMin > nVal)
|
|
|
|
nMin = nVal;
|
|
|
|
aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
|
|
|
|
while ((nErr == 0) && aValIter.GetNext(nVal, nErr))
|
|
|
|
{
|
|
|
|
if (nMin > nVal)
|
|
|
|
nMin = nVal;
|
|
|
|
}
|
|
|
|
SetError(nErr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix :
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = PopMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
if (pMat->IsNumeric())
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
|
|
|
|
for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
nVal = pMat->GetDouble(nMatCol,nMatRow);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nMin > nVal) nMin = nVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
if (!pMat->IsString(nMatCol,nMatRow))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
nVal = pMat->GetDouble(nMatCol,nMatRow);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nMin > nVal) nMin = nVal;
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero )
|
|
|
|
{
|
|
|
|
if ( nMin > 0.0 )
|
|
|
|
nMin = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
{
|
|
|
|
Pop();
|
|
|
|
if ( bTextAsZero )
|
|
|
|
{
|
|
|
|
if ( nMin > 0.0 )
|
|
|
|
nMin = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
Pop();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nMin == SC_DOUBLE_MAXVALUE)
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
PushDouble(nMin);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(WIN) && defined(MSC)
|
|
|
|
#pragma optimize("",off)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void ScInterpreter::ScMax( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
double nMax = -SC_DOUBLE_MAXVALUE;
|
|
|
|
double nVal = 0.0;
|
|
|
|
ScAddress aAdr;
|
|
|
|
ScRange aRange;
|
|
|
|
for (short i = 0; i < nParamCount; i++)
|
|
|
|
{
|
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
case svDouble :
|
|
|
|
{
|
|
|
|
nVal = GetDouble();
|
|
|
|
if (nMax < nVal) nMax = nVal;
|
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
nVal = GetCellValue( aAdr, pCell );
|
|
|
|
CurFmtToFuncFmt();
|
|
|
|
if (nMax < nVal) nMax = nVal;
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero && HasCellStringData( pCell ) )
|
|
|
|
{
|
|
|
|
if ( nMax < 0.0 )
|
|
|
|
nMax = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
|
|
|
USHORT nErr = 0;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
|
|
|
|
if (aValIter.GetFirst(nVal, nErr))
|
|
|
|
{
|
|
|
|
if (nMax < nVal)
|
|
|
|
nMax = nVal;
|
|
|
|
aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
|
|
|
|
while ((nErr == 0) && aValIter.GetNext(nVal, nErr))
|
|
|
|
{
|
|
|
|
if (nMax < nVal)
|
|
|
|
nMax = nVal;
|
|
|
|
}
|
|
|
|
SetError(nErr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix :
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = PopMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
if (pMat->IsNumeric())
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
|
|
|
|
for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
nVal = pMat->GetDouble(nMatCol,nMatRow);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nMax < nVal) nMax = nVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
if (!pMat->IsString(nMatCol,nMatRow))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
nVal = pMat->GetDouble(nMatCol,nMatRow);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nMax < nVal) nMax = nVal;
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero )
|
|
|
|
{
|
|
|
|
if ( nMax < 0.0 )
|
|
|
|
nMax = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
{
|
|
|
|
Pop();
|
|
|
|
if ( bTextAsZero )
|
|
|
|
{
|
|
|
|
if ( nMax < 0.0 )
|
|
|
|
nMax = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
Pop();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nMax == -SC_DOUBLE_MAXVALUE)
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
PushDouble(nMax);
|
|
|
|
}
|
|
|
|
#if defined(WIN) && defined(MSC)
|
|
|
|
#pragma optimize("",on)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
double fRes = ( eFunc == ifPRODUCT ) ? 1.0 : 0.0;
|
|
|
|
double fVal = 0.0;
|
|
|
|
double fMem = 0.0;
|
|
|
|
BOOL bNull = TRUE;
|
2001-02-28 13:31:18 +00:00
|
|
|
ULONG nCount = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
ScAddress aAdr;
|
|
|
|
ScRange aRange;
|
|
|
|
for (short i = 0; i < nParamCount; i++)
|
|
|
|
{
|
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
|
|
|
|
case svString:
|
|
|
|
{
|
|
|
|
if( eFunc == ifCOUNT )
|
|
|
|
{
|
|
|
|
String aStr( PopString() );
|
2005-12-14 14:06:41 +00:00
|
|
|
sal_uInt32 nFIndex = 0; // damit default Land/Spr.
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( bTextAsZero || pFormatter->IsNumberFormat(aStr, nFIndex, fVal))
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch ( eFunc )
|
|
|
|
{
|
|
|
|
case ifAVERAGE:
|
|
|
|
case ifSUM:
|
|
|
|
case ifSUMSQ:
|
|
|
|
case ifPRODUCT:
|
|
|
|
{
|
|
|
|
if ( bTextAsZero )
|
|
|
|
{
|
|
|
|
Pop();
|
|
|
|
nCount++;
|
|
|
|
if ( eFunc == ifPRODUCT )
|
|
|
|
fRes = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( ; i < nParamCount; i++ )
|
|
|
|
Pop();
|
|
|
|
SetError( errNoValue );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Pop();
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDouble :
|
|
|
|
fVal = GetDouble();
|
|
|
|
nCount++;
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifAVERAGE:
|
|
|
|
case ifSUM:
|
|
|
|
if ( bNull && fVal != 0.0 )
|
|
|
|
{
|
|
|
|
bNull = FALSE;
|
|
|
|
fMem = fVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fRes += fVal;
|
|
|
|
break;
|
|
|
|
case ifSUMSQ: fRes += fVal * fVal; break;
|
|
|
|
case ifPRODUCT: fRes *= fVal; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( pCell )
|
|
|
|
{
|
|
|
|
if( eFunc == ifCOUNT2 )
|
|
|
|
{
|
|
|
|
CellType eCellType = pCell->GetCellType();
|
|
|
|
if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
else if ( pCell->HasValueData() )
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
fVal = GetCellValue( aAdr, pCell );
|
|
|
|
CurFmtToFuncFmt();
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifAVERAGE:
|
|
|
|
case ifSUM:
|
|
|
|
if ( bNull && fVal != 0.0 )
|
|
|
|
{
|
|
|
|
bNull = FALSE;
|
|
|
|
fMem = fVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fRes += fVal;
|
|
|
|
break;
|
|
|
|
case ifSUMSQ: fRes += fVal * fVal; break;
|
|
|
|
case ifPRODUCT: fRes *= fVal; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero && pCell->HasStringData() )
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
if ( eFunc == ifPRODUCT )
|
|
|
|
fRes = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
|
|
|
USHORT nErr = 0;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
if( eFunc == ifCOUNT2 )
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell;
|
|
|
|
ScCellIterator aIter( pDok, aRange, glSubTotal );
|
2007-02-27 11:16:06 +00:00
|
|
|
if ( (pCell = aIter.GetFirst()) != NULL )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
CellType eType = pCell->GetCellType();
|
|
|
|
if( eType != CELLTYPE_NONE && eType != CELLTYPE_NOTE )
|
|
|
|
nCount++;
|
|
|
|
}
|
2007-02-27 11:16:06 +00:00
|
|
|
while ( (pCell = aIter.GetNext()) != NULL );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
|
|
|
|
if (aValIter.GetFirst(fVal, nErr))
|
|
|
|
{
|
|
|
|
// Schleife aus Performance-Gruenden nach innen verlegt:
|
|
|
|
aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifAVERAGE:
|
|
|
|
case ifSUM:
|
|
|
|
do
|
|
|
|
{
|
|
|
|
SetError(nErr);
|
|
|
|
if ( bNull && fVal != 0.0 )
|
|
|
|
{
|
|
|
|
bNull = FALSE;
|
|
|
|
fMem = fVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fRes += fVal;
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
while (aValIter.GetNext(fVal, nErr));
|
|
|
|
break;
|
|
|
|
case ifSUMSQ:
|
|
|
|
do
|
|
|
|
{
|
|
|
|
SetError(nErr);
|
|
|
|
fRes += fVal * fVal;
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
while (aValIter.GetNext(fVal, nErr));
|
|
|
|
break;
|
|
|
|
case ifPRODUCT:
|
|
|
|
do
|
|
|
|
{
|
|
|
|
SetError(nErr);
|
|
|
|
fRes *= fVal;
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
while (aValIter.GetNext(fVal, nErr));
|
|
|
|
break;
|
|
|
|
default: // count
|
|
|
|
do
|
|
|
|
{
|
|
|
|
SetError(nErr);
|
|
|
|
nCount++;
|
|
|
|
}
|
|
|
|
while (aValIter.GetNext(fVal, nErr));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SetError( nErr );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix :
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = PopMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
if( eFunc == ifCOUNT2 )
|
2001-02-28 13:31:18 +00:00
|
|
|
nCount += (ULONG) nC * nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
if (!pMat->IsString(nMatCol,nMatRow))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
nCount++;
|
2007-02-27 11:16:06 +00:00
|
|
|
fVal = pMat->GetDouble(nMatCol,nMatRow);
|
2000-09-18 23:16:46 +00:00
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifAVERAGE:
|
|
|
|
case ifSUM:
|
|
|
|
if ( bNull && fVal != 0.0 )
|
|
|
|
{
|
|
|
|
bNull = FALSE;
|
|
|
|
fMem = fVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fRes += fVal;
|
|
|
|
break;
|
|
|
|
case ifSUMSQ: fRes += fVal * fVal; break;
|
|
|
|
case ifPRODUCT: fRes *= fVal; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero )
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
if ( eFunc == ifPRODUCT )
|
|
|
|
fRes = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
for ( ; i < nParamCount; i++ )
|
|
|
|
Pop();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
case ifSUM: fRes = ::rtl::math::approxAdd( fRes, fMem ); break;
|
2007-07-06 11:35:07 +00:00
|
|
|
case ifAVERAGE: fRes = div(::rtl::math::approxAdd( fRes, fMem ), nCount); break;
|
2000-09-18 23:16:46 +00:00
|
|
|
case ifCOUNT2:
|
|
|
|
case ifCOUNT: fRes = nCount; break;
|
|
|
|
case ifPRODUCT: if ( !nCount ) fRes = 0.0; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
// Bei Summen etc. macht ein BOOL-Ergebnis keinen Sinn
|
|
|
|
// und Anzahl ist immer Number (#38345#)
|
|
|
|
if( eFunc == ifCOUNT || nFuncFmtType == NUMBERFORMAT_LOGICAL )
|
|
|
|
nFuncFmtType = NUMBERFORMAT_NUMBER;
|
|
|
|
return fRes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSumSQ()
|
|
|
|
{
|
|
|
|
PushDouble( IterateParameters( ifSUMSQ ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSum()
|
|
|
|
{
|
|
|
|
PushDouble( IterateParameters( ifSUM ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScProduct()
|
|
|
|
{
|
|
|
|
PushDouble( IterateParameters( ifPRODUCT ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScAverage( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
PushDouble( IterateParameters( ifAVERAGE, bTextAsZero ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCount()
|
|
|
|
{
|
|
|
|
PushDouble( IterateParameters( ifCOUNT ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCount2()
|
|
|
|
{
|
|
|
|
PushDouble( IterateParameters( ifCOUNT2 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::GetStVarParams( double& rVal, double& rValCount,
|
|
|
|
BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
2004-11-15 15:35:15 +00:00
|
|
|
|
|
|
|
std::vector<double> values;
|
2000-09-18 23:16:46 +00:00
|
|
|
double fSum = 0.0;
|
2004-11-15 15:35:15 +00:00
|
|
|
double vSum = 0.0;
|
|
|
|
double vMean = 0.0;
|
|
|
|
double fVal = 0.0;
|
2000-09-18 23:16:46 +00:00
|
|
|
rValCount = 0.0;
|
|
|
|
ScAddress aAdr;
|
|
|
|
ScRange aRange;
|
2006-08-04 10:34:02 +00:00
|
|
|
for (USHORT i = 0; i < nParamCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
case svDouble :
|
|
|
|
{
|
|
|
|
fVal = GetDouble();
|
2004-11-15 15:35:15 +00:00
|
|
|
values.push_back(fVal);
|
2000-09-18 23:16:46 +00:00
|
|
|
fSum += fVal;
|
|
|
|
rValCount++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
fVal = GetCellValue( aAdr, pCell );
|
2004-11-15 15:35:15 +00:00
|
|
|
values.push_back(fVal);
|
2000-09-18 23:16:46 +00:00
|
|
|
fSum += fVal;
|
|
|
|
rValCount++;
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero && HasCellStringData( pCell ) )
|
2004-11-15 15:35:15 +00:00
|
|
|
{
|
|
|
|
values.push_back(0.0);
|
2000-09-18 23:16:46 +00:00
|
|
|
rValCount++;
|
2004-11-15 15:35:15 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
|
|
|
USHORT nErr = 0;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
|
|
|
|
if (aValIter.GetFirst(fVal, nErr))
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2004-11-15 15:35:15 +00:00
|
|
|
values.push_back(fVal);
|
2000-09-18 23:16:46 +00:00
|
|
|
fSum += fVal;
|
|
|
|
rValCount++;
|
|
|
|
}
|
|
|
|
while ((nErr == 0) && aValIter.GetNext(fVal, nErr));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMatrix :
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = PopMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat->GetDimensions(nC, nR);
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
if (!pMat->IsString(nMatCol,nMatRow))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
fVal= pMat->GetDouble(nMatCol,nMatRow);
|
2004-11-15 15:35:15 +00:00
|
|
|
values.push_back(fVal);
|
2000-09-18 23:16:46 +00:00
|
|
|
fSum += fVal;
|
|
|
|
rValCount++;
|
|
|
|
}
|
|
|
|
else if ( bTextAsZero )
|
2004-11-15 15:35:15 +00:00
|
|
|
{
|
|
|
|
values.push_back(0.0);
|
2000-09-18 23:16:46 +00:00
|
|
|
rValCount++;
|
2004-11-15 15:35:15 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
{
|
|
|
|
if ( bTextAsZero )
|
2004-11-15 15:35:15 +00:00
|
|
|
{
|
|
|
|
values.push_back(0.0);
|
2000-09-18 23:16:46 +00:00
|
|
|
rValCount++;
|
2004-11-15 15:35:15 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Pop();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default :
|
|
|
|
Pop();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
2004-11-15 15:35:15 +00:00
|
|
|
|
2006-08-04 10:34:02 +00:00
|
|
|
::std::vector<double>::size_type n = values.size();
|
|
|
|
vMean = fSum / n;
|
|
|
|
for (::std::vector<double>::size_type i = 0; i < n; i++)
|
2004-11-15 15:35:15 +00:00
|
|
|
vSum += (values[i] - vMean) * (values[i] - vMean);
|
|
|
|
|
|
|
|
rVal = vSum;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScVar( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
double nVal;
|
|
|
|
double nValCount;
|
|
|
|
GetStVarParams( nVal, nValCount, bTextAsZero );
|
2007-07-06 11:35:07 +00:00
|
|
|
|
|
|
|
if (nValCount <= 1.0)
|
|
|
|
PushError( errDivisionByZero );
|
|
|
|
else
|
|
|
|
PushDouble( nVal / (nValCount - 1.0));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScVarP( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
double nVal;
|
|
|
|
double nValCount;
|
|
|
|
GetStVarParams( nVal, nValCount, bTextAsZero );
|
2007-07-06 11:35:07 +00:00
|
|
|
|
|
|
|
PushDouble( div( nVal, nValCount));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScStDev( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
double nVal;
|
|
|
|
double nValCount;
|
|
|
|
GetStVarParams( nVal, nValCount, bTextAsZero );
|
2007-07-06 11:35:07 +00:00
|
|
|
if (nValCount <= 1.0)
|
|
|
|
PushError( errDivisionByZero );
|
|
|
|
else
|
|
|
|
PushDouble( sqrt( nVal / (nValCount - 1.0)));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScStDevP( BOOL bTextAsZero )
|
|
|
|
{
|
|
|
|
double nVal;
|
|
|
|
double nValCount;
|
|
|
|
GetStVarParams( nVal, nValCount, bTextAsZero );
|
2007-07-06 11:35:07 +00:00
|
|
|
if (nValCount == 0.0)
|
|
|
|
PushError( errDivisionByZero );
|
|
|
|
else
|
|
|
|
PushDouble( sqrt( nVal / nValCount));
|
|
|
|
|
|
|
|
/* this was: PushDouble( sqrt( div( nVal, nValCount)));
|
|
|
|
*
|
|
|
|
* Besides that the special NAN gets lost in the call through sqrt(),
|
|
|
|
* unxlngi6.pro then looped back and forth somewhere between div() and
|
|
|
|
* ::rtl::math::setNan(). Tests showed that
|
|
|
|
*
|
|
|
|
* sqrt( div( 1, 0));
|
|
|
|
*
|
|
|
|
* produced a loop, but
|
|
|
|
*
|
|
|
|
* double f1 = div( 1, 0);
|
|
|
|
* sqrt( f1 );
|
|
|
|
*
|
|
|
|
* was fine. There seems to be some compiler optimization problem. It does
|
|
|
|
* not occur when compiled with debug=t.
|
|
|
|
*/
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScColumns()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
ULONG nVal = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
for (USHORT i = 1; i <= nParamCount; i++)
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svSingleRef:
|
|
|
|
PopError();
|
|
|
|
nVal++;
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nVal += static_cast<ULONG>(nTab2 - nTab1 + 1) *
|
|
|
|
static_cast<ULONG>(nCol2 - nCol1 + 1);
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = PopMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
nVal += nC;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PushDouble((double)nVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScRows()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
ULONG nVal = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
for (USHORT i = 1; i <= nParamCount; i++)
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svSingleRef:
|
|
|
|
PopError();
|
|
|
|
nVal++;
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nVal += static_cast<ULONG>(nTab2 - nTab1 + 1) *
|
|
|
|
static_cast<ULONG>(nRow2 - nRow1 + 1);
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = PopMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
nVal += nR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PushDouble((double)nVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScInterpreter::ScTables()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
ULONG nVal;
|
|
|
|
if ( nParamCount == 0 )
|
|
|
|
nVal = pDok->GetTableCount();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nVal = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
for (USHORT i = 1; i <= nParamCount; i++)
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svSingleRef:
|
|
|
|
PopError();
|
|
|
|
nVal++;
|
|
|
|
break;
|
|
|
|
case svDoubleRef:
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nVal += static_cast<ULONG>(nTab2 - nTab1 + 1);
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
case svMatrix:
|
|
|
|
PopError();
|
|
|
|
nVal++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PushDouble( (double) nVal );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScColumn()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 0, 1 ) )
|
|
|
|
{
|
2007-03-05 13:41:58 +00:00
|
|
|
double nVal = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nParamCount == 0)
|
2005-09-28 10:37:54 +00:00
|
|
|
{
|
2000-09-18 23:16:46 +00:00
|
|
|
nVal = aPos.Col() + 1;
|
2005-09-28 10:37:54 +00:00
|
|
|
if (bMatrixFormula)
|
|
|
|
{
|
|
|
|
SCCOL nCols;
|
|
|
|
SCROW nRows;
|
|
|
|
pMyFormulaCell->GetMatColsRows( nCols, nRows);
|
|
|
|
ScMatrixRef pResMat = GetNewMat( static_cast<SCSIZE>(nCols), 1);
|
|
|
|
if (pResMat)
|
|
|
|
{
|
|
|
|
for (SCCOL i=0; i < nCols; ++i)
|
|
|
|
pResMat->PutDouble( nVal + i, static_cast<SCSIZE>(i), 0);
|
|
|
|
PushMatrix( pResMat);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopSingleRef( nCol1, nRow1, nTab1 );
|
|
|
|
nVal = (double) (nCol1 + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
|
|
|
|
if (nCol2 > nCol1)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
ScMatrixRef pResMat = GetNewMat(
|
|
|
|
static_cast<SCSIZE>(nCol2-nCol1+1), 1);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pResMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for (SCCOL i = nCol1; i <= nCol2; i++)
|
|
|
|
pResMat->PutDouble((double)(i+1),
|
|
|
|
static_cast<SCSIZE>(i-nCol1), 0);
|
2000-09-18 23:16:46 +00:00
|
|
|
PushMatrix(pResMat);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nVal = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nVal = (double) (nCol1 + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
nVal = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PushDouble( nVal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScRow()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 0, 1 ) )
|
|
|
|
{
|
2007-03-05 13:41:58 +00:00
|
|
|
double nVal = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nParamCount == 0)
|
2005-09-28 10:37:54 +00:00
|
|
|
{
|
2000-09-18 23:16:46 +00:00
|
|
|
nVal = aPos.Row() + 1;
|
2005-09-28 10:37:54 +00:00
|
|
|
if (bMatrixFormula)
|
|
|
|
{
|
|
|
|
SCCOL nCols;
|
|
|
|
SCROW nRows;
|
|
|
|
pMyFormulaCell->GetMatColsRows( nCols, nRows);
|
|
|
|
ScMatrixRef pResMat = GetNewMat( 1, static_cast<SCSIZE>(nRows));
|
|
|
|
if (pResMat)
|
|
|
|
{
|
|
|
|
for (SCROW i=0; i < nRows; i++)
|
|
|
|
pResMat->PutDouble( nVal + i, 0, static_cast<SCSIZE>(i));
|
|
|
|
PushMatrix( pResMat);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopSingleRef( nCol1, nRow1, nTab1 );
|
|
|
|
nVal = (double) (nRow1 + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
|
|
|
|
if (nRow2 > nRow1)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
ScMatrixRef pResMat = GetNewMat( 1,
|
|
|
|
static_cast<SCSIZE>(nRow2-nRow1+1));
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pResMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
for (SCROW i = nRow1; i <= nRow2; i++)
|
|
|
|
pResMat->PutDouble((double)(i+1), 0,
|
|
|
|
static_cast<SCSIZE>(i-nRow1));
|
2000-09-18 23:16:46 +00:00
|
|
|
PushMatrix(pResMat);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nVal = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nVal = (double) (nRow1 + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
nVal = 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PushDouble( nVal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScInterpreter::ScTable()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 0, 1 ) )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
SCTAB nVal = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( nParamCount == 0 )
|
|
|
|
nVal = aPos.Tab() + 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svString :
|
|
|
|
{
|
|
|
|
String aStr( PopString() );
|
|
|
|
if ( pDok->GetTable( aStr, nVal ) )
|
|
|
|
++nVal;
|
|
|
|
else
|
|
|
|
SetError( errIllegalArgument );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopSingleRef( nCol1, nRow1, nTab1 );
|
|
|
|
nVal = nTab1 + 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
|
|
|
|
nVal = nTab1 + 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
}
|
|
|
|
if ( nGlobalError )
|
|
|
|
nVal = 0;
|
|
|
|
}
|
|
|
|
PushDouble( (double) nVal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScMatch()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
|
|
|
|
{
|
|
|
|
double fTyp;
|
|
|
|
if (nParamCount == 3)
|
|
|
|
fTyp = GetDouble();
|
|
|
|
else
|
|
|
|
fTyp = 1.0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
|
|
|
if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2))
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nGlobalError == 0)
|
|
|
|
{
|
|
|
|
double fVal;
|
|
|
|
String sStr;
|
|
|
|
ScQueryParam rParam;
|
|
|
|
rParam.nCol1 = nCol1;
|
|
|
|
rParam.nRow1 = nRow1;
|
|
|
|
rParam.nCol2 = nCol2;
|
2007-09-27 12:53:45 +00:00
|
|
|
rParam.nTab = nTab1;
|
2004-11-15 15:35:15 +00:00
|
|
|
rParam.bMixedComparison = TRUE;
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
ScQueryEntry& rEntry = rParam.GetEntry(0);
|
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
if (fTyp < 0.0)
|
|
|
|
rEntry.eOp = SC_GREATER_EQUAL;
|
|
|
|
else if (fTyp > 0.0)
|
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
{
|
|
|
|
fVal = GetDouble();
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = fVal;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
{
|
|
|
|
sStr = GetString();
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
fVal = GetCellValue( aAdr, pCell );
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = fVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetCellString(sStr, pCell);
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-10-22 06:58:58 +00:00
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix(
|
|
|
|
rEntry.nVal, *rEntry.pStr);
|
2007-06-13 08:07:39 +00:00
|
|
|
rEntry.bQueryByString = ScMatrix::IsStringType( nType);
|
2004-10-22 06:58:58 +00:00
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( rEntry.bQueryByString )
|
2001-05-15 20:06:49 +00:00
|
|
|
rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2007-09-27 12:53:45 +00:00
|
|
|
SCCOLROW nDelta = 0;
|
2001-09-05 08:36:25 +00:00
|
|
|
if (nCol1 == nCol2)
|
|
|
|
{ // search row in column
|
2000-09-18 23:16:46 +00:00
|
|
|
rParam.nRow2 = nRow2;
|
|
|
|
rEntry.nField = nCol1;
|
2007-09-27 12:53:45 +00:00
|
|
|
ScAddress aResultPos( nCol1, nRow1, nTab1);
|
|
|
|
if (!LookupQueryWithCache( aResultPos, rParam))
|
|
|
|
{
|
|
|
|
SetNA();
|
|
|
|
return;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2007-09-27 12:53:45 +00:00
|
|
|
nDelta = aResultPos.Row() - nRow1;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-09-05 08:36:25 +00:00
|
|
|
else
|
|
|
|
{ // search column in row
|
2007-09-27 12:53:45 +00:00
|
|
|
SCCOL nC;
|
2004-09-08 14:56:16 +00:00
|
|
|
rParam.bByRow = FALSE;
|
2000-09-18 23:16:46 +00:00
|
|
|
rParam.nRow2 = nRow1;
|
|
|
|
rEntry.nField = nCol1;
|
|
|
|
ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
|
2001-09-05 08:36:25 +00:00
|
|
|
// Advance Entry.nField in Iterator if column changed
|
2000-09-18 23:16:46 +00:00
|
|
|
aCellIter.SetAdvanceQueryParamEntryField( TRUE );
|
2001-09-05 08:36:25 +00:00
|
|
|
if (fTyp == 0.0)
|
|
|
|
{ // EQUAL
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( aCellIter.GetFirst() )
|
|
|
|
nC = aCellIter.GetCol();
|
|
|
|
else
|
2001-09-05 08:36:25 +00:00
|
|
|
{
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2000-09-18 23:16:46 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2001-09-05 08:36:25 +00:00
|
|
|
{ // <= or >=
|
2007-09-27 12:53:45 +00:00
|
|
|
SCROW nR;
|
2004-09-08 14:56:16 +00:00
|
|
|
if ( !aCellIter.FindEqualOrSortedLastInRange( nC, nR ) )
|
2001-09-05 08:36:25 +00:00
|
|
|
{
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2001-09-05 08:36:25 +00:00
|
|
|
return;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
nDelta = nC - nCol1;
|
|
|
|
}
|
|
|
|
PushDouble((double) (nDelta + 1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCountEmptyCells()
|
|
|
|
{
|
|
|
|
if ( MustHaveParamCount( GetByte(), 1 ) )
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
ULONG nMaxCount = 0, nCount = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
CellType eCellType;
|
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
nMaxCount = 1;
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
eCellType = GetCellType( GetCell( aAdr ) );
|
|
|
|
if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
|
|
|
|
nCount = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nMaxCount = static_cast<ULONG>(nRow2 - nRow1 + 1) *
|
|
|
|
static_cast<ULONG>(nCol2 - nCol1 + 1) *
|
|
|
|
static_cast<ULONG>(nTab2 - nTab1 + 1);
|
2000-09-18 23:16:46 +00:00
|
|
|
ScBaseCell* pCell;
|
|
|
|
ScCellIterator aDocIter(pDok, nCol1, nRow1, nTab1,
|
|
|
|
nCol2, nRow2, nTab2, glSubTotal);
|
2007-02-27 11:16:06 +00:00
|
|
|
if ( (pCell = aDocIter.GetFirst()) != NULL )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ((eCellType = pCell->GetCellType()) != CELLTYPE_NONE
|
|
|
|
&& eCellType != CELLTYPE_NOTE)
|
|
|
|
nCount++;
|
2007-02-27 11:16:06 +00:00
|
|
|
} while ( (pCell = aDocIter.GetNext()) != NULL );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default : SetError(errIllegalParameter); break;
|
|
|
|
}
|
|
|
|
PushDouble(nMaxCount - nCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCountIf()
|
|
|
|
{
|
|
|
|
if ( MustHaveParamCount( GetByte(), 2 ) )
|
|
|
|
{
|
|
|
|
String rString;
|
2007-02-27 11:16:06 +00:00
|
|
|
double fVal = 0.0;
|
2000-09-18 23:16:46 +00:00
|
|
|
BOOL bIsString = TRUE;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
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;
|
2006-12-19 12:17:39 +00:00
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
|
|
|
|
rString);
|
2007-06-13 08:07:39 +00:00
|
|
|
bIsString = ScMatrix::IsStringType( nType);
|
2006-12-19 12:17:39 +00:00
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
case svString:
|
|
|
|
rString = GetString();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
fVal = GetDouble();
|
|
|
|
bIsString = FALSE;
|
|
|
|
}
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
PopSingleRef( nCol1, nRow1, nTab1 );
|
|
|
|
nCol2 = nCol1;
|
|
|
|
nRow2 = nRow1;
|
|
|
|
nTab2 = nTab1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetIllegalParameter();
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
if ( nTab1 != nTab2 )
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nCol1 > nCol2)
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nGlobalError == 0)
|
|
|
|
{
|
|
|
|
ScQueryParam rParam;
|
|
|
|
rParam.nRow1 = nRow1;
|
|
|
|
rParam.nRow2 = nRow2;
|
|
|
|
|
|
|
|
ScQueryEntry& rEntry = rParam.GetEntry(0);
|
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
if (!bIsString)
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = fVal;
|
|
|
|
rEntry.eOp = SC_EQUAL;
|
|
|
|
}
|
2005-03-29 12:32:52 +00:00
|
|
|
else
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
rParam.FillInExcelSyntax(rString, 0);
|
2005-12-14 14:06:41 +00:00
|
|
|
sal_uInt32 nIndex = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
rEntry.bQueryByString =
|
|
|
|
!(pFormatter->IsNumberFormat(
|
|
|
|
*rEntry.pStr, nIndex, rEntry.nVal));
|
|
|
|
if ( rEntry.bQueryByString )
|
2001-05-15 20:06:49 +00:00
|
|
|
rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
double fSum = 0.0;
|
|
|
|
rParam.nCol1 = nCol1;
|
|
|
|
rParam.nCol2 = nCol2;
|
|
|
|
rEntry.nField = nCol1;
|
|
|
|
ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
|
|
|
|
// Entry.nField im Iterator bei Spaltenwechsel weiterschalten
|
|
|
|
aCellIter.SetAdvanceQueryParamEntryField( TRUE );
|
|
|
|
if ( aCellIter.GetFirst() )
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
fSum++;
|
|
|
|
} while ( aCellIter.GetNext() );
|
|
|
|
}
|
|
|
|
PushDouble(fSum);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSumIf()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
SCCOL nCol3 = 0;
|
|
|
|
SCROW nRow3 = 0;
|
|
|
|
SCTAB nTab3 = 0;
|
|
|
|
SCCOL nCol4 = 0;
|
|
|
|
SCROW nRow4 = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab4;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nParamCount == 3)
|
|
|
|
{
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
PopDoubleRef( nCol3, nRow3, nTab3, nCol4, nRow4, nTab4 );
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
PopSingleRef( nCol3, nRow3, nTab3 );
|
|
|
|
nCol4 = nCol3;
|
|
|
|
nRow4 = nRow3;
|
|
|
|
nTab4 = nTab3;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetIllegalParameter();
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
if ( nTab3 != nTab4 )
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String rString;
|
2007-02-27 11:16:06 +00:00
|
|
|
double fVal = 0.0;
|
2000-09-18 23:16:46 +00:00
|
|
|
BOOL bIsString = TRUE;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
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;
|
2004-10-22 06:58:58 +00:00
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
|
|
|
|
rString);
|
2007-06-13 08:07:39 +00:00
|
|
|
bIsString = ScMatrix::IsStringType( nType);
|
2004-10-22 06:58:58 +00:00
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
fVal = GetDouble();
|
|
|
|
bIsString = FALSE;
|
|
|
|
}
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
PopSingleRef( nCol1, nRow1, nTab1 );
|
|
|
|
nCol2 = nCol1;
|
|
|
|
nRow2 = nRow1;
|
|
|
|
nTab2 = nTab1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetIllegalParameter();
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
if ( nTab1 != nTab2 )
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nParamCount != 3)
|
|
|
|
{
|
|
|
|
nCol3 = nCol1;
|
|
|
|
nRow3 = nRow1;
|
|
|
|
nTab3 = nTab1;
|
|
|
|
nCol4 = nCol2;
|
|
|
|
nRow4 = nRow2;
|
|
|
|
nTab4 = nTab2;
|
|
|
|
}
|
|
|
|
else if (nCol4 - nCol3 != nCol2 - nCol1 ||
|
|
|
|
nRow4 - nRow3 != nRow2 - nRow1 || nCol1 > nCol2)
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nGlobalError == 0)
|
|
|
|
{
|
|
|
|
ScQueryParam rParam;
|
|
|
|
rParam.nRow1 = nRow1;
|
|
|
|
rParam.nRow2 = nRow2;
|
|
|
|
|
|
|
|
ScQueryEntry& rEntry = rParam.GetEntry(0);
|
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
if (!bIsString)
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = fVal;
|
|
|
|
rEntry.eOp = SC_EQUAL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
rParam.FillInExcelSyntax(rString, 0);
|
2005-12-14 14:06:41 +00:00
|
|
|
sal_uInt32 nIndex = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
rEntry.bQueryByString =
|
|
|
|
!(pFormatter->IsNumberFormat(
|
|
|
|
*rEntry.pStr, nIndex, rEntry.nVal));
|
|
|
|
if ( rEntry.bQueryByString )
|
2001-05-15 20:06:49 +00:00
|
|
|
rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
double fSum = 0.0;
|
|
|
|
double fMem = 0.0;
|
|
|
|
BOOL bNull = TRUE;
|
|
|
|
ScAddress aAdr;
|
|
|
|
aAdr.SetTab( nTab3 );
|
|
|
|
rParam.nCol1 = nCol1;
|
|
|
|
rParam.nCol2 = nCol2;
|
|
|
|
rEntry.nField = nCol1;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
long nColDiff = nCol3 - nCol1;
|
|
|
|
long nRowDiff = nRow3 - nRow1;
|
2000-09-18 23:16:46 +00:00
|
|
|
ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
|
|
|
|
// Entry.nField im Iterator bei Spaltenwechsel weiterschalten
|
|
|
|
aCellIter.SetAdvanceQueryParamEntryField( TRUE );
|
|
|
|
if ( aCellIter.GetFirst() )
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
aAdr.SetCol( sal::static_int_cast<SCCOL>( aCellIter.GetCol() + nColDiff ) );
|
|
|
|
aAdr.SetRow( sal::static_int_cast<SCROW>( aCellIter.GetRow() + nRowDiff ) );
|
2000-09-18 23:16:46 +00:00
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if ( HasCellValueData(pCell) )
|
|
|
|
{
|
|
|
|
fVal = GetCellValue( aAdr, pCell );
|
|
|
|
if ( bNull && fVal != 0.0 )
|
|
|
|
{
|
|
|
|
bNull = FALSE;
|
|
|
|
fMem = fVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fSum += fVal;
|
|
|
|
}
|
|
|
|
} while ( aCellIter.GetNext() );
|
|
|
|
}
|
2003-03-26 17:07:02 +00:00
|
|
|
PushDouble( ::rtl::math::approxAdd( fSum, fMem ) );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScLookup()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
|
|
|
|
return ;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCSIZE nC3 = 0, nC1 = 0;
|
|
|
|
SCSIZE nR3 = 0, nR1 = 0;
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat3 = NULL;
|
|
|
|
ScMatrixRef pMat1 = NULL;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCCOL nCol1 = 0;
|
|
|
|
SCROW nRow1 = 0;
|
|
|
|
SCTAB nTab1 = 0;
|
|
|
|
SCCOL nCol2 = 0;
|
|
|
|
SCROW nRow2 = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab2;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCCOL nCol3 = 0;
|
|
|
|
SCROW nRow3 = 0;
|
|
|
|
SCTAB nTab3 = 0;
|
|
|
|
SCCOL nCol4 = 0;
|
|
|
|
SCROW nRow4 = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab4;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCSIZE nDelta = 0;
|
2001-05-16 23:56:22 +00:00
|
|
|
|
|
|
|
// param 3: data range
|
|
|
|
if ( nParamCount == 3 )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
PopDoubleRef(nCol3, nRow3, nTab3, nCol4, nRow4, nTab4);
|
|
|
|
if (nTab3 != nTab4 || (nCol3 != nCol4 && nRow3 != nRow4))
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GetStackType() == svMatrix)
|
|
|
|
{
|
|
|
|
pMat3 = PopMatrix();
|
|
|
|
if (pMat3)
|
|
|
|
{
|
|
|
|
pMat3->GetDimensions(nC3, nR3);
|
|
|
|
if (nC3 != 1 && nR3 != 1)
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// param 2: key range, or key range and data range
|
|
|
|
if (GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
|
|
|
if ( nTab1 != nTab2 || (nParamCount == 3 && nCol1 != nCol2 && nRow1 != nRow2) )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
else if (GetStackType() == svMatrix)
|
|
|
|
{
|
|
|
|
pMat1 = PopMatrix();
|
|
|
|
if (pMat1)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
pMat1->GetDimensions(nC1, nR1);
|
|
|
|
if (nC1 != 1 && nR1 != 1)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
BOOL bSpMatrix, bSpVector;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nMatCount, nVecCount;
|
2001-05-16 23:56:22 +00:00
|
|
|
if (pMat1 == NULL)
|
|
|
|
{
|
|
|
|
if (nRow1 == nRow2)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nMatCount = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
|
2001-05-16 23:56:22 +00:00
|
|
|
bSpMatrix = FALSE;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nMatCount = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
|
2001-05-16 23:56:22 +00:00
|
|
|
bSpMatrix = TRUE;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (nR1 == 1)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
nMatCount = nC1;
|
|
|
|
bSpMatrix = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nMatCount = nR1;
|
|
|
|
bSpMatrix = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( nParamCount < 3 )
|
|
|
|
{
|
|
|
|
nVecCount = nMatCount;
|
|
|
|
bSpVector = bSpMatrix;
|
|
|
|
}
|
|
|
|
else if (pMat3 == NULL)
|
|
|
|
{
|
|
|
|
if (nRow3 == nRow4)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nVecCount = static_cast<SCSIZE>(nCol4 - nCol3 + 1);
|
2001-05-16 23:56:22 +00:00
|
|
|
bSpVector = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nVecCount = static_cast<SCSIZE>(nRow4 - nRow3 + 1);
|
2001-05-16 23:56:22 +00:00
|
|
|
bSpVector = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (nR3 == 1)
|
|
|
|
{
|
|
|
|
nVecCount = nC3;
|
|
|
|
bSpVector = FALSE;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
nVecCount = nR3;
|
|
|
|
bSpVector = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nGlobalError == 0 && nVecCount == nMatCount)
|
|
|
|
{
|
|
|
|
String sStr;
|
2005-03-29 12:32:52 +00:00
|
|
|
ScQueryParam aParam;
|
|
|
|
aParam.nCol1 = nCol1;
|
|
|
|
aParam.nRow1 = nRow1;
|
|
|
|
aParam.nCol2 = (bSpMatrix ? nCol1 : nCol2);
|
|
|
|
aParam.nRow2 = (bSpMatrix ? nRow2 : nRow1);
|
|
|
|
aParam.bByRow = bSpMatrix;
|
|
|
|
aParam.bMixedComparison = TRUE;
|
|
|
|
|
|
|
|
ScQueryEntry& rEntry = aParam.GetEntry(0);
|
2001-05-16 23:56:22 +00:00
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
|
|
|
rEntry.nField = nCol1;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = GetDouble();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
break;
|
|
|
|
case svString:
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
sStr = GetString();
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
PushInt(0);
|
|
|
|
return ;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = GetCellValue( aAdr, pCell );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
else
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
if ( GetCellType( pCell ) == CELLTYPE_NOTE )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
2001-05-16 23:56:22 +00:00
|
|
|
rEntry.nVal = 0.0;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
GetCellString(sStr, pCell);
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
break;
|
2004-10-22 06:58:58 +00:00
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix( rEntry.nVal,
|
|
|
|
*rEntry.pStr);
|
2007-06-13 08:07:39 +00:00
|
|
|
rEntry.bQueryByString = ScMatrix::IsStringType( nType);
|
2004-10-22 06:58:58 +00:00
|
|
|
}
|
|
|
|
break;
|
2001-05-16 23:56:22 +00:00
|
|
|
default:
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( rEntry.bQueryByString )
|
2005-03-29 12:32:52 +00:00
|
|
|
aParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2001-05-16 23:56:22 +00:00
|
|
|
if (pMat1)
|
|
|
|
{
|
|
|
|
if (rEntry.bQueryByString)
|
|
|
|
{
|
|
|
|
//!!!!!!!
|
|
|
|
//! TODO: enable regex on matrix strings
|
|
|
|
//!!!!!!!
|
|
|
|
BOOL bFound = FALSE;
|
|
|
|
sal_Int32 nRes;
|
|
|
|
String aParamStr = *rEntry.pStr;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE i;
|
2003-12-01 16:51:02 +00:00
|
|
|
for ( i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
if (!pMat1->IsValue(i))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
nRes = ScGlobal::pCollator->compareString(
|
|
|
|
pMat1->GetString(i), aParamStr );
|
|
|
|
if (nRes == COMPARE_EQUAL)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
bFound = TRUE;
|
|
|
|
nDelta = i;
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
else if (nRes == COMPARE_LESS)
|
2000-09-18 23:16:46 +00:00
|
|
|
i = nMatCount+1;
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
if (i == nMatCount+2 && !bFound)
|
|
|
|
{
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2001-05-16 23:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (!bFound)
|
|
|
|
nDelta = i-1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BOOL bFound = FALSE;
|
|
|
|
double fVal1;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE i;
|
2003-12-01 16:51:02 +00:00
|
|
|
for ( i = 0; i < nMatCount; i++)
|
2001-05-16 23:56:22 +00:00
|
|
|
{
|
|
|
|
if (pMat1->IsValue(i))
|
|
|
|
fVal1 = pMat1->GetDouble(i);
|
|
|
|
else
|
|
|
|
fVal1 = MAXDOUBLE;
|
|
|
|
if (fVal1 == rEntry.nVal)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
bFound = TRUE;
|
|
|
|
nDelta = i;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
else if (fVal1 > rEntry.nVal)
|
|
|
|
i = nMatCount+1;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
if (i == nMatCount+2 && !bFound)
|
|
|
|
{
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2001-05-16 23:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (!bFound)
|
|
|
|
nDelta = i-1;
|
|
|
|
}
|
|
|
|
}
|
2005-03-29 12:32:52 +00:00
|
|
|
else
|
2001-05-16 23:56:22 +00:00
|
|
|
{
|
2005-03-29 12:32:52 +00:00
|
|
|
ScQueryCellIterator aCellIter(pDok, nTab1, aParam, FALSE);
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nC;
|
|
|
|
SCROW nR;
|
2005-03-29 12:32:52 +00:00
|
|
|
// Advance Entry.nField in iterator upon switching columns if
|
|
|
|
// lookup in row.
|
|
|
|
aCellIter.SetAdvanceQueryParamEntryField( !bSpMatrix);
|
2001-09-05 08:36:25 +00:00
|
|
|
if ( aCellIter.FindEqualOrSortedLastInRange( nC, nR ) )
|
2005-03-29 12:32:52 +00:00
|
|
|
nDelta = bSpMatrix ? static_cast<SCSIZE>(nR - nRow1) :
|
|
|
|
static_cast<SCSIZE>(nC - nCol1);
|
2001-05-16 23:56:22 +00:00
|
|
|
else
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2001-09-05 08:36:25 +00:00
|
|
|
return;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (pMat3)
|
|
|
|
{
|
|
|
|
if (pMat3->IsValue(nDelta))
|
|
|
|
PushDouble(pMat3->GetDouble(nDelta));
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2001-05-16 23:56:22 +00:00
|
|
|
PushString(pMat3->GetString(nDelta));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( nParamCount < 3 )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
if (bSpVector)
|
|
|
|
{
|
|
|
|
aAdr.SetCol( nCol2 ); // data in right col of key/data range
|
2007-02-27 11:16:06 +00:00
|
|
|
aAdr.SetRow( sal::static_int_cast<SCROW>( nRow1 + nDelta ) );
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2001-05-16 23:56:22 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
aAdr.SetCol( sal::static_int_cast<SCCOL>( nCol1 + nDelta ) );
|
2001-05-16 23:56:22 +00:00
|
|
|
aAdr.SetRow( nRow2 ); // data in lower row of key/data range
|
|
|
|
}
|
|
|
|
aAdr.SetTab( nTab1 );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (bSpVector)
|
|
|
|
{
|
|
|
|
aAdr.SetCol( nCol3 );
|
2007-02-27 11:16:06 +00:00
|
|
|
aAdr.SetRow( sal::static_int_cast<SCROW>( nRow3 + nDelta ) );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
aAdr.SetCol( sal::static_int_cast<SCCOL>( nCol3 + nDelta ) );
|
2000-09-18 23:16:46 +00:00
|
|
|
aAdr.SetRow( nRow3 );
|
|
|
|
}
|
|
|
|
aAdr.SetTab( nTab3 );
|
|
|
|
}
|
2001-05-16 23:56:22 +00:00
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
PushDouble(GetCellValue( aAdr, pCell ));
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
String aStr;
|
|
|
|
GetCellString(aStr, pCell);
|
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScHLookup()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 3, 4 ) )
|
|
|
|
{
|
|
|
|
BOOL bSorted;
|
|
|
|
if (nParamCount == 4)
|
|
|
|
bSorted = GetBool();
|
|
|
|
else
|
|
|
|
bSorted = TRUE;
|
2003-03-26 17:07:02 +00:00
|
|
|
double fIndex = ::rtl::math::approxFloor( GetDouble() ) - 1.0;
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = NULL;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCSIZE nC = 0, nR = 0;
|
|
|
|
SCCOL nCol1 = 0;
|
|
|
|
SCROW nRow1 = 0;
|
|
|
|
SCTAB nTab1 = 0;
|
|
|
|
SCCOL nCol2 = 0;
|
|
|
|
SCROW nRow2 = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
|
|
|
if (nTab1 != nTab2)
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GetStackType() == svMatrix)
|
|
|
|
{
|
|
|
|
pMat = PopMatrix();
|
|
|
|
if (pMat)
|
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( fIndex < 0.0 || (pMat ? (fIndex >= nR) : (fIndex+nRow1 > nRow2)) )
|
|
|
|
{
|
|
|
|
SetIllegalArgument();
|
|
|
|
return;
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCROW nZIndex = static_cast<SCROW>(fIndex);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (!pMat)
|
|
|
|
nZIndex += nRow1; // Wertzeile
|
|
|
|
if (nGlobalError == 0)
|
|
|
|
{
|
|
|
|
String sStr;
|
|
|
|
ScQueryParam rParam;
|
|
|
|
rParam.nCol1 = nCol1;
|
|
|
|
rParam.nRow1 = nRow1;
|
|
|
|
rParam.nCol2 = nCol2;
|
|
|
|
rParam.nRow2 = nRow1; // nur in der ersten Zeile suchen
|
2004-09-08 14:56:16 +00:00
|
|
|
rParam.bByRow = FALSE;
|
2004-11-15 15:35:15 +00:00
|
|
|
rParam.bMixedComparison = TRUE;
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
ScQueryEntry& rEntry = rParam.GetEntry(0);
|
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
if ( bSorted )
|
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = GetDouble();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
{
|
|
|
|
sStr = GetString();
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = GetCellValue( aAdr, pCell );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( GetCellType( pCell ) == CELLTYPE_NOTE )
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetCellString(sStr, pCell);
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-10-22 06:58:58 +00:00
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix(
|
|
|
|
rEntry.nVal, *rEntry.pStr);
|
2007-06-13 08:07:39 +00:00
|
|
|
rEntry.bQueryByString = ScMatrix::IsStringType( nType);
|
2004-10-22 06:58:58 +00:00
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( rEntry.bQueryByString )
|
2001-05-15 20:06:49 +00:00
|
|
|
rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nMatCount = nC;
|
|
|
|
SCSIZE nDelta = SCSIZE_MAX;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (rEntry.bQueryByString)
|
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
//!!!!!!!
|
|
|
|
//! TODO: enable regex on matrix strings
|
|
|
|
//!!!!!!!
|
2000-09-18 23:16:46 +00:00
|
|
|
String aParamStr = *rEntry.pStr;
|
|
|
|
if ( bSorted )
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (pMat->IsString(i, 0))
|
2001-03-14 15:02:54 +00:00
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
sal_Int32 nRes =
|
|
|
|
ScGlobal::pCollator->compareString(
|
|
|
|
pMat->GetString(i,0), aParamStr);
|
|
|
|
if (nRes <= 0)
|
2001-03-14 15:02:54 +00:00
|
|
|
nDelta = i;
|
2004-09-08 14:56:16 +00:00
|
|
|
else if (i>0) // #i2168# ignore first mismatch
|
|
|
|
i = nMatCount+1;
|
2001-03-14 15:02:54 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
nDelta = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (pMat->IsString(i, 0))
|
|
|
|
{
|
2001-08-06 09:21:02 +00:00
|
|
|
if ( ScGlobal::pTransliteration->isEqual(
|
|
|
|
pMat->GetString(i,0), aParamStr ) )
|
2001-03-14 15:02:54 +00:00
|
|
|
{
|
|
|
|
nDelta = i;
|
|
|
|
i = nMatCount + 1;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( bSorted )
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
// #i2168# ignore strings
|
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (!pMat->IsString(i, 0))
|
2004-09-08 14:56:16 +00:00
|
|
|
{
|
|
|
|
if (pMat->GetDouble(i,0) <= rEntry.nVal)
|
|
|
|
nDelta = i;
|
|
|
|
else
|
|
|
|
i = nMatCount+1;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (!pMat->IsString(i, 0))
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
if (pMat->GetDouble(i,0) == rEntry.nVal)
|
|
|
|
{
|
|
|
|
nDelta = i;
|
|
|
|
i = nMatCount + 1;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
if ( nDelta != SCSIZE_MAX )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
if (!pMat->IsString( nDelta, static_cast<SCSIZE>(nZIndex)))
|
|
|
|
PushDouble(pMat->GetDouble( nDelta,
|
|
|
|
static_cast<SCSIZE>(nZIndex)));
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
PushString(pMat->GetString( nDelta,
|
|
|
|
static_cast<SCSIZE>(nZIndex)));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rEntry.nField = nCol1;
|
2001-05-16 23:56:22 +00:00
|
|
|
BOOL bFound = FALSE;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCCOL nCol = 0;
|
2001-09-05 08:36:25 +00:00
|
|
|
if ( bSorted )
|
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
|
|
|
ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
|
|
|
|
// advance Entry.nField in Iterator upon switching columns
|
|
|
|
aCellIter.SetAdvanceQueryParamEntryField( TRUE );
|
2001-05-16 23:56:22 +00:00
|
|
|
if ( bSorted )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2007-02-27 11:16:06 +00:00
|
|
|
SCROW nRow;
|
|
|
|
bFound = aCellIter.FindEqualOrSortedLastInRange( nCol, nRow );
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
2001-09-05 08:36:25 +00:00
|
|
|
else if ( aCellIter.GetFirst() )
|
2001-05-16 23:56:22 +00:00
|
|
|
{
|
2001-09-05 08:36:25 +00:00
|
|
|
bFound = TRUE;
|
2007-02-27 11:16:06 +00:00
|
|
|
nCol = aCellIter.GetCol();
|
2001-05-16 23:56:22 +00:00
|
|
|
}
|
|
|
|
if ( bFound )
|
|
|
|
{
|
2000-09-18 23:16:46 +00:00
|
|
|
ScBaseCell* pCell;
|
2007-02-27 11:16:06 +00:00
|
|
|
ScAddress aAdr( nCol, nZIndex, nTab1 );
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( HasCellValueData( pCell = GetCell( aAdr ) ) )
|
|
|
|
PushDouble(GetCellValue( aAdr, pCell ));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
String aStr;
|
|
|
|
GetCellString(aStr, pCell);
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScVLookup()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 3, 4 ) )
|
|
|
|
{
|
|
|
|
BOOL bSorted;
|
|
|
|
if (nParamCount == 4)
|
|
|
|
bSorted = GetBool();
|
|
|
|
else
|
|
|
|
bSorted = TRUE;
|
2003-03-26 17:07:02 +00:00
|
|
|
double fIndex = ::rtl::math::approxFloor( GetDouble() ) - 1.0;
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = NULL;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCSIZE nC = 0, nR = 0;
|
|
|
|
SCCOL nCol1 = 0;
|
|
|
|
SCROW nRow1 = 0;
|
|
|
|
SCTAB nTab1 = 0;
|
|
|
|
SCCOL nCol2 = 0;
|
|
|
|
SCROW nRow2 = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
|
|
|
if (nTab1 != nTab2)
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GetStackType() == svMatrix)
|
|
|
|
{
|
|
|
|
pMat = PopMatrix();
|
|
|
|
if (pMat)
|
|
|
|
pMat->GetDimensions(nC, nR);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( fIndex < 0.0 || (pMat ? (fIndex >= nC) : (fIndex+nCol1 > nCol2)) )
|
|
|
|
{
|
|
|
|
SetIllegalArgument();
|
|
|
|
return;
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nSpIndex = static_cast<SCCOL>(fIndex);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (!pMat)
|
2007-02-27 11:16:06 +00:00
|
|
|
nSpIndex = sal::static_int_cast<SCCOL>( nSpIndex + nCol1 ); // value column
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nGlobalError == 0)
|
|
|
|
{
|
|
|
|
String sStr;
|
|
|
|
ScQueryParam rParam;
|
|
|
|
rParam.nCol1 = nCol1;
|
|
|
|
rParam.nRow1 = nRow1;
|
|
|
|
rParam.nCol2 = nCol1; // nur in der ersten Spalte suchen
|
|
|
|
rParam.nRow2 = nRow2;
|
2007-09-27 12:53:45 +00:00
|
|
|
rParam.nTab = nTab1;
|
2004-11-15 15:35:15 +00:00
|
|
|
rParam.bMixedComparison = TRUE;
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
ScQueryEntry& rEntry = rParam.GetEntry(0);
|
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
if ( bSorted )
|
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDouble:
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = GetDouble();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svString:
|
|
|
|
{
|
|
|
|
sStr = GetString();
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svDoubleRef :
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( !PopDoubleRefOrSingleRef( aAdr ) )
|
|
|
|
{
|
|
|
|
PushInt(0);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = GetCellValue( aAdr, pCell );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( GetCellType( pCell ) == CELLTYPE_NOTE )
|
|
|
|
{
|
|
|
|
rEntry.bQueryByString = FALSE;
|
|
|
|
rEntry.nVal = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetCellString(sStr, pCell);
|
|
|
|
rEntry.bQueryByString = TRUE;
|
|
|
|
*rEntry.pStr = sStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-10-22 06:58:58 +00:00
|
|
|
case svMatrix :
|
|
|
|
{
|
|
|
|
ScMatValType nType = GetDoubleOrStringFromMatrix(
|
|
|
|
rEntry.nVal, *rEntry.pStr);
|
2007-06-13 08:07:39 +00:00
|
|
|
rEntry.bQueryByString = ScMatrix::IsStringType( nType);
|
2004-10-22 06:58:58 +00:00
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:16:46 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( rEntry.bQueryByString )
|
2001-05-15 20:06:49 +00:00
|
|
|
rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
2007-09-27 12:53:45 +00:00
|
|
|
//!!!!!!!
|
|
|
|
//! TODO: enable caching on matrix?
|
|
|
|
//!!!!!!!
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nMatCount = nR;
|
|
|
|
SCSIZE nDelta = SCSIZE_MAX;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (rEntry.bQueryByString)
|
|
|
|
{
|
2001-05-16 23:56:22 +00:00
|
|
|
//!!!!!!!
|
|
|
|
//! TODO: enable regex on matrix strings
|
|
|
|
//!!!!!!!
|
2000-09-18 23:16:46 +00:00
|
|
|
String aParamStr = *rEntry.pStr;
|
|
|
|
if ( bSorted )
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (pMat->IsString(0, i))
|
2001-03-14 15:02:54 +00:00
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
sal_Int32 nRes =
|
|
|
|
ScGlobal::pCollator->compareString(
|
|
|
|
pMat->GetString(0,i), aParamStr);
|
|
|
|
if (nRes <= 0)
|
2001-03-14 15:02:54 +00:00
|
|
|
nDelta = i;
|
2004-09-08 14:56:16 +00:00
|
|
|
else if (i>0) // #i2168# ignore first mismatch
|
|
|
|
i = nMatCount+1;
|
2001-03-14 15:02:54 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
nDelta = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (pMat->IsString(0, i))
|
|
|
|
{
|
2001-08-06 09:21:02 +00:00
|
|
|
if ( ScGlobal::pTransliteration->isEqual(
|
|
|
|
pMat->GetString(0,i), aParamStr ) )
|
2001-03-14 15:02:54 +00:00
|
|
|
{
|
|
|
|
nDelta = i;
|
|
|
|
i = nMatCount + 1;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( bSorted )
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
// #i2168# ignore strings
|
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (!pMat->IsString(0, i))
|
2004-09-08 14:56:16 +00:00
|
|
|
{
|
|
|
|
if (pMat->GetDouble(0,i) <= rEntry.nVal)
|
|
|
|
nDelta = i;
|
|
|
|
else
|
|
|
|
i = nMatCount+1;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
for (SCSIZE i = 0; i < nMatCount; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
if (!pMat->IsString(0, i))
|
|
|
|
{
|
2004-09-08 14:56:16 +00:00
|
|
|
if (pMat->GetDouble(0,i) == rEntry.nVal)
|
|
|
|
{
|
|
|
|
nDelta = i;
|
|
|
|
i = nMatCount + 1;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
if ( nDelta != SCSIZE_MAX )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
if (!pMat->IsString( static_cast<SCSIZE>(nSpIndex), nDelta))
|
|
|
|
PushDouble( pMat->GetDouble(
|
|
|
|
static_cast<SCSIZE>(nSpIndex), nDelta));
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
PushString( pMat->GetString(
|
|
|
|
static_cast<SCSIZE>(nSpIndex), nDelta));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rEntry.nField = nCol1;
|
2001-09-05 08:36:25 +00:00
|
|
|
if ( bSorted )
|
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
2007-09-27 12:53:45 +00:00
|
|
|
ScAddress aResultPos( nCol1, nRow1, nTab1);
|
|
|
|
if (LookupQueryWithCache( aResultPos, rParam))
|
2001-05-16 23:56:22 +00:00
|
|
|
{
|
2000-09-18 23:16:46 +00:00
|
|
|
ScBaseCell* pCell;
|
2007-09-27 12:53:45 +00:00
|
|
|
ScAddress aAdr( nSpIndex, aResultPos.Row(), nTab1 );
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( HasCellValueData( pCell = GetCell( aAdr ) ) )
|
|
|
|
PushDouble(GetCellValue( aAdr, pCell ));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
String aStr;
|
|
|
|
GetCellString(aStr, pCell);
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(WIN) && defined(MSC)
|
|
|
|
#pragma optimize("",off)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void ScInterpreter::ScSubTotal()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCountMin( nParamCount, 2 ) )
|
|
|
|
{
|
|
|
|
// Wir muessen den 1. Parameter tief aus dem Stack herausfischen!
|
|
|
|
const ScToken* p = pStack[ sp - nParamCount ];
|
|
|
|
PushTempToken( *p );
|
2003-03-26 17:07:02 +00:00
|
|
|
int nFunc = (int) ::rtl::math::approxFloor( GetDouble() );
|
2000-09-18 23:16:46 +00:00
|
|
|
if( nFunc < 1 || nFunc > 11 )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cPar = nParamCount - 1;
|
|
|
|
glSubTotal = TRUE;
|
|
|
|
switch( nFunc )
|
|
|
|
{
|
|
|
|
case SUBTOTAL_FUNC_AVE : ScAverage(); break;
|
|
|
|
case SUBTOTAL_FUNC_CNT : ScCount(); break;
|
|
|
|
case SUBTOTAL_FUNC_CNT2 : ScCount2(); break;
|
|
|
|
case SUBTOTAL_FUNC_MAX : ScMax(); break;
|
|
|
|
case SUBTOTAL_FUNC_MIN : ScMin(); break;
|
|
|
|
case SUBTOTAL_FUNC_PROD : ScProduct(); break;
|
|
|
|
case SUBTOTAL_FUNC_STD : ScStDev(); break;
|
|
|
|
case SUBTOTAL_FUNC_STDP : ScStDevP(); break;
|
|
|
|
case SUBTOTAL_FUNC_SUM : ScSum(); break;
|
|
|
|
case SUBTOTAL_FUNC_VAR : ScVar(); break;
|
|
|
|
case SUBTOTAL_FUNC_VARP : ScVarP(); break;
|
|
|
|
default : SetIllegalParameter(); break;
|
|
|
|
}
|
|
|
|
glSubTotal = FALSE;
|
|
|
|
}
|
|
|
|
// den abgefischten 1. Parameter entfernen
|
|
|
|
double nVal = GetDouble();
|
|
|
|
Pop();
|
|
|
|
PushDouble( nVal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if defined(WIN) && defined(MSC)
|
|
|
|
#pragma optimize("",on)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam,
|
2003-03-26 17:07:02 +00:00
|
|
|
BOOL& rMissingField )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
BOOL bRet = FALSE;
|
2003-03-26 17:07:02 +00:00
|
|
|
BOOL bAllowMissingField = FALSE;
|
|
|
|
if ( rMissingField )
|
|
|
|
{
|
|
|
|
bAllowMissingField = TRUE;
|
|
|
|
rMissingField = FALSE;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( GetByte() == 3 )
|
|
|
|
{
|
|
|
|
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nQCol1;
|
|
|
|
SCROW nQRow1;
|
|
|
|
SCTAB nQTab1;
|
|
|
|
SCCOL nQCol2;
|
|
|
|
SCROW nQRow2;
|
|
|
|
SCTAB nQTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopDoubleRef(nQCol1, nQRow1, nQTab1, nQCol2, nQRow2, nQTab2);
|
|
|
|
|
|
|
|
BOOL bByVal = TRUE;
|
2007-02-27 11:16:06 +00:00
|
|
|
double nVal = 0.0;
|
2000-09-18 23:16:46 +00:00
|
|
|
String aStr;
|
2003-03-26 17:07:02 +00:00
|
|
|
ScRange aMissingRange;
|
|
|
|
BOOL bRangeFake = FALSE;
|
2000-09-18 23:16:46 +00:00
|
|
|
switch (GetStackType())
|
|
|
|
{
|
|
|
|
case svDouble :
|
2003-03-26 17:07:02 +00:00
|
|
|
nVal = ::rtl::math::approxFloor( GetDouble() );
|
|
|
|
if ( bAllowMissingField && nVal == 0.0 )
|
|
|
|
rMissingField = TRUE; // fake missing parameter
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
case svString :
|
|
|
|
bByVal = FALSE;
|
|
|
|
aStr = GetString();
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
ScBaseCell* pCell = GetCell( aAdr );
|
|
|
|
if (HasCellValueData(pCell))
|
|
|
|
nVal = GetCellValue( aAdr, pCell );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bByVal = FALSE;
|
|
|
|
GetCellString(aStr, pCell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2003-03-26 17:07:02 +00:00
|
|
|
case svDoubleRef :
|
|
|
|
if ( bAllowMissingField )
|
|
|
|
{ // fake missing parameter for old SO compatibility
|
|
|
|
bRangeFake = TRUE;
|
|
|
|
PopDoubleRef( aMissingRange );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PopError();
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svMissing :
|
|
|
|
PopError();
|
|
|
|
if ( bAllowMissingField )
|
|
|
|
rMissingField = TRUE;
|
|
|
|
else
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
SetError( errIllegalParameter );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nDBCol1;
|
|
|
|
SCROW nDBRow1;
|
|
|
|
SCTAB nDBTab1;
|
|
|
|
SCCOL nDBCol2;
|
|
|
|
SCROW nDBRow2;
|
|
|
|
SCTAB nDBTab2;
|
2000-09-18 23:16:46 +00:00
|
|
|
PopDoubleRef(nDBCol1, nDBRow1, nDBTab1, nDBCol2, nDBRow2, nDBTab2);
|
|
|
|
|
2003-03-26 17:07:02 +00:00
|
|
|
if ( nGlobalError == 0 && bRangeFake )
|
|
|
|
{
|
|
|
|
// range parameter must match entire database range
|
|
|
|
if ( aMissingRange == ScRange( nDBCol1, nDBRow1, nDBTab1, nDBCol2,
|
|
|
|
nDBRow2, nDBTab2) )
|
|
|
|
rMissingField = TRUE;
|
|
|
|
else
|
|
|
|
SetError( errIllegalParameter );
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nGlobalError == 0)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nField = nDBCol1;
|
2000-09-18 23:16:46 +00:00
|
|
|
BOOL bFound = TRUE;
|
2003-03-26 17:07:02 +00:00
|
|
|
if ( rMissingField )
|
|
|
|
; // special case
|
|
|
|
else if ( bByVal )
|
|
|
|
{
|
|
|
|
if ( nVal <= 0 || nVal > (nDBCol2 - nDBCol1 + 1) )
|
|
|
|
bFound = FALSE;
|
|
|
|
else
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nField = Min(nDBCol2, (SCCOL)(nDBCol1 + (SCCOL)nVal - 1));
|
2003-03-26 17:07:02 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
bFound = FALSE;
|
|
|
|
String aCellStr;
|
2002-11-28 16:56:11 +00:00
|
|
|
ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 );
|
|
|
|
while (!bFound && (aLook.Col() <= nDBCol2))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2002-11-28 16:56:11 +00:00
|
|
|
ScBaseCell* pCell = GetCell( aLook );
|
|
|
|
GetCellString( aCellStr, pCell );
|
2001-08-06 09:21:02 +00:00
|
|
|
bFound = ScGlobal::pTransliteration->isEqual( aCellStr, aStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
if (!bFound)
|
2002-11-28 16:56:11 +00:00
|
|
|
aLook.IncCol();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2002-11-28 16:56:11 +00:00
|
|
|
nField = aLook.Col();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
if (bFound)
|
|
|
|
{
|
|
|
|
rParam.nCol1 = nDBCol1;
|
|
|
|
rParam.nRow1 = nDBRow1;
|
|
|
|
rParam.nCol2 = nDBCol2;
|
|
|
|
rParam.nRow2 = nDBRow2;
|
|
|
|
rParam.nTab = nDBTab1;
|
|
|
|
rParam.bHasHeader = TRUE;
|
|
|
|
rParam.bByRow = TRUE;
|
|
|
|
rParam.bInplace = TRUE;
|
|
|
|
rParam.bCaseSens = FALSE;
|
|
|
|
rParam.bRegExp = FALSE;
|
|
|
|
rParam.bDuplicate = TRUE;
|
|
|
|
if (pDok->CreateQueryParam(nQCol1, nQRow1, nQCol2, nQRow2, nQTab1, rParam))
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
// An allowed missing field parameter sets the result field
|
|
|
|
// to any of the query fields, just to be able to return
|
|
|
|
// some cell from the iterator.
|
|
|
|
if ( rMissingField )
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nField = static_cast<SCCOL>(rParam.GetEntry(0).nField);
|
2003-03-26 17:07:02 +00:00
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
rParam.nCol1 = nField;
|
|
|
|
rParam.nCol2 = nField;
|
|
|
|
rTab = nDBTab1;
|
|
|
|
bRet = TRUE;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nCount = rParam.GetEntryCount();
|
|
|
|
for ( SCSIZE i=0; i < nCount; i++ )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
ScQueryEntry& rEntry = rParam.GetEntry(i);
|
|
|
|
if ( rEntry.bDoQuery )
|
|
|
|
{
|
2005-12-14 14:06:41 +00:00
|
|
|
sal_uInt32 nIndex = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
rEntry.bQueryByString = !pFormatter->IsNumberFormat(
|
|
|
|
*rEntry.pStr, nIndex, rEntry.nVal );
|
|
|
|
if ( rEntry.bQueryByString && !rParam.bRegExp )
|
2001-05-15 20:06:49 +00:00
|
|
|
rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
break; // for
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::DBIterator( ScIterFunc eFunc )
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab1;
|
2000-09-18 23:16:46 +00:00
|
|
|
double nErg = 0.0;
|
|
|
|
double fMem = 0.0;
|
|
|
|
BOOL bNull = TRUE;
|
2003-03-26 17:07:02 +00:00
|
|
|
ULONG nCount = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
ScQueryParam aQueryParam;
|
2003-03-26 17:07:02 +00:00
|
|
|
BOOL bMissingField = FALSE;
|
|
|
|
if ( GetDBParams( nTab1, aQueryParam, bMissingField) )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
double nVal;
|
|
|
|
USHORT nErr;
|
|
|
|
ScQueryValueIterator aValIter(pDok, nTab1, aQueryParam);
|
|
|
|
if ( aValIter.GetFirst(nVal, nErr) && !nErr )
|
|
|
|
{
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifPRODUCT: nErg = 1; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
case ifMAX: nErg = -MAXDOUBLE; break;
|
2000-09-18 23:16:46 +00:00
|
|
|
case ifMIN: nErg = MAXDOUBLE; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifAVERAGE:
|
|
|
|
case ifSUM:
|
|
|
|
if ( bNull && nVal != 0.0 )
|
|
|
|
{
|
|
|
|
bNull = FALSE;
|
|
|
|
fMem = nVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nErg += nVal;
|
|
|
|
break;
|
|
|
|
case ifSUMSQ: nErg += nVal * nVal; break;
|
|
|
|
case ifPRODUCT: nErg *= nVal; break;
|
|
|
|
case ifMAX: if( nVal > nErg ) nErg = nVal; break;
|
|
|
|
case ifMIN: if( nVal < nErg ) nErg = nVal; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while ( aValIter.GetNext(nVal, nErr) && !nErr );
|
|
|
|
}
|
|
|
|
SetError(nErr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
switch( eFunc )
|
|
|
|
{
|
|
|
|
case ifCOUNT: nErg = nCount; break;
|
2003-03-26 17:07:02 +00:00
|
|
|
case ifSUM: nErg = ::rtl::math::approxAdd( nErg, fMem ); break;
|
|
|
|
case ifAVERAGE: nErg = ::rtl::math::approxAdd( nErg, fMem ) / nCount; break;
|
2005-03-29 12:32:52 +00:00
|
|
|
default: ; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
PushDouble( nErg );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBSum()
|
|
|
|
{
|
|
|
|
DBIterator( ifSUM );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBCount()
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab;
|
2003-03-26 17:07:02 +00:00
|
|
|
ScQueryParam aQueryParam;
|
|
|
|
BOOL bMissingField = TRUE;
|
|
|
|
if ( GetDBParams( nTab, aQueryParam, bMissingField) )
|
|
|
|
{
|
|
|
|
ULONG nCount = 0;
|
|
|
|
if ( bMissingField )
|
|
|
|
{ // count all matching records
|
|
|
|
// TODO: currently the QueryIterators only return cell pointers of
|
|
|
|
// existing cells, so if a query matches an empty cell there's
|
|
|
|
// nothing returned, and therefor not counted!
|
|
|
|
// Since this has ever been the case and this code here only came
|
|
|
|
// into existance to fix #i6899 and it never worked before we'll
|
|
|
|
// have to live with it until we reimplement the iterators to also
|
|
|
|
// return empty cells, which would mean to adapt all callers of
|
|
|
|
// iterators.
|
|
|
|
ScQueryCellIterator aCellIter( pDok, nTab, aQueryParam);
|
|
|
|
if ( aCellIter.GetFirst() )
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
} while ( aCellIter.GetNext() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // count only matching records with a value in the "result" field
|
|
|
|
double nVal;
|
|
|
|
USHORT nErr = 0;
|
|
|
|
ScQueryValueIterator aValIter( pDok, nTab, aQueryParam);
|
|
|
|
if ( aValIter.GetFirst( nVal, nErr) && !nErr )
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
} while ( aValIter.GetNext( nVal, nErr) && !nErr );
|
|
|
|
}
|
|
|
|
SetError( nErr );
|
|
|
|
}
|
|
|
|
PushDouble( nCount );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBCount2()
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab;
|
2000-09-18 23:16:46 +00:00
|
|
|
ScQueryParam aQueryParam;
|
2004-06-03 11:34:56 +00:00
|
|
|
BOOL bMissingField = TRUE;
|
2003-03-26 17:07:02 +00:00
|
|
|
if (GetDBParams( nTab, aQueryParam, bMissingField))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
ULONG nCount = 0;
|
|
|
|
ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam);
|
|
|
|
if ( aCellIter.GetFirst() )
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
} while ( aCellIter.GetNext() );
|
|
|
|
}
|
|
|
|
PushDouble(nCount);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBAverage()
|
|
|
|
{
|
|
|
|
DBIterator( ifAVERAGE );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBMax()
|
|
|
|
{
|
|
|
|
DBIterator( ifMAX );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBMin()
|
|
|
|
{
|
|
|
|
DBIterator( ifMIN );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBProduct()
|
|
|
|
{
|
|
|
|
DBIterator( ifPRODUCT );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-08 16:13:47 +00:00
|
|
|
void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-11-15 15:35:15 +00:00
|
|
|
std::vector<double> values;
|
|
|
|
double vSum = 0.0;
|
|
|
|
double vMean = 0.0;
|
|
|
|
|
2002-12-08 16:13:47 +00:00
|
|
|
rValCount = 0.0;
|
|
|
|
double fSum = 0.0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab;
|
2000-09-18 23:16:46 +00:00
|
|
|
ScQueryParam aQueryParam;
|
2003-03-26 17:07:02 +00:00
|
|
|
BOOL bMissingField = FALSE;
|
|
|
|
if (GetDBParams( nTab, aQueryParam, bMissingField))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2002-12-08 16:13:47 +00:00
|
|
|
double fVal;
|
2000-09-18 23:16:46 +00:00
|
|
|
USHORT nErr;
|
|
|
|
ScQueryValueIterator aValIter(pDok, nTab, aQueryParam);
|
|
|
|
if (aValIter.GetFirst(fVal, nErr) && !nErr)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2002-12-08 16:13:47 +00:00
|
|
|
rValCount++;
|
2004-11-15 15:35:15 +00:00
|
|
|
values.push_back(fVal);
|
2000-09-18 23:16:46 +00:00
|
|
|
fSum += fVal;
|
|
|
|
}
|
|
|
|
while ((nErr == 0) && aValIter.GetNext(fVal, nErr));
|
|
|
|
}
|
|
|
|
SetError(nErr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
2004-11-15 15:35:15 +00:00
|
|
|
|
|
|
|
vMean = fSum / values.size();
|
|
|
|
|
2005-03-29 12:32:52 +00:00
|
|
|
for (size_t i = 0; i < values.size(); i++)
|
2004-11-15 15:35:15 +00:00
|
|
|
vSum += (values[i] - vMean) * (values[i] - vMean);
|
|
|
|
|
|
|
|
rVal = vSum;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBStdDev()
|
|
|
|
{
|
2002-12-08 16:13:47 +00:00
|
|
|
double fVal, fCount;
|
|
|
|
GetDBStVarParams( fVal, fCount );
|
|
|
|
PushDouble( sqrt(fVal/(fCount-1)));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBStdDevP()
|
|
|
|
{
|
2002-12-08 16:13:47 +00:00
|
|
|
double fVal, fCount;
|
|
|
|
GetDBStVarParams( fVal, fCount );
|
|
|
|
PushDouble( sqrt(fVal/fCount));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBVar()
|
|
|
|
{
|
2002-12-08 16:13:47 +00:00
|
|
|
double fVal, fCount;
|
|
|
|
GetDBStVarParams( fVal, fCount );
|
|
|
|
PushDouble(fVal/(fCount-1));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScDBVarP()
|
|
|
|
{
|
2002-12-08 16:13:47 +00:00
|
|
|
double fVal, fCount;
|
|
|
|
GetDBStVarParams( fVal, fCount );
|
|
|
|
PushDouble(fVal/fCount);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-18 11:22:33 +00:00
|
|
|
#if 0
|
|
|
|
// This could be the code to handle Excel notation. However, we don't offer it
|
|
|
|
// (yet) at UI level and documents must not use it, as it isn't clarified how
|
|
|
|
// to handle interoperability issues.
|
|
|
|
|
|
|
|
void ScInterpreter::ScIndirectXL()
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
2006-10-18 11:22:33 +00:00
|
|
|
ScAddress::Convention conv = ScAddress::CONV_XL_A1;
|
|
|
|
|
|
|
|
if (nParamCount == 2 && 0. == GetDouble())
|
|
|
|
conv = ScAddress::CONV_XL_R1C1;
|
|
|
|
|
|
|
|
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
|
2008-01-29 07:02:08 +00:00
|
|
|
{
|
2006-10-18 11:22:33 +00:00
|
|
|
ScAddress::Details const details( conv, aPos );
|
|
|
|
SCTAB nTab = aPos.Tab();
|
|
|
|
String sRefStr( GetString() );
|
|
|
|
ScRefAddress aRefAd, aRefAd2;
|
|
|
|
if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2, details ) )
|
|
|
|
PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
|
|
|
|
aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
|
|
|
|
else if ( ConvertSingleRef ( pDok, sRefStr, nTab, aRefAd, details ) )
|
|
|
|
PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2008-01-29 07:02:08 +00:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
ScRangeName* pNames = pDok->GetRangeName();
|
|
|
|
if (!pNames)
|
|
|
|
break;
|
|
|
|
|
|
|
|
USHORT nPos = 0;
|
|
|
|
if (!pNames->SearchName(sRefStr, nPos))
|
|
|
|
break;
|
|
|
|
|
|
|
|
ScRangeData* rData = (*pNames)[nPos];
|
|
|
|
if (!rData)
|
|
|
|
break;
|
|
|
|
|
|
|
|
rData->ValidateTabRefs();
|
|
|
|
|
|
|
|
ScRange aRange;
|
|
|
|
if (!rData->IsReference(aRange, ScAddress(aPos.Tab(), 0, 0)))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( aRange.aStart == aRange.aEnd )
|
|
|
|
PushSingleRef(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab());
|
|
|
|
else
|
|
|
|
PushDoubleRef(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
|
|
|
|
aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab());
|
|
|
|
|
|
|
|
// success!
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (false);
|
|
|
|
|
2006-10-18 11:22:33 +00:00
|
|
|
SetIllegalArgument();
|
2008-01-29 07:02:08 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2006-10-18 11:22:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // ScIndirectXL
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIndirect()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( MustHaveParamCount( nParamCount, 1 ) )
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab = aPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
String sRefStr( GetString() );
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
ScRefAddress aRefAd, aRefAd2;
|
2006-10-18 11:22:33 +00:00
|
|
|
/* Always OOO format which does not require a position */
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2 ) )
|
|
|
|
PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
|
|
|
|
aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
|
|
|
|
else if ( ConvertSingleRef( pDok, sRefStr, nTab, aRefAd ) )
|
|
|
|
PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
2008-01-29 07:02:08 +00:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
ScRangeName* pNames = pDok->GetRangeName();
|
|
|
|
if (!pNames)
|
|
|
|
break;
|
|
|
|
|
|
|
|
USHORT nPos = 0;
|
|
|
|
if (!pNames->SearchName(sRefStr, nPos))
|
|
|
|
break;
|
|
|
|
|
|
|
|
ScRangeData* rData = (*pNames)[nPos];
|
|
|
|
if (!rData)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// we need this in order to obtain good range
|
|
|
|
rData->ValidateTabRefs();
|
|
|
|
|
|
|
|
ScRange aRange;
|
|
|
|
if (!rData->IsReference(aRange, aPos))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( aRange.aStart == aRange.aEnd )
|
|
|
|
PushSingleRef(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab());
|
|
|
|
else
|
|
|
|
PushDoubleRef(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
|
|
|
|
aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab());
|
|
|
|
|
|
|
|
// success!
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (false);
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
SetIllegalArgument();
|
2008-01-29 07:02:08 +00:00
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-18 11:22:33 +00:00
|
|
|
void ScInterpreter::ScAddressFunc()
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 2, 4 ) )
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
String sTabStr;
|
2000-09-18 23:16:46 +00:00
|
|
|
USHORT nAbs = 1;
|
|
|
|
if (nParamCount == 4)
|
|
|
|
sTabStr = GetString();
|
|
|
|
if (nParamCount >= 3)
|
2003-03-26 17:07:02 +00:00
|
|
|
nAbs = (USHORT) ::rtl::math::approxFloor(GetDouble());
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
|
|
|
|
SCROW nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nCol < 1 || nCol > MAXCOL + 1 || nRow < 1 || nRow > MAXROW + 1)
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nRow--;
|
|
|
|
nCol--;
|
|
|
|
}
|
|
|
|
String aRefStr;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
ScAddress aAdr( nCol, nRow, 0);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nAbs == 4)
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
aRefStr = aAdr.GetColRowString();
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
aRefStr = aAdr.GetColRowString(TRUE);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nAbs == 2)
|
|
|
|
aRefStr.EraseLeadingChars('$');
|
|
|
|
else if (nAbs == 3)
|
|
|
|
aRefStr.Erase(aRefStr.Search('$',1),1);
|
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
if ( sTabStr.Len() )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
aRefStr.Insert('.',0);
|
|
|
|
aRefStr.Insert(sTabStr,0);
|
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aRefStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-18 11:22:33 +00:00
|
|
|
#if 0
|
|
|
|
// This could be the code to handle Excel notation. However, we don't offer it
|
|
|
|
// (yet) at UI level and documents must not use it, as it isn't clarified how
|
|
|
|
// to handle interoperability issues.
|
|
|
|
|
|
|
|
void ScInterpreter::ScAddressXL()
|
|
|
|
{
|
|
|
|
String sTabStr;
|
|
|
|
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if( !MustHaveParamCount( nParamCount, 2, 5 ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( nParamCount >= 5 )
|
|
|
|
sTabStr = GetString();
|
|
|
|
|
|
|
|
ScAddress::Convention eConv = ScAddress::CONV_XL_A1; // default
|
|
|
|
if( nParamCount >= 4 && (USHORT) ::rtl::math::approxFloor(GetDouble()) == 0 )
|
|
|
|
eConv = ScAddress::CONV_XL_R1C1;
|
|
|
|
|
|
|
|
USHORT nFlags = SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE; // default
|
|
|
|
if( nParamCount >= 3 )
|
|
|
|
{
|
|
|
|
USHORT n = (USHORT) ::rtl::math::approxFloor(GetDouble());
|
|
|
|
switch ( n )
|
|
|
|
{
|
|
|
|
default :
|
|
|
|
SetNoValue();
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
case 1 : break; // default
|
|
|
|
case 6:
|
|
|
|
case 2 : nFlags = SCA_ROW_ABSOLUTE; break;
|
|
|
|
case 7:
|
|
|
|
case 3 : nFlags = SCA_COL_ABSOLUTE; break;
|
|
|
|
case 8:
|
|
|
|
case 4 : nFlags = 0; break; // both relative
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nFlags |= SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
|
|
|
|
|
|
|
|
SCCOL nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
|
|
|
|
SCROW nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
|
|
|
|
if( eConv == ScAddress::CONV_XL_R1C1 )
|
|
|
|
{
|
|
|
|
// YUCK! The XL interface actually treats rel R1C1 refs differently
|
|
|
|
// than A1
|
|
|
|
if( !(nFlags & SCA_COL_ABSOLUTE) )
|
|
|
|
nCol += aPos.Col() + 1;
|
|
|
|
if( !(nFlags & SCA_ROW_ABSOLUTE) )
|
|
|
|
nRow += aPos.Row() + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nCol < 1 || nCol > MAXCOL + 1 || nRow < 1 || nRow > MAXROW + 1 )
|
|
|
|
{
|
|
|
|
SetNoValue();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String aRefStr;
|
|
|
|
const ScAddress::Details aDetails( eConv, aPos );
|
|
|
|
const ScAddress aAdr( nCol-1, nRow-1, 0);
|
|
|
|
aAdr.Format( aRefStr, nFlags, pDok, aDetails );
|
|
|
|
|
|
|
|
if( nParamCount >= 5 )
|
|
|
|
{ // TODO Do we need to quote this ?
|
|
|
|
sTabStr += static_cast<sal_Unicode>('!');
|
|
|
|
sTabStr += aRefStr;
|
|
|
|
PushString( sTabStr );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushString( aRefStr );
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // ScAddressXL()
|
|
|
|
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
void ScInterpreter::ScOffset()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 3, 5 ) )
|
|
|
|
{
|
2006-12-19 12:17:39 +00:00
|
|
|
long nColNew = -1, nRowNew = -1, nColPlus, nRowPlus;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nParamCount == 5)
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nColNew = (long) ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nParamCount >= 4)
|
2006-12-19 12:17:39 +00:00
|
|
|
nRowNew = (long) ::rtl::math::approxFloor(GetDoubleWithDefault( -1.0 ));
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nColPlus = (long) ::rtl::math::approxFloor(GetDouble());
|
|
|
|
nRowPlus = (long) ::rtl::math::approxFloor(GetDouble());
|
|
|
|
SCCOL nCol1;
|
|
|
|
SCROW nRow1;
|
|
|
|
SCTAB nTab1;
|
|
|
|
SCCOL nCol2;
|
|
|
|
SCROW nRow2;
|
|
|
|
SCTAB nTab2;
|
2006-12-19 12:17:39 +00:00
|
|
|
if (nColNew == 0 || nRowNew == 0)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (GetStackType() == svSingleRef)
|
|
|
|
{
|
|
|
|
PopSingleRef(nCol1, nRow1, nTab1);
|
2006-12-19 12:17:39 +00:00
|
|
|
if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nCol1 = (SCCOL)((long) nCol1 + nColPlus);
|
|
|
|
nRow1 = (SCROW)((long) nRow1 + nRowPlus);
|
|
|
|
if (!ValidCol(nCol1) || !ValidRow(nRow1))
|
2000-09-18 23:16:46 +00:00
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
PushSingleRef(nCol1, nRow1, nTab1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-12-19 12:17:39 +00:00
|
|
|
if (nColNew < 0)
|
2000-09-18 23:16:46 +00:00
|
|
|
nColNew = 1;
|
2006-12-19 12:17:39 +00:00
|
|
|
if (nRowNew < 0)
|
|
|
|
nRowNew = 1;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nCol1 = (SCCOL)((long)nCol1+nColPlus); // ! nCol1 wird veraendert!
|
|
|
|
nRow1 = (SCROW)((long)nRow1+nRowPlus);
|
|
|
|
nCol2 = (SCCOL)((long)nCol1+nColNew-1);
|
|
|
|
nRow2 = (SCROW)((long)nRow1+nRowNew-1);
|
|
|
|
if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
|
|
|
|
!ValidCol(nCol2) || !ValidRow(nRow2))
|
2000-09-18 23:16:46 +00:00
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
2006-12-19 12:17:39 +00:00
|
|
|
if (nColNew < 0)
|
2000-09-18 23:16:46 +00:00
|
|
|
nColNew = nCol2 - nCol1 + 1;
|
2006-12-19 12:17:39 +00:00
|
|
|
if (nRowNew < 0)
|
2000-09-18 23:16:46 +00:00
|
|
|
nRowNew = nRow2 - nRow1 + 1;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nCol1 = (SCCOL)((long)nCol1+nColPlus);
|
|
|
|
nRow1 = (SCROW)((long)nRow1+nRowPlus);
|
|
|
|
nCol2 = (SCCOL)((long)nCol1+nColNew-1);
|
|
|
|
nRow2 = (SCROW)((long)nRow1+nRowNew-1);
|
|
|
|
if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
|
|
|
|
!ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
|
2000-09-18 23:16:46 +00:00
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScIndex()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 1, 4 ) )
|
|
|
|
{
|
|
|
|
short nBereich, nMaxAnz, nCount;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCCOL nCol;
|
|
|
|
SCROW nRow;
|
2000-09-18 23:16:46 +00:00
|
|
|
if (nParamCount == 4)
|
2003-03-26 17:07:02 +00:00
|
|
|
nBereich = (short) ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
nBereich = 1;
|
|
|
|
if (nParamCount >= 3)
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
nCol = 0;
|
|
|
|
if (nParamCount >= 2)
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
nRow = 0;
|
|
|
|
if (GetStackType() == svByte) // vorher MultiSelektion?
|
|
|
|
nMaxAnz = (short) PopByte();
|
|
|
|
else // sonst Einzelselektion
|
|
|
|
nMaxAnz = 1;
|
2004-10-22 06:58:58 +00:00
|
|
|
if (nBereich > nMaxAnz || nBereich < 1 || nCol < 0 || nRow < 0)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (GetStackType() == svMatrix)
|
|
|
|
{
|
|
|
|
if (nBereich != 1)
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
USHORT nOldSp = sp;
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pMat = GetMatrix();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nC, nR;
|
2000-09-18 23:16:46 +00:00
|
|
|
pMat->GetDimensions(nC, nR);
|
2006-08-04 10:34:02 +00:00
|
|
|
// Access one element of a vector independent of col/row
|
|
|
|
// orientation?
|
|
|
|
bool bVector = ((nCol == 0 || nRow == 0) && (nC == 1 || nR == 1));
|
|
|
|
SCSIZE nElement = ::std::max( static_cast<SCSIZE>(nCol),
|
|
|
|
static_cast<SCSIZE>(nRow));
|
|
|
|
if (nC == 0 || nR == 0 ||
|
|
|
|
(!bVector && (static_cast<SCSIZE>(nCol) > nC ||
|
|
|
|
static_cast<SCSIZE>(nRow) > nR)) ||
|
|
|
|
(bVector && nElement > nC * nR))
|
2000-09-18 23:16:46 +00:00
|
|
|
SetIllegalArgument();
|
|
|
|
else if (nCol == 0 && nRow == 0)
|
|
|
|
sp = nOldSp;
|
2006-08-04 10:34:02 +00:00
|
|
|
else if (bVector)
|
|
|
|
{
|
|
|
|
--nElement;
|
|
|
|
if (pMat->IsString( nElement))
|
|
|
|
PushString( pMat->GetString( nElement));
|
|
|
|
else
|
|
|
|
PushDouble( pMat->GetDouble( nElement));
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
else if (nRow == 0)
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pResMat = GetNewMat(nC, 1);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pResMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nColMinus1 = static_cast<SCSIZE>(nCol - 1);
|
|
|
|
for (SCSIZE i = 0; i < nC; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
if (!pMat->IsString(i, nColMinus1))
|
|
|
|
pResMat->PutDouble(pMat->GetDouble(i,
|
|
|
|
nColMinus1), i, 0);
|
|
|
|
else
|
|
|
|
pResMat->PutString(pMat->GetString(i,
|
|
|
|
nColMinus1), i, 0);
|
|
|
|
PushMatrix(pResMat);
|
|
|
|
}
|
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
PushError();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else if (nCol == 0)
|
|
|
|
{
|
2004-03-08 10:47:52 +00:00
|
|
|
ScMatrixRef pResMat = GetNewMat(1, nR);
|
2000-09-18 23:16:46 +00:00
|
|
|
if (pResMat)
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCSIZE nRowMinus1 = static_cast<SCSIZE>(nRow - 1);
|
|
|
|
for (SCSIZE i = 0; i < nR; i++)
|
2000-09-18 23:16:46 +00:00
|
|
|
if (!pMat->IsString(nRowMinus1, i))
|
|
|
|
pResMat->PutDouble(pMat->GetDouble(nRowMinus1,
|
2001-04-27 21:44:26 +00:00
|
|
|
i), i);
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
pResMat->PutString(pMat->GetString(nRowMinus1,
|
2001-04-27 21:44:26 +00:00
|
|
|
i), i);
|
2000-09-18 23:16:46 +00:00
|
|
|
PushMatrix(pResMat);
|
|
|
|
}
|
|
|
|
else
|
2004-03-08 10:47:52 +00:00
|
|
|
PushError();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
if (!pMat->IsString( static_cast<SCSIZE>(nCol-1),
|
|
|
|
static_cast<SCSIZE>(nRow-1)))
|
|
|
|
PushDouble( pMat->GetDouble(
|
|
|
|
static_cast<SCSIZE>(nCol-1),
|
|
|
|
static_cast<SCSIZE>(nRow-1)));
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
PushString( pMat->GetString(
|
|
|
|
static_cast<SCSIZE>(nCol-1),
|
|
|
|
static_cast<SCSIZE>(nRow-1)));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GetStackType() == svSingleRef || GetStackType() == svDoubleRef)
|
|
|
|
{
|
|
|
|
ScAddress aDummyAdr;
|
|
|
|
ScRange aDummyRange;
|
2007-02-27 11:16:06 +00:00
|
|
|
SCCOL nCol1 = 0;
|
|
|
|
SCROW nRow1 = 0;
|
|
|
|
SCTAB nTab1 = 0;
|
|
|
|
SCCOL nCol2 = 0;
|
|
|
|
SCROW nRow2 = 0;
|
INTEGRATION: CWS rowlimit (1.26.16); FILE MERGED
2004/03/25 21:35:55 er 1.26.16.6: #i1967# use ValidCol,ValidRow,ValidTab
2004/03/18 10:22:41 er 1.26.16.5: #i1967# type correctness
2004/03/15 17:35:32 er 1.26.16.4: RESYNC: (1.26-1.27); FILE MERGED
2004/02/04 11:28:05 er 1.26.16.3: #i1967# replace ScTripel,ScRefTripel with ScAddress,ScRefAddress; get rid of some warnings
2004/01/13 17:19:38 er 1.26.16.2: #i1967# SCCOL,SCROW,SCTAB replace USHORT; SCsCOL,SCsROW,SCsTAB replace short
2003/12/19 20:16:19 er 1.26.16.1: #i1967# SCCOL,SCROW,SCTAB replace USHORT
2004-06-04 09:36:24 +00:00
|
|
|
SCTAB nTab2 = MAXTAB+1;
|
2000-09-18 23:16:46 +00:00
|
|
|
nCount = nMaxAnz; // Refs liegen umgekehrt auf dem Stack!
|
|
|
|
while (nCount > nBereich && !nGlobalError) // erste Refs weg
|
|
|
|
{
|
|
|
|
nCount--;
|
|
|
|
if ( GetStackType() == svSingleRef )
|
|
|
|
PopSingleRef( aDummyAdr );
|
|
|
|
else if ( GetStackType() == svDoubleRef )
|
|
|
|
PopDoubleRef( aDummyRange );
|
|
|
|
}
|
|
|
|
while (nCount > nBereich-1 && !nGlobalError) // richtigen Teilbezug
|
|
|
|
{
|
|
|
|
nCount--;
|
|
|
|
if (GetStackType() == svSingleRef)
|
|
|
|
PopSingleRef(nCol1, nRow1, nTab1);
|
|
|
|
else if (GetStackType() == svDoubleRef)
|
|
|
|
PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
|
|
|
|
}
|
|
|
|
while (nCount > 0 && !nGlobalError) // restliche Refs weg
|
|
|
|
{
|
|
|
|
nCount--;
|
|
|
|
if ( GetStackType() == svSingleRef )
|
|
|
|
PopSingleRef( aDummyAdr );
|
|
|
|
else if ( GetStackType() == svDoubleRef )
|
|
|
|
PopDoubleRef( aDummyRange );
|
|
|
|
}
|
|
|
|
if (nTab2 == MAXTAB+1) // SingleRef
|
|
|
|
{
|
|
|
|
if (nCol > 1 || nRow > 1)
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
|
|
|
PushSingleRef(nCol1, nRow1, nTab1);
|
|
|
|
}
|
|
|
|
else // DoubleRef
|
|
|
|
{
|
|
|
|
if ( nTab1 != nTab2 ||
|
|
|
|
(nCol > 0 && nCol1+nCol-1 > nCol2) ||
|
|
|
|
(nRow > 0 && nRow1+nRow-1 > nRow2) )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else if (nCol == 0 && nRow == 0)
|
|
|
|
{
|
|
|
|
if ( nCol1 == nCol2 && nRow1 == nRow2 )
|
|
|
|
PushSingleRef( nCol1, nRow1, nTab1 );
|
|
|
|
else
|
|
|
|
PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab1 );
|
|
|
|
}
|
|
|
|
else if (nRow == 0)
|
|
|
|
{
|
|
|
|
if ( nRow1 == nRow2 )
|
|
|
|
PushSingleRef( nCol1+nCol-1, nRow1, nTab1 );
|
|
|
|
else
|
|
|
|
PushDoubleRef( nCol1+nCol-1, nRow1, nTab1,
|
|
|
|
nCol1+nCol-1, nRow2, nTab1 );
|
|
|
|
}
|
|
|
|
else if (nCol == 0)
|
|
|
|
{
|
|
|
|
if ( nCol1 == nCol2 )
|
|
|
|
PushSingleRef( nCol1, nRow1+nRow-1, nTab1 );
|
|
|
|
else
|
|
|
|
PushDoubleRef(nCol1, nRow1+nRow-1, nTab1,
|
|
|
|
nCol2, nRow1+nRow-1, nTab1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PushSingleRef(nCol1+nCol-1, nRow1+nRow-1, nTab1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScMultiArea()
|
|
|
|
{
|
|
|
|
// Hier ist nichts zu tun, der paramCount von ScMultiSelektion
|
|
|
|
// bleibt auf dem Stack !!
|
|
|
|
// Den muessen die nachfolgenden Funktionen (Index ...) wegraeumen !!
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScAreas()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
double fMaxAnz = 1.0;
|
|
|
|
ScAddress aDummyAdr;
|
|
|
|
ScRange aDummyRange;
|
|
|
|
for (USHORT i = 0; i < nParamCount && nGlobalError == 0; i++)
|
|
|
|
{
|
|
|
|
if (GetStackType() == svByte) // vorher MultiSelektion?
|
|
|
|
{
|
|
|
|
double fCount = 0.0;
|
|
|
|
fMaxAnz = (double) GetByte();
|
|
|
|
while (fCount < fMaxAnz && !nGlobalError) // mehrere Refs
|
|
|
|
{
|
|
|
|
fCount++;
|
|
|
|
if (GetStackType() == svSingleRef)
|
|
|
|
PopSingleRef( aDummyAdr );
|
|
|
|
else if (GetStackType() == svDoubleRef)
|
|
|
|
PopDoubleRef( aDummyRange );
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GetStackType() == svSingleRef)
|
|
|
|
PopSingleRef( aDummyAdr );
|
|
|
|
else if (GetStackType() == svDoubleRef)
|
|
|
|
PopDoubleRef( aDummyRange );
|
|
|
|
else
|
|
|
|
SetIllegalParameter();
|
|
|
|
}
|
|
|
|
if (nGlobalError == 0)
|
|
|
|
PushDouble((double)nParamCount + fMaxAnz - 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScCurrency()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
String aStr;
|
2000-09-18 23:16:46 +00:00
|
|
|
double fDec;
|
|
|
|
if (nParamCount == 2)
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
fDec = ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
if (fDec < -15.0 || fDec > 15.0)
|
|
|
|
{
|
|
|
|
SetIllegalArgument();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fDec = 2.0;
|
|
|
|
double fVal = GetDouble();
|
|
|
|
double fFac;
|
|
|
|
if ( fDec != 0.0 )
|
|
|
|
fFac = pow( (double)10, fDec );
|
|
|
|
else
|
|
|
|
fFac = 1.0;
|
|
|
|
if (fVal < 0.0)
|
|
|
|
fVal = ceil(fVal*fFac-0.5)/fFac;
|
|
|
|
else
|
|
|
|
fVal = floor(fVal*fFac+0.5)/fFac;
|
|
|
|
Color* pColor = NULL;
|
|
|
|
if ( fDec < 0.0 )
|
|
|
|
fDec = 0.0;
|
|
|
|
ULONG nIndex = pFormatter->GetStandardFormat(
|
|
|
|
NUMBERFORMAT_CURRENCY,
|
|
|
|
ScGlobal::eLnge);
|
|
|
|
if ( (USHORT) fDec != pFormatter->GetFormatPrecision( nIndex ) )
|
|
|
|
{
|
|
|
|
String sFormatString;
|
|
|
|
pFormatter->GenerateFormat(sFormatString,
|
|
|
|
nIndex,
|
|
|
|
ScGlobal::eLnge,
|
|
|
|
TRUE, // mit Tausenderpunkt
|
|
|
|
FALSE, // nicht rot
|
|
|
|
(USHORT) fDec,// Nachkommastellen
|
|
|
|
1); // 1 Vorkommanull
|
|
|
|
if (!pFormatter->GetPreviewString(sFormatString,
|
|
|
|
fVal,
|
2001-02-21 17:39:37 +00:00
|
|
|
aStr,
|
2000-09-18 23:16:46 +00:00
|
|
|
&pColor,
|
|
|
|
ScGlobal::eLnge))
|
|
|
|
SetError(errIllegalParameter);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
pFormatter->GetOutputString(fVal, nIndex, aStr, &pColor);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScReplace()
|
|
|
|
{
|
|
|
|
if ( MustHaveParamCount( GetByte(), 4 ) )
|
|
|
|
{
|
|
|
|
String aNewStr( GetString() );
|
|
|
|
short nCount = (short) GetDouble();
|
|
|
|
short nPos = (short) GetDouble();
|
|
|
|
String aOldStr( GetString() );
|
|
|
|
if( nPos < 1 || nCount < 1 )
|
|
|
|
SetIllegalArgument();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aOldStr.Erase( nPos-1, nCount );
|
2001-02-21 17:39:37 +00:00
|
|
|
if ( CheckStringResultLen( aOldStr, aNewStr ) )
|
|
|
|
aOldStr.Insert( aNewStr, nPos-1 );
|
|
|
|
PushString( aOldStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScFixed()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 1, 3 ) )
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
String aStr;
|
2000-09-18 23:16:46 +00:00
|
|
|
double fDec;
|
|
|
|
BOOL bThousand;
|
|
|
|
if (nParamCount == 3)
|
|
|
|
bThousand = !GetBool(); // Param TRUE: keine Tausenderpunkte
|
|
|
|
else
|
|
|
|
bThousand = TRUE;
|
|
|
|
if (nParamCount >= 2)
|
|
|
|
{
|
2006-12-19 12:17:39 +00:00
|
|
|
fDec = ::rtl::math::approxFloor(GetDoubleWithDefault( 2.0 ));
|
2000-09-18 23:16:46 +00:00
|
|
|
if (fDec < -15.0 || fDec > 15.0)
|
|
|
|
{
|
|
|
|
SetIllegalArgument();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fDec = 2.0;
|
|
|
|
double fVal = GetDouble();
|
|
|
|
double fFac;
|
|
|
|
if ( fDec != 0.0 )
|
|
|
|
fFac = pow( (double)10, fDec );
|
|
|
|
else
|
|
|
|
fFac = 1.0;
|
|
|
|
if (fVal < 0.0)
|
|
|
|
fVal = ceil(fVal*fFac-0.5)/fFac;
|
|
|
|
else
|
|
|
|
fVal = floor(fVal*fFac+0.5)/fFac;
|
|
|
|
Color* pColor = NULL;
|
|
|
|
String sFormatString;
|
|
|
|
if (fDec < 0.0)
|
|
|
|
fDec = 0.0;
|
|
|
|
ULONG nIndex = pFormatter->GetStandardFormat(
|
|
|
|
NUMBERFORMAT_NUMBER,
|
|
|
|
ScGlobal::eLnge);
|
|
|
|
pFormatter->GenerateFormat(sFormatString,
|
|
|
|
nIndex,
|
|
|
|
ScGlobal::eLnge,
|
|
|
|
bThousand, // mit Tausenderpunkt
|
|
|
|
FALSE, // nicht rot
|
|
|
|
(USHORT) fDec,// Nachkommastellen
|
|
|
|
1); // 1 Vorkommanull
|
|
|
|
if (!pFormatter->GetPreviewString(sFormatString,
|
|
|
|
fVal,
|
2001-02-21 17:39:37 +00:00
|
|
|
aStr,
|
2000-09-18 23:16:46 +00:00
|
|
|
&pColor,
|
|
|
|
ScGlobal::eLnge))
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScFind()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
|
|
|
|
{
|
|
|
|
double fAnz;
|
|
|
|
if (nParamCount == 3)
|
|
|
|
fAnz = GetDouble();
|
|
|
|
else
|
|
|
|
fAnz = 1.0;
|
|
|
|
String sStr = GetString();
|
|
|
|
if( fAnz < 1.0 || fAnz > (double) sStr.Len() )
|
|
|
|
SetNoValue();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xub_StrLen nPos = sStr.Search( GetString(), (xub_StrLen) fAnz - 1 );
|
|
|
|
if (nPos == STRING_NOTFOUND)
|
|
|
|
SetNoValue();
|
|
|
|
else
|
|
|
|
PushDouble((double)(nPos + 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScExact()
|
|
|
|
{
|
|
|
|
nFuncFmtType = NUMBERFORMAT_LOGICAL;
|
|
|
|
if ( MustHaveParamCount( GetByte(), 2 ) )
|
|
|
|
{
|
|
|
|
String s1( GetString() );
|
|
|
|
String s2( GetString() );
|
|
|
|
PushInt( s1 == s2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScLeft()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
|
|
|
|
{
|
|
|
|
xub_StrLen n;
|
|
|
|
if (nParamCount == 2)
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
double nVal = ::rtl::math::approxFloor(GetDouble());
|
2001-02-21 17:39:37 +00:00
|
|
|
if ( nVal < 0.0 || nVal > STRING_MAXLEN )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
n = (xub_StrLen) nVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
n = 1;
|
|
|
|
String aStr( GetString() );
|
|
|
|
aStr.Erase( n );
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScRight()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
|
|
|
|
{
|
|
|
|
xub_StrLen n;
|
|
|
|
if (nParamCount == 2)
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
double nVal = ::rtl::math::approxFloor(GetDouble());
|
2001-02-21 17:39:37 +00:00
|
|
|
if ( nVal < 0.0 || nVal > STRING_MAXLEN )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
n = (xub_StrLen) nVal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
n = 1;
|
|
|
|
String aStr( GetString() );
|
|
|
|
if( n < aStr.Len() )
|
|
|
|
aStr.Erase( 0, aStr.Len() - n );
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSearch()
|
|
|
|
{
|
|
|
|
double fAnz;
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
|
|
|
|
{
|
|
|
|
if (nParamCount == 3)
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
fAnz = ::rtl::math::approxFloor(GetDouble());
|
2000-09-18 23:16:46 +00:00
|
|
|
if (fAnz > double(STRING_MAXLEN))
|
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fAnz = 1.0;
|
|
|
|
String sStr = GetString();
|
|
|
|
String SearchStr = GetString();
|
|
|
|
xub_StrLen nPos = (xub_StrLen) fAnz - 1;
|
|
|
|
xub_StrLen nEndPos = sStr.Len();
|
|
|
|
if( nPos >= nEndPos )
|
|
|
|
SetNoValue();
|
|
|
|
else
|
|
|
|
{
|
2001-05-15 20:06:49 +00:00
|
|
|
utl::SearchParam::SearchType eSearchType =
|
|
|
|
(MayBeRegExp( SearchStr, pDok ) ?
|
|
|
|
utl::SearchParam::SRCH_REGEXP : utl::SearchParam::SRCH_NORMAL);
|
|
|
|
utl::SearchParam sPar(SearchStr, eSearchType, FALSE, FALSE, FALSE);
|
2000-11-20 09:31:47 +00:00
|
|
|
utl::TextSearch sT( sPar, *ScGlobal::pCharClass );
|
2000-09-18 23:16:46 +00:00
|
|
|
int nBool = sT.SearchFrwrd(sStr, &nPos, &nEndPos);
|
|
|
|
if (!nBool)
|
|
|
|
SetNoValue();
|
|
|
|
else
|
|
|
|
PushDouble((double)(nPos) + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScMid()
|
|
|
|
{
|
|
|
|
if ( MustHaveParamCount( GetByte(), 3 ) )
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
double fAnz = ::rtl::math::approxFloor(GetDouble());
|
|
|
|
double fAnfang = ::rtl::math::approxFloor(GetDouble());
|
2001-02-21 17:39:37 +00:00
|
|
|
const String& rStr = GetString();
|
2000-09-18 23:16:46 +00:00
|
|
|
if (fAnfang < 1.0 || fAnz < 0.0 || fAnfang > double(STRING_MAXLEN) || fAnz > double(STRING_MAXLEN))
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(rStr.Copy( (xub_StrLen) fAnfang - 1, (xub_StrLen) fAnz ));
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScText()
|
|
|
|
{
|
|
|
|
if ( MustHaveParamCount( GetByte(), 2 ) )
|
|
|
|
{
|
|
|
|
String sFormatString = GetString();
|
|
|
|
double fVal = GetDouble();
|
2001-02-21 17:39:37 +00:00
|
|
|
String aStr;
|
2000-09-18 23:16:46 +00:00
|
|
|
Color* pColor = NULL;
|
|
|
|
LanguageType eCellLang;
|
|
|
|
const ScPatternAttr* pPattern = pDok->GetPattern(
|
|
|
|
aPos.Col(), aPos.Row(), aPos.Tab() );
|
|
|
|
if ( pPattern )
|
|
|
|
eCellLang = ((const SvxLanguageItem&)
|
|
|
|
pPattern->GetItem( ATTR_LANGUAGE_FORMAT )).GetValue();
|
|
|
|
else
|
|
|
|
eCellLang = ScGlobal::eLnge;
|
2001-02-21 17:39:37 +00:00
|
|
|
if ( !pFormatter->GetPreviewStringGuess( sFormatString, fVal, aStr,
|
2000-09-18 23:16:46 +00:00
|
|
|
&pColor, eCellLang ) )
|
|
|
|
SetIllegalParameter();
|
|
|
|
else
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString(aStr);
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScSubstitute()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
if ( MustHaveParamCount( nParamCount, 3, 4 ) )
|
|
|
|
{
|
|
|
|
xub_StrLen nAnz;
|
|
|
|
if (nParamCount == 4)
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
double fAnz = ::rtl::math::approxFloor(GetDouble());
|
2001-02-21 17:39:37 +00:00
|
|
|
if( fAnz < 1 || fAnz > STRING_MAXLEN )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
SetIllegalParameter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nAnz = (xub_StrLen) fAnz;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nAnz = 0;
|
|
|
|
String sNewStr = GetString();
|
|
|
|
String sOldStr = GetString();
|
|
|
|
String sStr = GetString();
|
|
|
|
xub_StrLen nPos = 0;
|
|
|
|
xub_StrLen nCount = 0;
|
|
|
|
xub_StrLen nNewLen = sNewStr.Len();
|
|
|
|
xub_StrLen nOldLen = sOldStr.Len();
|
|
|
|
while( TRUE )
|
|
|
|
{
|
|
|
|
nPos = sStr.Search( sOldStr, nPos );
|
|
|
|
if (nPos != STRING_NOTFOUND)
|
|
|
|
{
|
|
|
|
nCount++;
|
|
|
|
if( !nAnz || nCount == nAnz )
|
|
|
|
{
|
|
|
|
sStr.Erase(nPos,nOldLen);
|
2001-02-21 17:39:37 +00:00
|
|
|
if ( CheckStringResultLen( sStr, sNewStr ) )
|
|
|
|
{
|
|
|
|
sStr.Insert(sNewStr,nPos);
|
2007-02-27 11:16:06 +00:00
|
|
|
nPos = sal::static_int_cast<xub_StrLen>( nPos + nNewLen );
|
2001-02-21 17:39:37 +00:00
|
|
|
}
|
|
|
|
else
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nPos++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( sStr );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScRept()
|
|
|
|
{
|
|
|
|
if ( MustHaveParamCount( GetByte(), 2 ) )
|
|
|
|
{
|
2003-03-26 17:07:02 +00:00
|
|
|
double fAnz = ::rtl::math::approxFloor(GetDouble());
|
2001-02-21 17:39:37 +00:00
|
|
|
String aStr( GetString() );
|
2001-01-10 17:48:10 +00:00
|
|
|
if ( fAnz < 0.0 )
|
2000-09-18 23:16:46 +00:00
|
|
|
SetIllegalParameter();
|
2001-02-21 17:39:37 +00:00
|
|
|
else if ( fAnz * aStr.Len() > STRING_MAXLEN )
|
2001-01-10 17:48:10 +00:00
|
|
|
{
|
|
|
|
SetError( errStringOverflow );
|
|
|
|
PushInt(0);
|
|
|
|
}
|
|
|
|
else if ( fAnz == 0.0 )
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( EMPTY_STRING );
|
2000-09-18 23:16:46 +00:00
|
|
|
else
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
xub_StrLen n = (xub_StrLen) fAnz;
|
|
|
|
const xub_StrLen nLen = aStr.Len();
|
2000-09-18 23:16:46 +00:00
|
|
|
String aRes;
|
2001-02-21 17:39:37 +00:00
|
|
|
const sal_Unicode* const pSrc = aStr.GetBuffer();
|
|
|
|
sal_Unicode* pDst = aRes.AllocBuffer( n * nLen );
|
2000-09-18 23:16:46 +00:00
|
|
|
while( n-- )
|
2001-02-21 17:39:37 +00:00
|
|
|
{
|
|
|
|
memcpy( pDst, pSrc, nLen * sizeof(sal_Unicode) );
|
|
|
|
pDst += nLen;
|
|
|
|
}
|
|
|
|
PushString( aRes );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScConcat()
|
|
|
|
{
|
|
|
|
BYTE nParamCount = GetByte();
|
|
|
|
String aRes;
|
|
|
|
while( nParamCount-- )
|
|
|
|
{
|
2001-02-21 17:39:37 +00:00
|
|
|
const String& rStr = GetString();
|
|
|
|
aRes.Insert( rStr, 0 );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
2001-02-21 17:39:37 +00:00
|
|
|
PushString( aRes );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScInterpreter::ScErrorType()
|
|
|
|
{
|
|
|
|
USHORT nErr;
|
|
|
|
USHORT nOldError = nGlobalError;
|
|
|
|
nGlobalError = 0;
|
|
|
|
switch ( GetStackType() )
|
|
|
|
{
|
|
|
|
case svDoubleRef :
|
|
|
|
{
|
|
|
|
ScRange aRange;
|
|
|
|
PopDoubleRef( aRange );
|
|
|
|
if ( nGlobalError )
|
|
|
|
nErr = nGlobalError;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
if ( DoubleRefToPosSingleRef( aRange, aAdr ) )
|
|
|
|
nErr = pDok->GetErrCode( aAdr );
|
|
|
|
else
|
|
|
|
nErr = nGlobalError;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case svSingleRef :
|
|
|
|
{
|
|
|
|
ScAddress aAdr;
|
|
|
|
PopSingleRef( aAdr );
|
|
|
|
if ( nGlobalError )
|
|
|
|
nErr = nGlobalError;
|
|
|
|
else
|
|
|
|
nErr = pDok->GetErrCode( aAdr );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PopError();
|
|
|
|
nErr = nGlobalError;
|
|
|
|
}
|
|
|
|
if ( nErr )
|
|
|
|
{
|
|
|
|
nGlobalError = 0;
|
|
|
|
PushDouble( nErr );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nGlobalError = nOldError;
|
2007-07-06 11:35:07 +00:00
|
|
|
SetNA();
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-15 20:06:49 +00:00
|
|
|
BOOL ScInterpreter::MayBeRegExp( const String& rStr, const ScDocument* pDoc )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2001-05-15 20:06:49 +00:00
|
|
|
if ( pDoc && !pDoc->GetDocOptions().IsFormulaRegexEnabled() )
|
|
|
|
return FALSE;
|
2001-05-16 23:56:22 +00:00
|
|
|
if ( !rStr.Len() || (rStr.Len() == 1 && rStr.GetChar(0) != '.') )
|
|
|
|
return FALSE; // einzelnes Metazeichen kann keine RegExp sein
|
2001-02-22 14:50:23 +00:00
|
|
|
static const sal_Unicode cre[] = { '.','*','+','?','[',']','^','$','\\','<','>','(',')','|', 0 };
|
2000-09-18 23:16:46 +00:00
|
|
|
const sal_Unicode* p1 = rStr.GetBuffer();
|
|
|
|
sal_Unicode c1;
|
2007-02-27 11:16:06 +00:00
|
|
|
while ( ( c1 = *p1++ ) != 0 )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
const sal_Unicode* p2 = cre;
|
|
|
|
while ( *p2 )
|
|
|
|
{
|
|
|
|
if ( c1 == *p2++ )
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-09-27 12:53:45 +00:00
|
|
|
static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc,
|
|
|
|
const ScQueryParam & rParam, const ScQueryEntry & rEntry )
|
|
|
|
{
|
|
|
|
bool bFound = false;
|
|
|
|
ScQueryCellIterator aCellIter( pDoc, rParam.nTab, rParam, FALSE);
|
|
|
|
if (rEntry.eOp != SC_EQUAL)
|
|
|
|
{
|
|
|
|
// range lookup <= or >=
|
|
|
|
SCCOL nCol;
|
|
|
|
SCROW nRow;
|
|
|
|
bFound = aCellIter.FindEqualOrSortedLastInRange( nCol, nRow);
|
|
|
|
if (bFound)
|
|
|
|
{
|
|
|
|
o_rResultPos.SetCol( nCol);
|
|
|
|
o_rResultPos.SetRow( nRow);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aCellIter.GetFirst())
|
|
|
|
{
|
|
|
|
// EQUAL
|
|
|
|
bFound = true;
|
|
|
|
o_rResultPos.SetCol( aCellIter.GetCol());
|
|
|
|
o_rResultPos.SetRow( aCellIter.GetRow());
|
|
|
|
}
|
|
|
|
return bFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define erDEBUG_LOOKUPCACHE 0
|
|
|
|
#if erDEBUG_LOOKUPCACHE
|
|
|
|
#include <cstdio>
|
|
|
|
using ::std::fprintf;
|
|
|
|
using ::std::fflush;
|
|
|
|
static struct LookupCacheDebugCounter
|
|
|
|
{
|
|
|
|
unsigned long nMiss;
|
|
|
|
unsigned long nHit;
|
|
|
|
LookupCacheDebugCounter() : nMiss(0), nHit(0) {}
|
|
|
|
~LookupCacheDebugCounter()
|
|
|
|
{
|
|
|
|
fprintf( stderr, "\nmiss: %lu, hit: %lu, total: %lu, hit/miss: %lu, hit/total %lu%\n",
|
|
|
|
nMiss, nHit, nHit+nMiss, (nMiss>0 ? nHit/nMiss : 0),
|
|
|
|
((nHit+nMiss)>0 ? (100*nHit)/(nHit+nMiss) : 0));
|
|
|
|
fflush( stderr);
|
|
|
|
}
|
|
|
|
} aLookupCacheDebugCounter;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
|
|
|
|
const ScQueryParam & rParam ) const
|
|
|
|
{
|
|
|
|
bool bFound = false;
|
|
|
|
const ScQueryEntry& rEntry = rParam.GetEntry(0);
|
|
|
|
bool bColumnsMatch = (rParam.nCol1 == rEntry.nField);
|
|
|
|
DBG_ASSERT( bColumnsMatch, "ScInterpreter::LookupQueryWithCache: columns don't match");
|
|
|
|
if (!bColumnsMatch)
|
|
|
|
bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ScRange aLookupRange( rParam.nCol1, rParam.nRow1, rParam.nTab,
|
|
|
|
rParam.nCol2, rParam.nRow2, rParam.nTab);
|
|
|
|
ScLookupCache& rCache = pDok->GetLookupCache( aLookupRange);
|
|
|
|
ScLookupCache::QueryCriteria aCriteria( rEntry);
|
|
|
|
ScLookupCache::Result eCacheResult = rCache.lookup( o_rResultPos,
|
|
|
|
aCriteria, aPos);
|
|
|
|
switch (eCacheResult)
|
|
|
|
{
|
|
|
|
case ScLookupCache::NOT_CACHED :
|
|
|
|
case ScLookupCache::CRITERIA_DIFFERENT :
|
|
|
|
#if erDEBUG_LOOKUPCACHE
|
|
|
|
++aLookupCacheDebugCounter.nMiss;
|
|
|
|
#if erDEBUG_LOOKUPCACHE > 1
|
|
|
|
fprintf( stderr, "miss %d,%d,%d\n", (int)aPos.Col(), (int)aPos.Row(), (int)aPos.Tab());
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
|
|
|
|
if (eCacheResult == ScLookupCache::NOT_CACHED)
|
|
|
|
rCache.insert( o_rResultPos, aCriteria, aPos, bFound);
|
|
|
|
break;
|
|
|
|
case ScLookupCache::FOUND :
|
|
|
|
#if erDEBUG_LOOKUPCACHE
|
|
|
|
++aLookupCacheDebugCounter.nHit;
|
|
|
|
#if erDEBUG_LOOKUPCACHE > 1
|
|
|
|
fprintf( stderr, "hit %d,%d,%d\n", (int)aPos.Col(), (int)aPos.Row(), (int)aPos.Tab());
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
bFound = true;
|
|
|
|
break;
|
|
|
|
case ScLookupCache::NOT_AVAILABLE :
|
|
|
|
; // nothing, bFound remains FALSE
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bFound;
|
|
|
|
}
|