2009-09-09 10:57:16 -04:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* $RCSfile: interpre.hxx,v $
|
|
|
|
* $Revision: 1.35.44.2 $
|
|
|
|
*
|
|
|
|
* This file is part of OpenOffice.org.
|
|
|
|
*
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* OpenOffice.org 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 version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_sc.hxx"
|
|
|
|
|
|
|
|
// INCLUDE ---------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "doubleref.hxx"
|
|
|
|
#include "cell.hxx"
|
|
|
|
#include "global.hxx"
|
|
|
|
#include "document.hxx"
|
|
|
|
#include "queryparam.hxx"
|
2009-09-14 22:14:48 -04:00
|
|
|
#include "globstr.hrc"
|
2009-09-09 10:57:16 -04:00
|
|
|
|
2009-09-09 23:58:50 -04:00
|
|
|
#include <memory>
|
2009-09-14 22:53:29 -04:00
|
|
|
#include <vector>
|
2009-09-09 23:58:50 -04:00
|
|
|
|
2009-09-09 10:57:16 -04:00
|
|
|
using ::rtl::OUString;
|
2009-09-09 23:58:50 -04:00
|
|
|
using ::std::auto_ptr;
|
2009-09-14 22:53:29 -04:00
|
|
|
using ::std::vector;
|
2009-09-09 10:57:16 -04:00
|
|
|
|
2009-09-14 22:14:48 -04:00
|
|
|
namespace {
|
|
|
|
|
2009-09-14 23:50:13 -04:00
|
|
|
void lcl_toUpper(OUString& rStr)
|
|
|
|
{
|
|
|
|
rStr = ScGlobal::pCharClass->toUpper(rStr.trim(), 0, rStr.getLength());
|
|
|
|
}
|
2009-09-14 22:14:48 -04:00
|
|
|
|
2009-09-14 22:53:29 -04:00
|
|
|
bool lcl_createStarQuery(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
|
2009-09-14 22:14:48 -04:00
|
|
|
{
|
|
|
|
// A valid StarQuery must be at least 4 columns wide. To be precise it
|
|
|
|
// should be exactly 4 columns ...
|
|
|
|
// Additionally, if this wasn't checked, a formula pointing to a valid 1-3
|
|
|
|
// column Excel style query range immediately left to itself would result
|
|
|
|
// in a circular reference when the field name or operator or value (first
|
|
|
|
// to third query range column) is obtained (#i58354#). Furthermore, if the
|
|
|
|
// range wasn't sufficiently specified data changes wouldn't flag formula
|
|
|
|
// cells for recalculation.
|
|
|
|
|
|
|
|
if (pQueryRef->getColSize() < 4)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
BOOL bValid;
|
|
|
|
BOOL bFound;
|
2009-09-14 23:50:13 -04:00
|
|
|
OUString aCellStr;
|
2009-09-14 22:14:48 -04:00
|
|
|
SCSIZE nIndex = 0;
|
|
|
|
SCROW nRow = 0;
|
|
|
|
SCROW nRows = pDBRef->getRowSize();
|
|
|
|
SCSIZE nNewEntries = static_cast<SCSIZE>(nRows);
|
|
|
|
pParam->Resize(nNewEntries);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
ScQueryEntry& rEntry = pParam->GetEntry(nIndex);
|
|
|
|
|
|
|
|
bValid = FALSE;
|
|
|
|
|
|
|
|
if (nIndex > 0)
|
|
|
|
{
|
|
|
|
// For all entries after the first one, check the and/or connector in the first column.
|
|
|
|
aCellStr = pQueryRef->getString(0, nRow);
|
2009-09-14 23:50:13 -04:00
|
|
|
lcl_toUpper(aCellStr);
|
|
|
|
if ( aCellStr.equals(ScGlobal::GetRscString(STR_TABLE_UND)) )
|
2009-09-14 22:14:48 -04:00
|
|
|
{
|
|
|
|
rEntry.eConnect = SC_AND;
|
|
|
|
bValid = TRUE;
|
|
|
|
}
|
2009-09-14 23:50:13 -04:00
|
|
|
else if ( aCellStr.equals(ScGlobal::GetRscString(STR_TABLE_ODER)) )
|
2009-09-14 22:14:48 -04:00
|
|
|
{
|
|
|
|
rEntry.eConnect = SC_OR;
|
|
|
|
bValid = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((nIndex < 1) || bValid)
|
|
|
|
{
|
|
|
|
// field name in the 2nd column.
|
|
|
|
bFound = FALSE;
|
|
|
|
aCellStr = pQueryRef->getString(1, nRow);
|
|
|
|
SCCOL nField = pDBRef->findFieldColumn(aCellStr); // TODO: must be case insensitive comparison.
|
|
|
|
if (ValidCol(nField))
|
|
|
|
{
|
|
|
|
rEntry.nField = nField;
|
|
|
|
bValid = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bValid)
|
|
|
|
{
|
|
|
|
// equality, non-equality operator in the 3rd column.
|
|
|
|
bFound = FALSE;
|
|
|
|
aCellStr = pQueryRef->getString(2, nRow);
|
2009-09-14 23:50:13 -04:00
|
|
|
lcl_toUpper(aCellStr);
|
|
|
|
const sal_Unicode* p = aCellStr.getStr();
|
|
|
|
if (p[0] == sal_Unicode('<'))
|
2009-09-14 22:14:48 -04:00
|
|
|
{
|
2009-09-14 23:50:13 -04:00
|
|
|
if (p[1] == sal_Unicode('>'))
|
2009-09-14 22:14:48 -04:00
|
|
|
rEntry.eOp = SC_NOT_EQUAL;
|
2009-09-14 23:50:13 -04:00
|
|
|
else if (p[1] == sal_Unicode('='))
|
2009-09-14 22:14:48 -04:00
|
|
|
rEntry.eOp = SC_LESS_EQUAL;
|
|
|
|
else
|
|
|
|
rEntry.eOp = SC_LESS;
|
|
|
|
}
|
2009-09-14 23:50:13 -04:00
|
|
|
else if (p[0] == sal_Unicode('>'))
|
2009-09-14 22:14:48 -04:00
|
|
|
{
|
2009-09-14 23:50:13 -04:00
|
|
|
if (p[1] == sal_Unicode('='))
|
2009-09-14 22:14:48 -04:00
|
|
|
rEntry.eOp = SC_GREATER_EQUAL;
|
|
|
|
else
|
|
|
|
rEntry.eOp = SC_GREATER;
|
|
|
|
}
|
2009-09-14 23:50:13 -04:00
|
|
|
else if (p[0] == sal_Unicode('='))
|
2009-09-14 22:14:48 -04:00
|
|
|
rEntry.eOp = SC_EQUAL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bValid)
|
|
|
|
{
|
|
|
|
// Finally, the right-hand-side value in the 4th column.
|
|
|
|
*rEntry.pStr = pQueryRef->getString(3, nRow);
|
|
|
|
rEntry.bDoQuery = TRUE;
|
|
|
|
}
|
|
|
|
nIndex++;
|
|
|
|
nRow++;
|
|
|
|
}
|
|
|
|
while (bValid && (nRow < nRows) /* && (nIndex < MAXQUERY) */ );
|
|
|
|
return bValid;
|
|
|
|
}
|
|
|
|
|
2009-09-14 22:53:29 -04:00
|
|
|
bool lcl_createExcelQuery(
|
2009-09-14 22:14:48 -04:00
|
|
|
ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
|
|
|
|
{
|
|
|
|
bool bValid = true;
|
|
|
|
SCCOL nCols = pQueryRef->getColSize();
|
|
|
|
SCROW nRows = pQueryRef->getRowSize();
|
2009-09-14 22:53:29 -04:00
|
|
|
vector<SCCOL> aFields(nCols);
|
2009-09-14 22:14:48 -04:00
|
|
|
SCCOL nCol = 0;
|
|
|
|
while (bValid && (nCol < nCols))
|
|
|
|
{
|
2009-09-14 23:50:13 -04:00
|
|
|
OUString aQueryStr = pQueryRef->getString(nCol, 0);
|
2009-09-14 22:14:48 -04:00
|
|
|
SCCOL nField = pDBRef->findFieldColumn(aQueryStr);
|
|
|
|
if (ValidCol(nField))
|
2009-09-14 22:53:29 -04:00
|
|
|
aFields[nCol] = nField;
|
2009-09-14 22:14:48 -04:00
|
|
|
else
|
|
|
|
bValid = false;
|
|
|
|
++nCol;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bValid)
|
|
|
|
{
|
|
|
|
// ULONG nVisible = 0;
|
|
|
|
// for ( nCol=nCol1; nCol<=nCol2; nCol++ )
|
|
|
|
// nVisible += aCol[nCol].VisibleCount( nRow1+1, nRow2 );
|
|
|
|
|
|
|
|
// Count the number of visible cells (excluding the header row). Each
|
|
|
|
// visible cell corresponds with a single query.
|
|
|
|
SCSIZE nVisible = pQueryRef->getVisibleDataCellCount();
|
|
|
|
if ( nVisible > SCSIZE_MAX / sizeof(void*) )
|
|
|
|
{
|
|
|
|
DBG_ERROR("zu viele Filterkritierien");
|
|
|
|
nVisible = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCSIZE nNewEntries = nVisible;
|
|
|
|
pParam->Resize( nNewEntries );
|
|
|
|
|
|
|
|
SCSIZE nIndex = 0;
|
|
|
|
SCROW nRow = 1;
|
|
|
|
String aCellStr;
|
|
|
|
while (nRow < nRows)
|
|
|
|
{
|
|
|
|
nCol = 0;
|
|
|
|
while (nCol < nCols)
|
|
|
|
{
|
|
|
|
aCellStr = pQueryRef->getString(nCol, nRow);
|
|
|
|
ScGlobal::pCharClass->toUpper( aCellStr );
|
|
|
|
if (aCellStr.Len() > 0)
|
|
|
|
{
|
|
|
|
if (nIndex < nNewEntries)
|
|
|
|
{
|
2009-09-14 22:53:29 -04:00
|
|
|
pParam->GetEntry(nIndex).nField = aFields[nCol];
|
2009-09-14 22:14:48 -04:00
|
|
|
pParam->FillInExcelSyntax(aCellStr, nIndex);
|
|
|
|
nIndex++;
|
|
|
|
if (nIndex < nNewEntries)
|
|
|
|
pParam->GetEntry(nIndex).eConnect = SC_AND;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bValid = FALSE;
|
|
|
|
}
|
|
|
|
nCol++;
|
|
|
|
}
|
|
|
|
nRow++;
|
|
|
|
if (nIndex < nNewEntries)
|
|
|
|
pParam->GetEntry(nIndex).eConnect = SC_OR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bValid;
|
|
|
|
}
|
|
|
|
|
2009-09-14 22:53:29 -04:00
|
|
|
bool lcl_fillQueryEntries(
|
2009-09-14 22:14:48 -04:00
|
|
|
ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
|
|
|
|
{
|
|
|
|
SCSIZE nCount = pParam->GetEntryCount();
|
|
|
|
for (SCSIZE i = 0; i < nCount; ++i)
|
|
|
|
pParam->GetEntry(i).Clear();
|
|
|
|
|
|
|
|
// Standard QueryTabelle
|
2009-09-14 22:53:29 -04:00
|
|
|
bool bValid = lcl_createStarQuery(pParam, pDBRef, pQueryRef);
|
2009-09-14 22:14:48 -04:00
|
|
|
// Excel QueryTabelle
|
|
|
|
if (!bValid)
|
2009-09-14 22:53:29 -04:00
|
|
|
bValid = lcl_createExcelQuery(pParam, pDBRef, pQueryRef);
|
2009-09-14 22:14:48 -04:00
|
|
|
|
|
|
|
nCount = pParam->GetEntryCount();
|
|
|
|
if (bValid)
|
|
|
|
{
|
|
|
|
// bQueryByString muss gesetzt sein
|
|
|
|
for (SCSIZE i = 0; i < nCount; ++i)
|
|
|
|
pParam->GetEntry(i).bQueryByString = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// nix
|
|
|
|
for (SCSIZE i = 0; i < nCount; ++i)
|
|
|
|
pParam->GetEntry(i).Clear();
|
|
|
|
}
|
|
|
|
return bValid;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-09-09 10:57:16 -04:00
|
|
|
// ============================================================================
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBRangeBase::ScDBRangeBase(ScDocument* pDoc, RefType eType) :
|
2009-09-09 10:57:16 -04:00
|
|
|
mpDoc(pDoc), meType(eType)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBRangeBase::~ScDBRangeBase()
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBRangeBase::RefType ScDBRangeBase::getType() const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
return meType;
|
|
|
|
}
|
|
|
|
|
2009-09-14 22:32:35 -04:00
|
|
|
bool ScDBRangeBase::fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const
|
|
|
|
{
|
|
|
|
if (!pDBRef)
|
|
|
|
return false;
|
|
|
|
|
2009-09-14 22:53:29 -04:00
|
|
|
return lcl_fillQueryEntries(pParam, pDBRef, this);
|
2009-09-14 22:32:35 -04:00
|
|
|
}
|
|
|
|
|
2009-09-15 21:33:57 -04:00
|
|
|
void ScDBRangeBase::fillQueryOptions(ScQueryParamBase* pParam)
|
|
|
|
{
|
|
|
|
pParam->bHasHeader = true;
|
|
|
|
pParam->bByRow = true;
|
|
|
|
pParam->bInplace = true;
|
|
|
|
pParam->bCaseSens = false;
|
|
|
|
pParam->bRegExp = false;
|
|
|
|
pParam->bDuplicate = true;
|
|
|
|
pParam->bMixedComparison = false;
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDocument* ScDBRangeBase::getDoc() const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
return mpDoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBInternalRange::ScDBInternalRange(ScDocument* pDoc, const ScRange& rRange) :
|
|
|
|
ScDBRangeBase(pDoc, INTERNAL), maRange(rRange)
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBInternalRange::~ScDBInternalRange()
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
const ScRange& ScDBInternalRange::getRange() const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
return maRange;
|
|
|
|
}
|
|
|
|
|
2009-09-14 22:14:48 -04:00
|
|
|
SCCOL ScDBInternalRange::getColSize() const
|
|
|
|
{
|
|
|
|
return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCROW ScDBInternalRange::getRowSize() const
|
|
|
|
{
|
|
|
|
return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCSIZE ScDBInternalRange::getVisibleDataCellCount() const
|
|
|
|
{
|
|
|
|
SCCOL nCols = getColSize();
|
|
|
|
SCROW nRows = getRowSize();
|
|
|
|
if (nRows <= 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (nRows-1)*nCols;
|
|
|
|
}
|
|
|
|
|
|
|
|
OUString ScDBInternalRange::getString(SCCOL nCol, SCROW nRow) const
|
|
|
|
{
|
|
|
|
String aStr;
|
2009-09-14 22:53:29 -04:00
|
|
|
const ScAddress& s = maRange.aStart;
|
|
|
|
getDoc()->GetString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr);
|
2009-09-14 22:14:48 -04:00
|
|
|
return aStr;
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
SCCOL ScDBInternalRange::getFirstFieldColumn() const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
return getRange().aStart.Col();
|
|
|
|
}
|
|
|
|
|
2009-09-15 17:23:28 -04:00
|
|
|
SCCOL ScDBInternalRange::findFieldColumn(SCCOL nIndex) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
const ScRange& rRange = getRange();
|
|
|
|
const ScAddress& s = rRange.aStart;
|
|
|
|
const ScAddress& e = rRange.aEnd;
|
|
|
|
|
|
|
|
SCCOL nDBCol1 = s.Col();
|
|
|
|
SCCOL nDBCol2 = e.Col();
|
|
|
|
|
2009-09-15 17:23:28 -04:00
|
|
|
if ( nIndex <= 0 || nIndex > (nDBCol2 - nDBCol1 + 1) )
|
2009-09-09 10:57:16 -04:00
|
|
|
return nDBCol1;
|
|
|
|
|
2009-09-15 17:23:28 -04:00
|
|
|
return Min(nDBCol2, static_cast<SCCOL>(nDBCol1 + nIndex - 1));
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
|
2009-09-14 23:50:13 -04:00
|
|
|
sal_uInt16 ScDBInternalRange::getCellString(OUString& rStr, ScBaseCell* pCell) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
sal_uInt16 nErr = 0;
|
2009-09-14 23:50:13 -04:00
|
|
|
String aStr;
|
2009-09-09 10:57:16 -04:00
|
|
|
if (pCell)
|
|
|
|
{
|
|
|
|
SvNumberFormatter* pFormatter = getDoc()->GetFormatTable();
|
|
|
|
switch (pCell->GetCellType())
|
|
|
|
{
|
|
|
|
case CELLTYPE_STRING:
|
2009-09-14 23:50:13 -04:00
|
|
|
((ScStringCell*) pCell)->GetString(aStr);
|
2009-09-09 10:57:16 -04:00
|
|
|
break;
|
|
|
|
case CELLTYPE_EDIT:
|
2009-09-14 23:50:13 -04:00
|
|
|
((ScEditCell*) pCell)->GetString(aStr);
|
2009-09-09 10:57:16 -04:00
|
|
|
break;
|
|
|
|
case CELLTYPE_FORMULA:
|
|
|
|
{
|
|
|
|
ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
|
|
|
|
nErr = pFCell->GetErrCode();
|
|
|
|
if (pFCell->IsValue())
|
|
|
|
{
|
|
|
|
double fVal = pFCell->GetValue();
|
|
|
|
ULONG nIndex = pFormatter->GetStandardFormat(
|
|
|
|
NUMBERFORMAT_NUMBER,
|
|
|
|
ScGlobal::eLnge);
|
2009-09-14 23:50:13 -04:00
|
|
|
pFormatter->GetInputLineString(fVal, nIndex, aStr);
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
else
|
2009-09-14 23:50:13 -04:00
|
|
|
pFCell->GetString(aStr);
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CELLTYPE_VALUE:
|
|
|
|
{
|
|
|
|
double fVal = ((ScValueCell*) pCell)->GetValue();
|
|
|
|
ULONG nIndex = pFormatter->GetStandardFormat(
|
|
|
|
NUMBERFORMAT_NUMBER,
|
|
|
|
ScGlobal::eLnge);
|
2009-09-14 23:50:13 -04:00
|
|
|
pFormatter->GetInputLineString(fVal, nIndex, aStr);
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2009-09-14 23:50:13 -04:00
|
|
|
;
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
}
|
2009-09-14 23:50:13 -04:00
|
|
|
rStr = aStr;
|
2009-09-09 10:57:16 -04:00
|
|
|
return nErr;
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
SCCOL ScDBInternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-09 23:58:50 -04:00
|
|
|
const ScAddress& s = maRange.aStart;
|
|
|
|
const ScAddress& e = maRange.aEnd;
|
2009-09-14 23:50:13 -04:00
|
|
|
OUString aUpper = rStr;
|
|
|
|
lcl_toUpper(aUpper);
|
2009-09-09 10:57:16 -04:00
|
|
|
|
|
|
|
SCCOL nDBCol1 = s.Col();
|
|
|
|
SCROW nDBRow1 = s.Row();
|
|
|
|
SCTAB nDBTab1 = s.Tab();
|
|
|
|
SCCOL nDBCol2 = e.Col();
|
|
|
|
|
|
|
|
SCCOL nField = nDBCol1;
|
|
|
|
BOOL bFound = TRUE;
|
|
|
|
|
|
|
|
bFound = FALSE;
|
2009-09-14 23:50:13 -04:00
|
|
|
OUString aCellStr;
|
2009-09-09 10:57:16 -04:00
|
|
|
ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 );
|
|
|
|
while (!bFound && (aLook.Col() <= nDBCol2))
|
|
|
|
{
|
|
|
|
ScBaseCell* pCell = getDoc()->GetCell( aLook );
|
2009-09-09 23:58:50 -04:00
|
|
|
sal_uInt16 nErr = getCellString( aCellStr, pCell );
|
|
|
|
if (pErr)
|
|
|
|
*pErr = nErr;
|
2009-09-14 23:50:13 -04:00
|
|
|
lcl_toUpper(aCellStr);
|
|
|
|
bFound = ScGlobal::pTransliteration->isEqual(aCellStr, aUpper);
|
2009-09-09 10:57:16 -04:00
|
|
|
if (!bFound)
|
|
|
|
aLook.IncCol();
|
|
|
|
}
|
|
|
|
nField = aLook.Col();
|
|
|
|
|
|
|
|
return bFound ? nField : -1;
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBQueryParamBase* ScDBInternalRange::createQueryParam(const ScDBRangeBase* pQueryRef) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-09 23:58:50 -04:00
|
|
|
auto_ptr<ScDBQueryParamInternal> pParam(new ScDBQueryParamInternal);
|
|
|
|
|
|
|
|
// Set the database range first.
|
2009-09-09 10:57:16 -04:00
|
|
|
const ScAddress& s = maRange.aStart;
|
|
|
|
const ScAddress& e = maRange.aEnd;
|
2009-09-09 23:58:50 -04:00
|
|
|
pParam->nCol1 = s.Col();
|
|
|
|
pParam->nRow1 = s.Row();
|
|
|
|
pParam->nCol2 = e.Col();
|
|
|
|
pParam->nRow2 = e.Row();
|
|
|
|
pParam->nTab = s.Tab();
|
2009-09-15 21:33:57 -04:00
|
|
|
|
|
|
|
fillQueryOptions(pParam.get());
|
2009-09-09 23:58:50 -04:00
|
|
|
|
|
|
|
// Now construct the query entries from the query range.
|
|
|
|
if (!pQueryRef->fillQueryEntries(pParam.get(), this))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return pParam.release();
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
bool ScDBInternalRange::isRangeEqual(const ScRange& rRange) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
return maRange == rRange;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
2009-09-14 22:14:48 -04:00
|
|
|
ScDBExternalRange::ScDBExternalRange(ScDocument* pDoc, const ScMatrixRef& pMat) :
|
|
|
|
ScDBRangeBase(pDoc, EXTERNAL), mpMatrix(pMat)
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-14 22:14:48 -04:00
|
|
|
SCSIZE nC, nR;
|
|
|
|
mpMatrix->GetDimensions(nC, nR);
|
|
|
|
mnCols = nC;
|
|
|
|
mnRows = nR;
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
ScDBExternalRange::~ScDBExternalRange()
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-09-14 22:14:48 -04:00
|
|
|
SCCOL ScDBExternalRange::getColSize() const
|
|
|
|
{
|
|
|
|
return mnCols;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCROW ScDBExternalRange::getRowSize() const
|
|
|
|
{
|
|
|
|
return mnRows;
|
|
|
|
}
|
|
|
|
|
|
|
|
SCSIZE ScDBExternalRange::getVisibleDataCellCount() const
|
|
|
|
{
|
|
|
|
SCCOL nCols = getColSize();
|
|
|
|
SCROW nRows = getRowSize();
|
|
|
|
if (nRows <= 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (nRows-1)*nCols;
|
|
|
|
}
|
|
|
|
|
|
|
|
OUString ScDBExternalRange::getString(SCCOL nCol, SCROW nRow) const
|
|
|
|
{
|
|
|
|
if (nCol >= mnCols || nRow >= mnRows)
|
|
|
|
return OUString();
|
|
|
|
|
|
|
|
return mpMatrix->GetString(nCol, nRow);
|
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
SCCOL ScDBExternalRange::getFirstFieldColumn() const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-15 17:23:28 -04:00
|
|
|
return 0;
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
|
2009-09-15 17:23:28 -04:00
|
|
|
SCCOL ScDBExternalRange::findFieldColumn(SCCOL nIndex) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-15 17:23:28 -04:00
|
|
|
if (nIndex < 1)
|
|
|
|
// 1st field
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (nIndex > mnCols)
|
|
|
|
// last field
|
|
|
|
return mnCols - 1;
|
|
|
|
|
|
|
|
return nIndex - 1;
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
|
2009-09-15 17:23:28 -04:00
|
|
|
SCCOL ScDBExternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-15 17:23:28 -04:00
|
|
|
if (pErr)
|
|
|
|
pErr = 0;
|
|
|
|
|
|
|
|
OUString aUpper = rStr;
|
|
|
|
lcl_toUpper(aUpper);
|
|
|
|
for (SCCOL i = 0; i < mnCols; ++i)
|
|
|
|
{
|
|
|
|
OUString aUpperVal = mpMatrix->GetString(i, 0);
|
|
|
|
lcl_toUpper(aUpperVal);
|
|
|
|
if (aUpper.equals(aUpperVal))
|
|
|
|
return i;
|
|
|
|
}
|
2009-09-09 10:57:16 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-09-15 17:23:28 -04:00
|
|
|
ScDBQueryParamBase* ScDBExternalRange::createQueryParam(const ScDBRangeBase* pQueryRef) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
2009-09-15 17:23:28 -04:00
|
|
|
auto_ptr<ScDBQueryParamMatrix> pParam(new ScDBQueryParamMatrix);
|
|
|
|
pParam->mpMatrix = mpMatrix;
|
2009-09-15 21:33:57 -04:00
|
|
|
fillQueryOptions(pParam.get());
|
2009-09-15 17:23:28 -04:00
|
|
|
|
|
|
|
// Now construct the query entries from the query range.
|
|
|
|
if (!pQueryRef->fillQueryEntries(pParam.get(), this))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return pParam.release();
|
2009-09-09 10:57:16 -04:00
|
|
|
}
|
|
|
|
|
2009-09-10 00:28:42 -04:00
|
|
|
bool ScDBExternalRange::isRangeEqual(const ScRange& /*rRange*/) const
|
2009-09-09 10:57:16 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2009-09-14 23:50:13 -04:00
|
|
|
|