1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "oox/xls/formulabase.hxx" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <map> 31*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/sheet/AddressConvention.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/sheet/ReferenceFlags.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/sheet/SingleReference.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/sheet/ComplexReference.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaLanguage.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaMapGroup.hpp> 39*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp> 40*cdf0e10cSrcweir #include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/sheet/XFormulaParser.hpp> 42*cdf0e10cSrcweir #include <rtl/strbuf.hxx> 43*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 44*cdf0e10cSrcweir #include "oox/core/filterbase.hxx" 45*cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx" 46*cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx" 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir namespace oox { 49*cdf0e10cSrcweir namespace xls { 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir // ============================================================================ 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 54*cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 55*cdf0e10cSrcweir using namespace ::com::sun::star::table; 56*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir using ::rtl::OString; 59*cdf0e10cSrcweir using ::rtl::OStringBuffer; 60*cdf0e10cSrcweir using ::rtl::OStringToOUString; 61*cdf0e10cSrcweir using ::rtl::OUString; 62*cdf0e10cSrcweir using ::rtl::OUStringBuffer; 63*cdf0e10cSrcweir using ::rtl::OUStringToOString; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir // reference helpers ========================================================== 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir BinSingleRef2d::BinSingleRef2d() : 68*cdf0e10cSrcweir mnCol( 0 ), 69*cdf0e10cSrcweir mnRow( 0 ), 70*cdf0e10cSrcweir mbColRel( false ), 71*cdf0e10cSrcweir mbRowRel( false ) 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir void BinSingleRef2d::setBiff12Data( sal_uInt16 nCol, sal_Int32 nRow, bool bRelativeAsOffset ) 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir mnCol = nCol & BIFF12_TOK_REF_COLMASK; 78*cdf0e10cSrcweir mnRow = nRow & BIFF12_TOK_REF_ROWMASK; 79*cdf0e10cSrcweir mbColRel = getFlag( nCol, BIFF12_TOK_REF_COLREL ); 80*cdf0e10cSrcweir mbRowRel = getFlag( nCol, BIFF12_TOK_REF_ROWREL ); 81*cdf0e10cSrcweir if( bRelativeAsOffset && mbColRel && (mnCol > (BIFF12_TOK_REF_COLMASK >> 1)) ) 82*cdf0e10cSrcweir mnCol -= (BIFF12_TOK_REF_COLMASK + 1); 83*cdf0e10cSrcweir if( bRelativeAsOffset && mbRowRel && (mnRow > (BIFF12_TOK_REF_ROWMASK >> 1)) ) 84*cdf0e10cSrcweir mnRow -= (BIFF12_TOK_REF_ROWMASK + 1); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir void BinSingleRef2d::setBiff2Data( sal_uInt8 nCol, sal_uInt16 nRow, bool bRelativeAsOffset ) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir mnCol = nCol; 90*cdf0e10cSrcweir mnRow = nRow & BIFF_TOK_REF_ROWMASK; 91*cdf0e10cSrcweir mbColRel = getFlag( nRow, BIFF_TOK_REF_COLREL ); 92*cdf0e10cSrcweir mbRowRel = getFlag( nRow, BIFF_TOK_REF_ROWREL ); 93*cdf0e10cSrcweir if( bRelativeAsOffset && mbColRel && (mnCol >= 0x80) ) 94*cdf0e10cSrcweir mnCol -= 0x100; 95*cdf0e10cSrcweir if( bRelativeAsOffset && mbRowRel && (mnRow > (BIFF_TOK_REF_ROWMASK >> 1)) ) 96*cdf0e10cSrcweir mnRow -= (BIFF_TOK_REF_ROWMASK + 1); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir void BinSingleRef2d::setBiff8Data( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelativeAsOffset ) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir mnCol = nCol & BIFF_TOK_REF_COLMASK; 102*cdf0e10cSrcweir mnRow = nRow; 103*cdf0e10cSrcweir mbColRel = getFlag( nCol, BIFF_TOK_REF_COLREL ); 104*cdf0e10cSrcweir mbRowRel = getFlag( nCol, BIFF_TOK_REF_ROWREL ); 105*cdf0e10cSrcweir if( bRelativeAsOffset && mbColRel && (mnCol > (BIFF_TOK_REF_COLMASK >> 1)) ) 106*cdf0e10cSrcweir mnCol -= (BIFF_TOK_REF_COLMASK + 1); 107*cdf0e10cSrcweir if( bRelativeAsOffset && mbRowRel && (mnRow >= 0x8000) ) 108*cdf0e10cSrcweir mnRow -= 0x10000; 109*cdf0e10cSrcweir } 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir void BinSingleRef2d::readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset ) 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir sal_Int32 nRow; 114*cdf0e10cSrcweir sal_uInt16 nCol; 115*cdf0e10cSrcweir rStrm >> nRow >> nCol; 116*cdf0e10cSrcweir setBiff12Data( nCol, nRow, bRelativeAsOffset ); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir void BinSingleRef2d::readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir sal_uInt16 nRow; 122*cdf0e10cSrcweir sal_uInt8 nCol; 123*cdf0e10cSrcweir rStrm >> nRow >> nCol; 124*cdf0e10cSrcweir setBiff2Data( nCol, nRow, bRelativeAsOffset ); 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir void BinSingleRef2d::readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset ) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir sal_uInt16 nRow, nCol; 130*cdf0e10cSrcweir rStrm >> nRow >> nCol; 131*cdf0e10cSrcweir setBiff8Data( nCol, nRow, bRelativeAsOffset ); 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir void BinComplexRef2d::readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir sal_Int32 nRow1, nRow2; 139*cdf0e10cSrcweir sal_uInt16 nCol1, nCol2; 140*cdf0e10cSrcweir rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2; 141*cdf0e10cSrcweir maRef1.setBiff12Data( nCol1, nRow1, bRelativeAsOffset ); 142*cdf0e10cSrcweir maRef2.setBiff12Data( nCol2, nRow2, bRelativeAsOffset ); 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir void BinComplexRef2d::readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir sal_uInt16 nRow1, nRow2; 148*cdf0e10cSrcweir sal_uInt8 nCol1, nCol2; 149*cdf0e10cSrcweir rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2; 150*cdf0e10cSrcweir maRef1.setBiff2Data( nCol1, nRow1, bRelativeAsOffset ); 151*cdf0e10cSrcweir maRef2.setBiff2Data( nCol2, nRow2, bRelativeAsOffset ); 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir void BinComplexRef2d::readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset ) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir sal_uInt16 nRow1, nRow2, nCol1, nCol2; 157*cdf0e10cSrcweir rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2; 158*cdf0e10cSrcweir maRef1.setBiff8Data( nCol1, nRow1, bRelativeAsOffset ); 159*cdf0e10cSrcweir maRef2.setBiff8Data( nCol2, nRow2, bRelativeAsOffset ); 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir // token vector, sequence ===================================================== 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir ApiTokenVector::ApiTokenVector() 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir } 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir Any& ApiTokenVector::append( sal_Int32 nOpCode ) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir resize( size() + 1 ); 171*cdf0e10cSrcweir back().OpCode = nOpCode; 172*cdf0e10cSrcweir return back().Data; 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir // token sequence iterator ==================================================== 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir ApiTokenIterator::ApiTokenIterator( const ApiTokenSequence& rTokens, sal_Int32 nSpacesOpCode, bool bSkipSpaces ) : 178*cdf0e10cSrcweir mpToken( rTokens.getConstArray() ), 179*cdf0e10cSrcweir mpTokenEnd( rTokens.getConstArray() + rTokens.getLength() ), 180*cdf0e10cSrcweir mnSpacesOpCode( nSpacesOpCode ), 181*cdf0e10cSrcweir mbSkipSpaces( bSkipSpaces ) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir skipSpaces(); 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir ApiTokenIterator::ApiTokenIterator( const ApiTokenIterator& rIter, bool bSkipSpaces ) : 187*cdf0e10cSrcweir mpToken( rIter.mpToken ), 188*cdf0e10cSrcweir mpTokenEnd( rIter.mpTokenEnd ), 189*cdf0e10cSrcweir mnSpacesOpCode( rIter.mnSpacesOpCode ), 190*cdf0e10cSrcweir mbSkipSpaces( bSkipSpaces ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir skipSpaces(); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir ApiTokenIterator& ApiTokenIterator::operator++() 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir if( is() ) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir ++mpToken; 200*cdf0e10cSrcweir skipSpaces(); 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir return *this; 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir void ApiTokenIterator::skipSpaces() 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir if( mbSkipSpaces ) 208*cdf0e10cSrcweir while( is() && (mpToken->OpCode == mnSpacesOpCode) ) 209*cdf0e10cSrcweir ++mpToken; 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir // function data ============================================================== 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir namespace { 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir const size_t FUNCINFO_PARAMINFOCOUNT = 5; /// Number of parameter type entries. 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_VOLATILE = 0x0001; /// Result is volatile (e.g. NOW() function). 219*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_IMPORTONLY = 0x0002; /// Only used in import filter. 220*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_EXPORTONLY = 0x0004; /// Only used in export filter. 221*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROCALL = 0x0008; /// Function is stored as macro call in Excel (_xlfn. prefix). OOXML name MUST exist. 222*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROCALLODF = 0x0010; /// ODF-only function stored as macro call in Excel (_xlfnodf. prefix). ODF name MUST exist. 223*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0020; /// Function is external in Calc. 224*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0040; /// Function is a macro-sheet function. 225*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROCMD = 0x0080; /// Function is a macro-sheet command. 226*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0100; /// Function is always represented by a tFuncVar token. 227*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0200; /// Optional parameters are expected to appear in pairs. 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir /// Converts a function library index (value of enum FunctionLibraryType) to function flags. 230*cdf0e10cSrcweir #define FUNCLIB_TO_FUNCFLAGS( funclib_index ) static_cast< sal_uInt16 >( static_cast< sal_uInt8 >( funclib_index ) << 12 ) 231*cdf0e10cSrcweir /// Extracts a function library index (value of enum FunctionLibraryType) from function flags. 232*cdf0e10cSrcweir #define FUNCFLAGS_TO_FUNCLIB( func_flags ) extractValue< FunctionLibraryType >( func_flags, 12, 4 ) 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir typedef ::boost::shared_ptr< FunctionInfo > FunctionInfoRef; 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir struct FunctionData 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir const sal_Char* mpcOdfFuncName; /// ODF function name. 239*cdf0e10cSrcweir const sal_Char* mpcOoxFuncName; /// OOXML function name. 240*cdf0e10cSrcweir sal_uInt16 mnBiff12FuncId; /// BIFF12 function identifier. 241*cdf0e10cSrcweir sal_uInt16 mnBiffFuncId; /// BIFF2-BIFF8 function identifier. 242*cdf0e10cSrcweir sal_uInt8 mnMinParamCount; /// Minimum number of parameters. 243*cdf0e10cSrcweir sal_uInt8 mnMaxParamCount; /// Maximum number of parameters. 244*cdf0e10cSrcweir sal_uInt8 mnRetClass; /// BIFF token class of the return value. 245*cdf0e10cSrcweir FunctionParamInfo mpParamInfos[ FUNCINFO_PARAMINFOCOUNT ]; /// Information about all parameters. 246*cdf0e10cSrcweir sal_uInt16 mnFlags; /// Additional flags. 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir inline bool isSupported( bool bImportFilter ) const; 249*cdf0e10cSrcweir }; 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir inline bool FunctionData::isSupported( bool bImportFilter ) const 252*cdf0e10cSrcweir { 253*cdf0e10cSrcweir /* For import filters: the FUNCFLAG_EXPORTONLY flag must not be set, 254*cdf0e10cSrcweir for export filters: the FUNCFLAG_IMPORTONLY flag must not be set. */ 255*cdf0e10cSrcweir return !getFlag( mnFlags, bImportFilter ? FUNCFLAG_EXPORTONLY : FUNCFLAG_IMPORTONLY ); 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF function identifier available. 259*cdf0e10cSrcweir const sal_uInt8 MX = SAL_MAX_UINT8; /// Maximum parameter count. 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir // abbreviations for function return token class 262*cdf0e10cSrcweir const sal_uInt8 R = BIFF_TOKCLASS_REF; 263*cdf0e10cSrcweir const sal_uInt8 V = BIFF_TOKCLASS_VAL; 264*cdf0e10cSrcweir const sal_uInt8 A = BIFF_TOKCLASS_ARR; 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir // abbreviations for parameter infos 267*cdf0e10cSrcweir #define RO { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ORG, false } 268*cdf0e10cSrcweir #define RV { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_VAL, false } 269*cdf0e10cSrcweir #define RA { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ARR, false } 270*cdf0e10cSrcweir #define RR { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPT, false } 271*cdf0e10cSrcweir #define RX { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPX, false } 272*cdf0e10cSrcweir #define VO { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ORG, true } 273*cdf0e10cSrcweir #define VV { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_VAL, true } 274*cdf0e10cSrcweir #define VA { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_ARR, true } 275*cdf0e10cSrcweir #define VR { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPT, true } 276*cdf0e10cSrcweir #define VX { FUNC_PARAM_REGULAR, FUNC_PARAMCONV_RPX, true } 277*cdf0e10cSrcweir #define RO_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_ORG, false } 278*cdf0e10cSrcweir #define VR_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_RPT, true } 279*cdf0e10cSrcweir #define C { FUNC_PARAM_CALCONLY, FUNC_PARAMCONV_ORG, false } 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir // Note: parameter types of all macro sheet functions (FUNCFLAG_MACROFUNC/FUNCFLAG_MACROCMD) untested! 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir /** Functions new in BIFF2. */ 284*cdf0e10cSrcweir static const FunctionData saFuncTableBiff2[] = 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir { "COUNT", "COUNT", 0, 0, 0, MX, V, { RX }, 0 }, 287*cdf0e10cSrcweir { "IF", "IF", 1, 1, 2, 3, R, { VO, RO }, 0 }, 288*cdf0e10cSrcweir { "ISNA", "ISNA", 2, 2, 1, 1, V, { VR }, 0 }, 289*cdf0e10cSrcweir { "ISERROR", "ISERROR", 3, 3, 1, 1, V, { VR }, 0 }, 290*cdf0e10cSrcweir { "SUM", "SUM", 4, 4, 0, MX, V, { RX }, 0 }, 291*cdf0e10cSrcweir { "AVERAGE", "AVERAGE", 5, 5, 1, MX, V, { RX }, 0 }, 292*cdf0e10cSrcweir { "MIN", "MIN", 6, 6, 1, MX, V, { RX }, 0 }, 293*cdf0e10cSrcweir { "MAX", "MAX", 7, 7, 1, MX, V, { RX }, 0 }, 294*cdf0e10cSrcweir { "ROW", "ROW", 8, 8, 0, 1, V, { RO }, 0 }, 295*cdf0e10cSrcweir { "COLUMN", "COLUMN", 9, 9, 0, 1, V, { RO }, 0 }, 296*cdf0e10cSrcweir { "NA", "NA", 10, 10, 0, 0, V, {}, 0 }, 297*cdf0e10cSrcweir { "NPV", "NPV", 11, 11, 2, MX, V, { VR, RX }, 0 }, 298*cdf0e10cSrcweir { "STDEV", "STDEV", 12, 12, 1, MX, V, { RX }, 0 }, 299*cdf0e10cSrcweir { "DOLLAR", "DOLLAR", 13, 13, 1, 2, V, { VR }, 0 }, 300*cdf0e10cSrcweir { "FIXED", "FIXED", 14, 14, 1, 2, V, { VR, VR, C }, 0 }, 301*cdf0e10cSrcweir { "SIN", "SIN", 15, 15, 1, 1, V, { VR }, 0 }, 302*cdf0e10cSrcweir { "CSC", "SIN", 15, 15, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 303*cdf0e10cSrcweir { "COS", "COS", 16, 16, 1, 1, V, { VR }, 0 }, 304*cdf0e10cSrcweir { "SEC", "COS", 16, 16, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 305*cdf0e10cSrcweir { "TAN", "TAN", 17, 17, 1, 1, V, { VR }, 0 }, 306*cdf0e10cSrcweir { "COT", "TAN", 17, 17, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 307*cdf0e10cSrcweir { "ATAN", "ATAN", 18, 18, 1, 1, V, { VR }, 0 }, 308*cdf0e10cSrcweir { "ACOT", "ATAN", 18, 18, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 309*cdf0e10cSrcweir { "PI", "PI", 19, 19, 0, 0, V, {}, 0 }, 310*cdf0e10cSrcweir { "SQRT", "SQRT", 20, 20, 1, 1, V, { VR }, 0 }, 311*cdf0e10cSrcweir { "EXP", "EXP", 21, 21, 1, 1, V, { VR }, 0 }, 312*cdf0e10cSrcweir { "LN", "LN", 22, 22, 1, 1, V, { VR }, 0 }, 313*cdf0e10cSrcweir { "LOG10", "LOG10", 23, 23, 1, 1, V, { VR }, 0 }, 314*cdf0e10cSrcweir { "ABS", "ABS", 24, 24, 1, 1, V, { VR }, 0 }, 315*cdf0e10cSrcweir { "INT", "INT", 25, 25, 1, 1, V, { VR }, 0 }, 316*cdf0e10cSrcweir { "SIGN", "SIGN", 26, 26, 1, 1, V, { VR }, 0 }, 317*cdf0e10cSrcweir { "ROUND", "ROUND", 27, 27, 2, 2, V, { VR }, 0 }, 318*cdf0e10cSrcweir { "LOOKUP", "LOOKUP", 28, 28, 2, 3, V, { VR, RA }, 0 }, 319*cdf0e10cSrcweir { "INDEX", "INDEX", 29, 29, 2, 4, R, { RA, VV }, 0 }, 320*cdf0e10cSrcweir { "REPT", "REPT", 30, 30, 2, 2, V, { VR }, 0 }, 321*cdf0e10cSrcweir { "MID", "MID", 31, 31, 3, 3, V, { VR }, 0 }, 322*cdf0e10cSrcweir { "LEN", "LEN", 32, 32, 1, 1, V, { VR }, 0 }, 323*cdf0e10cSrcweir { "VALUE", "VALUE", 33, 33, 1, 1, V, { VR }, 0 }, 324*cdf0e10cSrcweir { "TRUE", "TRUE", 34, 34, 0, 0, V, {}, 0 }, 325*cdf0e10cSrcweir { "FALSE", "FALSE", 35, 35, 0, 0, V, {}, 0 }, 326*cdf0e10cSrcweir { "AND", "AND", 36, 36, 1, MX, V, { RX }, 0 }, 327*cdf0e10cSrcweir { "OR", "OR", 37, 37, 1, MX, V, { RX }, 0 }, 328*cdf0e10cSrcweir { "NOT", "NOT", 38, 38, 1, 1, V, { VR }, 0 }, 329*cdf0e10cSrcweir { "MOD", "MOD", 39, 39, 2, 2, V, { VR }, 0 }, 330*cdf0e10cSrcweir { "DCOUNT", "DCOUNT", 40, 40, 3, 3, V, { RO, RR }, 0 }, 331*cdf0e10cSrcweir { "DSUM", "DSUM", 41, 41, 3, 3, V, { RO, RR }, 0 }, 332*cdf0e10cSrcweir { "DAVERAGE", "DAVERAGE", 42, 42, 3, 3, V, { RO, RR }, 0 }, 333*cdf0e10cSrcweir { "DMIN", "DMIN", 43, 43, 3, 3, V, { RO, RR }, 0 }, 334*cdf0e10cSrcweir { "DMAX", "DMAX", 44, 44, 3, 3, V, { RO, RR }, 0 }, 335*cdf0e10cSrcweir { "DSTDEV", "DSTDEV", 45, 45, 3, 3, V, { RO, RR }, 0 }, 336*cdf0e10cSrcweir { "VAR", "VAR", 46, 46, 1, MX, V, { RX }, 0 }, 337*cdf0e10cSrcweir { "DVAR", "DVAR", 47, 47, 3, 3, V, { RO, RR }, 0 }, 338*cdf0e10cSrcweir { "TEXT", "TEXT", 48, 48, 2, 2, V, { VR }, 0 }, 339*cdf0e10cSrcweir { "LINEST", "LINEST", 49, 49, 1, 2, A, { RA, RA, C, C }, 0 }, 340*cdf0e10cSrcweir { "TREND", "TREND", 50, 50, 1, 3, A, { RA, RA, RA, C }, 0 }, 341*cdf0e10cSrcweir { "LOGEST", "LOGEST", 51, 51, 1, 2, A, { RA, RA, C, C }, 0 }, 342*cdf0e10cSrcweir { "GROWTH", "GROWTH", 52, 52, 1, 3, A, { RA, RA, RA, C }, 0 }, 343*cdf0e10cSrcweir { "PV", "PV", 56, 56, 3, 5, V, { VR }, 0 }, 344*cdf0e10cSrcweir { "FV", "FV", 57, 57, 3, 5, V, { VR }, 0 }, 345*cdf0e10cSrcweir { "NPER", "NPER", 58, 58, 3, 5, V, { VR }, 0 }, 346*cdf0e10cSrcweir { "PMT", "PMT", 59, 59, 3, 5, V, { VR }, 0 }, 347*cdf0e10cSrcweir { "RATE", "RATE", 60, 60, 3, 6, V, { VR }, 0 }, 348*cdf0e10cSrcweir { "MIRR", "MIRR", 61, 61, 3, 3, V, { RA, VR }, 0 }, 349*cdf0e10cSrcweir { "IRR", "IRR", 62, 62, 1, 2, V, { RA, VR }, 0 }, 350*cdf0e10cSrcweir { "RAND", "RAND", 63, 63, 0, 0, V, {}, FUNCFLAG_VOLATILE }, 351*cdf0e10cSrcweir { "MATCH", "MATCH", 64, 64, 2, 3, V, { VR, RX, RR }, 0 }, 352*cdf0e10cSrcweir { "DATE", "DATE", 65, 65, 3, 3, V, { VR }, 0 }, 353*cdf0e10cSrcweir { "TIME", "TIME", 66, 66, 3, 3, V, { VR }, 0 }, 354*cdf0e10cSrcweir { "DAY", "DAY", 67, 67, 1, 1, V, { VR }, 0 }, 355*cdf0e10cSrcweir { "MONTH", "MONTH", 68, 68, 1, 1, V, { VR }, 0 }, 356*cdf0e10cSrcweir { "YEAR", "YEAR", 69, 69, 1, 1, V, { VR }, 0 }, 357*cdf0e10cSrcweir { "WEEKDAY", "WEEKDAY", 70, 70, 1, 1, V, { VR, C }, 0 }, 358*cdf0e10cSrcweir { "HOUR", "HOUR", 71, 71, 1, 1, V, { VR }, 0 }, 359*cdf0e10cSrcweir { "MINUTE", "MINUTE", 72, 72, 1, 1, V, { VR }, 0 }, 360*cdf0e10cSrcweir { "SECOND", "SECOND", 73, 73, 1, 1, V, { VR }, 0 }, 361*cdf0e10cSrcweir { "NOW", "NOW", 74, 74, 0, 0, V, {}, FUNCFLAG_VOLATILE }, 362*cdf0e10cSrcweir { "AREAS", "AREAS", 75, 75, 1, 1, V, { RO }, 0 }, 363*cdf0e10cSrcweir { "ROWS", "ROWS", 76, 76, 1, 1, V, { RO }, 0 }, 364*cdf0e10cSrcweir { "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { RO }, 0 }, 365*cdf0e10cSrcweir { "OFFSET", "OFFSET", 78, 78, 3, 5, R, { RO, VR }, FUNCFLAG_VOLATILE }, 366*cdf0e10cSrcweir { "SEARCH", "SEARCH", 82, 82, 2, 3, V, { VR }, 0 }, 367*cdf0e10cSrcweir { "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { VO }, 0 }, 368*cdf0e10cSrcweir { "TYPE", "TYPE", 86, 86, 1, 1, V, { VX }, 0 }, 369*cdf0e10cSrcweir { "ATAN2", "ATAN2", 97, 97, 2, 2, V, { VR }, 0 }, 370*cdf0e10cSrcweir { "ASIN", "ASIN", 98, 98, 1, 1, V, { VR }, 0 }, 371*cdf0e10cSrcweir { "ACOS", "ACOS", 99, 99, 1, 1, V, { VR }, 0 }, 372*cdf0e10cSrcweir { "CHOOSE", "CHOOSE", 100, 100, 2, MX, R, { VO, RO }, 0 }, 373*cdf0e10cSrcweir { "HLOOKUP", "HLOOKUP", 101, 101, 3, 3, V, { VV, RO, RO, C }, 0 }, 374*cdf0e10cSrcweir { "VLOOKUP", "VLOOKUP", 102, 102, 3, 3, V, { VV, RO, RO, C }, 0 }, 375*cdf0e10cSrcweir { "ISREF", "ISREF", 105, 105, 1, 1, V, { RX }, 0 }, 376*cdf0e10cSrcweir { "LOG", "LOG", 109, 109, 1, 2, V, { VR }, 0 }, 377*cdf0e10cSrcweir { "CHAR", "CHAR", 111, 111, 1, 1, V, { VR }, 0 }, 378*cdf0e10cSrcweir { "LOWER", "LOWER", 112, 112, 1, 1, V, { VR }, 0 }, 379*cdf0e10cSrcweir { "UPPER", "UPPER", 113, 113, 1, 1, V, { VR }, 0 }, 380*cdf0e10cSrcweir { "PROPER", "PROPER", 114, 114, 1, 1, V, { VR }, 0 }, 381*cdf0e10cSrcweir { "LEFT", "LEFT", 115, 115, 1, 2, V, { VR }, 0 }, 382*cdf0e10cSrcweir { "RIGHT", "RIGHT", 116, 116, 1, 2, V, { VR }, 0 }, 383*cdf0e10cSrcweir { "EXACT", "EXACT", 117, 117, 2, 2, V, { VR }, 0 }, 384*cdf0e10cSrcweir { "TRIM", "TRIM", 118, 118, 1, 1, V, { VR }, 0 }, 385*cdf0e10cSrcweir { "REPLACE", "REPLACE", 119, 119, 4, 4, V, { VR }, 0 }, 386*cdf0e10cSrcweir { "SUBSTITUTE", "SUBSTITUTE", 120, 120, 3, 4, V, { VR }, 0 }, 387*cdf0e10cSrcweir { "CODE", "CODE", 121, 121, 1, 1, V, { VR }, 0 }, 388*cdf0e10cSrcweir { "FIND", "FIND", 124, 124, 2, 3, V, { VR }, 0 }, 389*cdf0e10cSrcweir { "CELL", "CELL", 125, 125, 1, 2, V, { VV, RO }, FUNCFLAG_VOLATILE }, 390*cdf0e10cSrcweir { "ISERR", "ISERR", 126, 126, 1, 1, V, { VR }, 0 }, 391*cdf0e10cSrcweir { "ISTEXT", "ISTEXT", 127, 127, 1, 1, V, { VR }, 0 }, 392*cdf0e10cSrcweir { "ISNUMBER", "ISNUMBER", 128, 128, 1, 1, V, { VR }, 0 }, 393*cdf0e10cSrcweir { "ISBLANK", "ISBLANK", 129, 129, 1, 1, V, { VR }, 0 }, 394*cdf0e10cSrcweir { "T", "T", 130, 130, 1, 1, V, { RO }, 0 }, 395*cdf0e10cSrcweir { "N", "N", 131, 131, 1, 1, V, { RO }, 0 }, 396*cdf0e10cSrcweir { "DATEVALUE", "DATEVALUE", 140, 140, 1, 1, V, { VR }, 0 }, 397*cdf0e10cSrcweir { "TIMEVALUE", "TIMEVALUE", 141, 141, 1, 1, V, { VR }, 0 }, 398*cdf0e10cSrcweir { "SLN", "SLN", 142, 142, 3, 3, V, { VR }, 0 }, 399*cdf0e10cSrcweir { "SYD", "SYD", 143, 143, 4, 4, V, { VR }, 0 }, 400*cdf0e10cSrcweir { "DDB", "DDB", 144, 144, 4, 5, V, { VR }, 0 }, 401*cdf0e10cSrcweir { "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { VR }, FUNCFLAG_VOLATILE }, 402*cdf0e10cSrcweir { "CLEAN", "CLEAN", 162, 162, 1, 1, V, { VR }, 0 }, 403*cdf0e10cSrcweir { "MDETERM", "MDETERM", 163, 163, 1, 1, V, { VA }, 0 }, 404*cdf0e10cSrcweir { "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { VA }, 0 }, 405*cdf0e10cSrcweir { "MMULT", "MMULT", 165, 165, 2, 2, A, { VA }, 0 }, 406*cdf0e10cSrcweir { "IPMT", "IPMT", 167, 167, 4, 6, V, { VR }, 0 }, 407*cdf0e10cSrcweir { "PPMT", "PPMT", 168, 168, 4, 6, V, { VR }, 0 }, 408*cdf0e10cSrcweir { "COUNTA", "COUNTA", 169, 169, 0, MX, V, { RX }, 0 }, 409*cdf0e10cSrcweir { "PRODUCT", "PRODUCT", 183, 183, 0, MX, V, { RX }, 0 }, 410*cdf0e10cSrcweir { "FACT", "FACT", 184, 184, 1, 1, V, { VR }, 0 }, 411*cdf0e10cSrcweir { "DPRODUCT", "DPRODUCT", 189, 189, 3, 3, V, { RO, RR }, 0 }, 412*cdf0e10cSrcweir { "ISNONTEXT", "ISNONTEXT", 190, 190, 1, 1, V, { VR }, 0 }, 413*cdf0e10cSrcweir { "STDEVP", "STDEVP", 193, 193, 1, MX, V, { RX }, 0 }, 414*cdf0e10cSrcweir { "VARP", "VARP", 194, 194, 1, MX, V, { RX }, 0 }, 415*cdf0e10cSrcweir { "DSTDEVP", "DSTDEVP", 195, 195, 3, 3, V, { RO, RR }, 0 }, 416*cdf0e10cSrcweir { "DVARP", "DVARP", 196, 196, 3, 3, V, { RO, RR }, 0 }, 417*cdf0e10cSrcweir { "TRUNC", "TRUNC", 197, 197, 1, 1, V, { VR, C }, 0 }, 418*cdf0e10cSrcweir { "ISLOGICAL", "ISLOGICAL", 198, 198, 1, 1, V, { VR }, 0 }, 419*cdf0e10cSrcweir { "DCOUNTA", "DCOUNTA", 199, 199, 3, 3, V, { RO, RR }, 0 }, 420*cdf0e10cSrcweir { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_IMPORTONLY }, 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // *** macro sheet commands *** 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir { 0, "A1.R1C1", 30, 30, 0, 1, V, { VR }, FUNCFLAG_MACROCMD }, 425*cdf0e10cSrcweir { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC }, 426*cdf0e10cSrcweir { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC }, 427*cdf0e10cSrcweir { 0, "ADD.ARROW", 81, 81, 0, 0, V, {}, FUNCFLAG_MACROCMD }, 428*cdf0e10cSrcweir { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC }, 429*cdf0e10cSrcweir { 0, "ACTIVATE", 103, 103, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, 430*cdf0e10cSrcweir { 0, "ACTIVATE.NEXT", 104, 104, 0, 0, V, {}, FUNCFLAG_MACROCMD }, 431*cdf0e10cSrcweir { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD }, 432*cdf0e10cSrcweir { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, 433*cdf0e10cSrcweir { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, 434*cdf0e10cSrcweir { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR } 435*cdf0e10cSrcweir }; 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir /** Functions new in BIFF3. */ 438*cdf0e10cSrcweir static const FunctionData saFuncTableBiff3[] = 439*cdf0e10cSrcweir { 440*cdf0e10cSrcweir { "LINEST", "LINEST", 49, 49, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 441*cdf0e10cSrcweir { "TREND", "TREND", 50, 50, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 442*cdf0e10cSrcweir { "LOGEST", "LOGEST", 51, 51, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 443*cdf0e10cSrcweir { "GROWTH", "GROWTH", 52, 52, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 444*cdf0e10cSrcweir { "TRUNC", "TRUNC", 197, 197, 1, 2, V, { VR }, 0 }, // BIFF2: 1, BIFF3: 1-2 445*cdf0e10cSrcweir { "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, 446*cdf0e10cSrcweir { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 }, 447*cdf0e10cSrcweir { 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { VR }, 0 }, 448*cdf0e10cSrcweir { 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { VR }, 0 }, 449*cdf0e10cSrcweir { 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { VR }, 0 }, 450*cdf0e10cSrcweir { 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 }, 451*cdf0e10cSrcweir { 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { VR }, 0 }, 452*cdf0e10cSrcweir { 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { VR }, 0 }, 453*cdf0e10cSrcweir { "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { VR }, 0 }, 454*cdf0e10cSrcweir { "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { VR }, 0 }, 455*cdf0e10cSrcweir { "ASC", "ASC", 214, 214, 1, 1, V, { VR }, 0 }, 456*cdf0e10cSrcweir { "JIS", "DBCS", 215, 215, 1, 1, V, { VR }, 0 }, 457*cdf0e10cSrcweir { "ADDRESS", "ADDRESS", 219, 219, 2, 5, V, { VR }, 0 }, 458*cdf0e10cSrcweir { "DAYS360", "DAYS360", 220, 220, 2, 2, V, { VR, VR, C }, 0 }, 459*cdf0e10cSrcweir { "TODAY", "TODAY", 221, 221, 0, 0, V, {}, FUNCFLAG_VOLATILE }, 460*cdf0e10cSrcweir { "VDB", "VDB", 222, 222, 5, 7, V, { VR }, 0 }, 461*cdf0e10cSrcweir { "MEDIAN", "MEDIAN", 227, 227, 1, MX, V, { RX }, 0 }, 462*cdf0e10cSrcweir { "SUMPRODUCT", "SUMPRODUCT", 228, 228, 1, MX, V, { VA }, 0 }, 463*cdf0e10cSrcweir { "SINH", "SINH", 229, 229, 1, 1, V, { VR }, 0 }, 464*cdf0e10cSrcweir { "CSCH", "SINH", 229, 229, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 465*cdf0e10cSrcweir { "COSH", "COSH", 230, 230, 1, 1, V, { VR }, 0 }, 466*cdf0e10cSrcweir { "SECH", "COSH", 230, 230, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 467*cdf0e10cSrcweir { "TANH", "TANH", 231, 231, 1, 1, V, { VR }, 0 }, 468*cdf0e10cSrcweir { "COTH", "TANH", 231, 231, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 469*cdf0e10cSrcweir { "ASINH", "ASINH", 232, 232, 1, 1, V, { VR }, 0 }, 470*cdf0e10cSrcweir { "ACOSH", "ACOSH", 233, 233, 1, 1, V, { VR }, 0 }, 471*cdf0e10cSrcweir { "ATANH", "ATANH", 234, 234, 1, 1, V, { VR }, 0 }, 472*cdf0e10cSrcweir { "ACOTH", "ATANH", 234, 234, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, 473*cdf0e10cSrcweir { "DGET", "DGET", 235, 235, 3, 3, V, { RO, RR }, 0 }, 474*cdf0e10cSrcweir { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE }, 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir // *** macro sheet commands *** 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1 479*cdf0e10cSrcweir { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3 480*cdf0e10cSrcweir { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC } // BIFF2: 3, BIFF3: 3-4 481*cdf0e10cSrcweir }; 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir /** Functions new in BIFF4. */ 484*cdf0e10cSrcweir static const FunctionData saFuncTableBiff4[] = 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir { "FIXED", "FIXED", 14, 14, 1, 3, V, { VR }, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3 487*cdf0e10cSrcweir { "RANK", "RANK", 216, 216, 2, 3, V, { VR, RO, VR }, 0 }, 488*cdf0e10cSrcweir { "DB", "DB", 247, 247, 4, 5, V, { VR }, 0 }, 489*cdf0e10cSrcweir { "FREQUENCY", "FREQUENCY", 252, 252, 2, 2, A, { RA }, 0 }, 490*cdf0e10cSrcweir { "ORG.OPENOFFICE.ERRORTYPE","ERROR.TYPE", 261, 261, 1, 1, V, { VR }, 0 }, 491*cdf0e10cSrcweir { "AVEDEV", "AVEDEV", 269, 269, 1, MX, V, { RX }, 0 }, 492*cdf0e10cSrcweir { "BETADIST", "BETADIST", 270, 270, 3, 5, V, { VR }, 0 }, 493*cdf0e10cSrcweir { "GAMMALN", "GAMMALN", 271, 271, 1, 1, V, { VR }, 0 }, 494*cdf0e10cSrcweir { "BETAINV", "BETAINV", 272, 272, 3, 5, V, { VR }, 0 }, 495*cdf0e10cSrcweir { "BINOMDIST", "BINOMDIST", 273, 273, 4, 4, V, { VR }, 0 }, 496*cdf0e10cSrcweir { "LEGACY.CHIDIST", "CHIDIST", 274, 274, 2, 2, V, { VR }, 0 }, 497*cdf0e10cSrcweir { "LEGACY.CHIINV", "CHIINV", 275, 275, 2, 2, V, { VR }, 0 }, 498*cdf0e10cSrcweir { "COMBIN", "COMBIN", 276, 276, 2, 2, V, { VR }, 0 }, 499*cdf0e10cSrcweir { "CONFIDENCE", "CONFIDENCE", 277, 277, 3, 3, V, { VR }, 0 }, 500*cdf0e10cSrcweir { "CRITBINOM", "CRITBINOM", 278, 278, 3, 3, V, { VR }, 0 }, 501*cdf0e10cSrcweir { "EVEN", "EVEN", 279, 279, 1, 1, V, { VR }, 0 }, 502*cdf0e10cSrcweir { "EXPONDIST", "EXPONDIST", 280, 280, 3, 3, V, { VR }, 0 }, 503*cdf0e10cSrcweir { "LEGACY.FDIST", "FDIST", 281, 281, 3, 3, V, { VR }, 0 }, 504*cdf0e10cSrcweir { "LEGACY.FINV", "FINV", 282, 282, 3, 3, V, { VR }, 0 }, 505*cdf0e10cSrcweir { "FISHER", "FISHER", 283, 283, 1, 1, V, { VR }, 0 }, 506*cdf0e10cSrcweir { "FISHERINV", "FISHERINV", 284, 284, 1, 1, V, { VR }, 0 }, 507*cdf0e10cSrcweir { "FLOOR", "FLOOR", 285, 285, 2, 2, V, { VR, VR, C }, 0 }, 508*cdf0e10cSrcweir { "GAMMADIST", "GAMMADIST", 286, 286, 4, 4, V, { VR }, 0 }, 509*cdf0e10cSrcweir { "GAMMAINV", "GAMMAINV", 287, 287, 3, 3, V, { VR }, 0 }, 510*cdf0e10cSrcweir { "CEILING", "CEILING", 288, 288, 2, 2, V, { VR, VR, C }, 0 }, 511*cdf0e10cSrcweir { "HYPGEOMDIST", "HYPGEOMDIST", 289, 289, 4, 4, V, { VR }, 0 }, 512*cdf0e10cSrcweir { "LOGNORMDIST", "LOGNORMDIST", 290, 290, 3, 3, V, { VR }, 0 }, 513*cdf0e10cSrcweir { "LOGINV", "LOGINV", 291, 291, 3, 3, V, { VR }, 0 }, 514*cdf0e10cSrcweir { "NEGBINOMDIST", "NEGBINOMDIST", 292, 292, 3, 3, V, { VR }, 0 }, 515*cdf0e10cSrcweir { "NORMDIST", "NORMDIST", 293, 293, 4, 4, V, { VR }, 0 }, 516*cdf0e10cSrcweir { "LEGACY.NORMSDIST", "NORMSDIST", 294, 294, 1, 1, V, { VR }, 0 }, 517*cdf0e10cSrcweir { "NORMINV", "NORMINV", 295, 295, 3, 3, V, { VR }, 0 }, 518*cdf0e10cSrcweir { "LEGACY.NORMSINV", "NORMSINV", 296, 296, 1, 1, V, { VR }, 0 }, 519*cdf0e10cSrcweir { "STANDARDIZE", "STANDARDIZE", 297, 297, 3, 3, V, { VR }, 0 }, 520*cdf0e10cSrcweir { "ODD", "ODD", 298, 298, 1, 1, V, { VR }, 0 }, 521*cdf0e10cSrcweir { "PERMUT", "PERMUT", 299, 299, 2, 2, V, { VR }, 0 }, 522*cdf0e10cSrcweir { "POISSON", "POISSON", 300, 300, 3, 3, V, { VR }, 0 }, 523*cdf0e10cSrcweir { "TDIST", "TDIST", 301, 301, 3, 3, V, { VR }, 0 }, 524*cdf0e10cSrcweir { "WEIBULL", "WEIBULL", 302, 302, 4, 4, V, { VR }, 0 }, 525*cdf0e10cSrcweir { "SUMXMY2", "SUMXMY2", 303, 303, 2, 2, V, { VA }, 0 }, 526*cdf0e10cSrcweir { "SUMX2MY2", "SUMX2MY2", 304, 304, 2, 2, V, { VA }, 0 }, 527*cdf0e10cSrcweir { "SUMX2PY2", "SUMX2PY2", 305, 305, 2, 2, V, { VA }, 0 }, 528*cdf0e10cSrcweir { "LEGACY.CHITEST", "CHITEST", 306, 306, 2, 2, V, { VA }, 0 }, 529*cdf0e10cSrcweir { "CORREL", "CORREL", 307, 307, 2, 2, V, { VA }, 0 }, 530*cdf0e10cSrcweir { "COVAR", "COVAR", 308, 308, 2, 2, V, { VA }, 0 }, 531*cdf0e10cSrcweir { "FORECAST", "FORECAST", 309, 309, 3, 3, V, { VR, VA }, 0 }, 532*cdf0e10cSrcweir { "FTEST", "FTEST", 310, 310, 2, 2, V, { VA }, 0 }, 533*cdf0e10cSrcweir { "INTERCEPT", "INTERCEPT", 311, 311, 2, 2, V, { VA }, 0 }, 534*cdf0e10cSrcweir { "PEARSON", "PEARSON", 312, 312, 2, 2, V, { VA }, 0 }, 535*cdf0e10cSrcweir { "RSQ", "RSQ", 313, 313, 2, 2, V, { VA }, 0 }, 536*cdf0e10cSrcweir { "STEYX", "STEYX", 314, 314, 2, 2, V, { VA }, 0 }, 537*cdf0e10cSrcweir { "SLOPE", "SLOPE", 315, 315, 2, 2, V, { VA }, 0 }, 538*cdf0e10cSrcweir { "TTEST", "TTEST", 316, 316, 4, 4, V, { VA, VA, VR }, 0 }, 539*cdf0e10cSrcweir { "PROB", "PROB", 317, 317, 3, 4, V, { VA, VA, VR }, 0 }, 540*cdf0e10cSrcweir { "DEVSQ", "DEVSQ", 318, 318, 1, MX, V, { RX }, 0 }, 541*cdf0e10cSrcweir { "GEOMEAN", "GEOMEAN", 319, 319, 1, MX, V, { RX }, 0 }, 542*cdf0e10cSrcweir { "HARMEAN", "HARMEAN", 320, 320, 1, MX, V, { RX }, 0 }, 543*cdf0e10cSrcweir { "SUMSQ", "SUMSQ", 321, 321, 0, MX, V, { RX }, 0 }, 544*cdf0e10cSrcweir { "KURT", "KURT", 322, 322, 1, MX, V, { RX }, 0 }, 545*cdf0e10cSrcweir { "SKEW", "SKEW", 323, 323, 1, MX, V, { RX }, 0 }, 546*cdf0e10cSrcweir { "ZTEST", "ZTEST", 324, 324, 2, 3, V, { RX, VR }, 0 }, 547*cdf0e10cSrcweir { "LARGE", "LARGE", 325, 325, 2, 2, V, { RX, VR }, 0 }, 548*cdf0e10cSrcweir { "SMALL", "SMALL", 326, 326, 2, 2, V, { RX, VR }, 0 }, 549*cdf0e10cSrcweir { "QUARTILE", "QUARTILE", 327, 327, 2, 2, V, { RX, VR }, 0 }, 550*cdf0e10cSrcweir { "PERCENTILE", "PERCENTILE", 328, 328, 2, 2, V, { RX, VR }, 0 }, 551*cdf0e10cSrcweir { "PERCENTRANK", "PERCENTRANK", 329, 329, 2, 3, V, { RX, VR, VR_E }, 0 }, 552*cdf0e10cSrcweir { "MODE", "MODE", 330, 330, 1, MX, V, { VA }, 0 }, 553*cdf0e10cSrcweir { "TRIMMEAN", "TRIMMEAN", 331, 331, 2, 2, V, { RX, VR }, 0 }, 554*cdf0e10cSrcweir { "TINV", "TINV", 332, 332, 2, 2, V, { VR }, 0 }, 555*cdf0e10cSrcweir 556*cdf0e10cSrcweir // *** Analysis add-in *** 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir { "HEX2BIN", "HEX2BIN", 384, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 559*cdf0e10cSrcweir { "HEX2DEC", "HEX2DEC", 385, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 560*cdf0e10cSrcweir { "HEX2OCT", "HEX2OCT", 386, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 561*cdf0e10cSrcweir { "DEC2BIN", "DEC2BIN", 387, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 562*cdf0e10cSrcweir { "DEC2HEX", "DEC2HEX", 388, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 563*cdf0e10cSrcweir { "DEC2OCT", "DEC2OCT", 389, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 564*cdf0e10cSrcweir { "OCT2BIN", "OCT2BIN", 390, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 565*cdf0e10cSrcweir { "OCT2HEX", "OCT2HEX", 391, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 566*cdf0e10cSrcweir { "OCT2DEC", "OCT2DEC", 392, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 567*cdf0e10cSrcweir { "BIN2DEC", "BIN2DEC", 393, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 568*cdf0e10cSrcweir { "BIN2OCT", "BIN2OCT", 394, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 569*cdf0e10cSrcweir { "BIN2HEX", "BIN2HEX", 395, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 570*cdf0e10cSrcweir { "IMSUB", "IMSUB", 396, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 571*cdf0e10cSrcweir { "IMDIV", "IMDIV", 397, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 572*cdf0e10cSrcweir { "IMPOWER", "IMPOWER", 398, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 573*cdf0e10cSrcweir { "IMABS", "IMABS", 399, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 574*cdf0e10cSrcweir { "IMSQRT", "IMSQRT", 400, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 575*cdf0e10cSrcweir { "IMLN", "IMLN", 401, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 576*cdf0e10cSrcweir { "IMLOG2", "IMLOG2", 402, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 577*cdf0e10cSrcweir { "IMLOG10", "IMLOG10", 403, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 578*cdf0e10cSrcweir { "IMSIN", "IMSIN", 404, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 579*cdf0e10cSrcweir { "IMCOS", "IMCOS", 405, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 580*cdf0e10cSrcweir { "IMEXP", "IMEXP", 406, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 581*cdf0e10cSrcweir { "IMARGUMENT", "IMARGUMENT", 407, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 582*cdf0e10cSrcweir { "IMCONJUGATE", "IMCONJUGATE", 408, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 583*cdf0e10cSrcweir { "IMAGINARY", "IMAGINARY", 409, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 584*cdf0e10cSrcweir { "IMREAL", "IMREAL", 410, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 585*cdf0e10cSrcweir { "COMPLEX", "COMPLEX", 411, NOID, 2, 3, V, { RR }, FUNCFLAG_EXTERNAL }, 586*cdf0e10cSrcweir { "IMSUM", "IMSUM", 412, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, 587*cdf0e10cSrcweir { "IMPRODUCT", "IMPRODUCT", 413, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, 588*cdf0e10cSrcweir { "SERIESSUM", "SERIESSUM", 414, NOID, 4, 4, V, { RR, RR, RR, RX }, FUNCFLAG_EXTERNAL }, 589*cdf0e10cSrcweir { "FACTDOUBLE", "FACTDOUBLE", 415, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 590*cdf0e10cSrcweir { "SQRTPI", "SQRTPI", 416, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 591*cdf0e10cSrcweir { "QUOTIENT", "QUOTIENT", 417, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 592*cdf0e10cSrcweir { "DELTA", "DELTA", 418, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 593*cdf0e10cSrcweir { "GESTEP", "GESTEP", 419, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 594*cdf0e10cSrcweir { "ISEVEN", "ISEVEN", 420, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 595*cdf0e10cSrcweir { "ISODD", "ISODD", 421, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 596*cdf0e10cSrcweir { "MROUND", "MROUND", 422, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 597*cdf0e10cSrcweir { "ERF", "ERF", 423, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 598*cdf0e10cSrcweir { "ERFC", "ERFC", 424, NOID, 1, 1, V, { RR }, FUNCFLAG_EXTERNAL }, 599*cdf0e10cSrcweir { "BESSELJ", "BESSELJ", 425, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 600*cdf0e10cSrcweir { "BESSELK", "BESSELK", 426, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 601*cdf0e10cSrcweir { "BESSELY", "BESSELY", 427, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 602*cdf0e10cSrcweir { "BESSELI", "BESSELI", 428, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 603*cdf0e10cSrcweir { "XIRR", "XIRR", 429, NOID, 2, 3, V, { RX, RX, RR }, FUNCFLAG_EXTERNAL }, 604*cdf0e10cSrcweir { "XNPV", "XNPV", 430, NOID, 3, 3, V, { RR, RX, RX }, FUNCFLAG_EXTERNAL }, 605*cdf0e10cSrcweir { "PRICEMAT", "PRICEMAT", 431, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, 606*cdf0e10cSrcweir { "YIELDMAT", "YIELDMAT", 432, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, 607*cdf0e10cSrcweir { "INTRATE", "INTRATE", 433, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, 608*cdf0e10cSrcweir { "RECEIVED", "RECEIVED", 434, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, 609*cdf0e10cSrcweir { "DISC", "DISC", 435, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, 610*cdf0e10cSrcweir { "PRICEDISC", "PRICEDISC", 436, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, 611*cdf0e10cSrcweir { "YIELDDISC", "YIELDDISC", 437, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, 612*cdf0e10cSrcweir { "TBILLEQ", "TBILLEQ", 438, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, 613*cdf0e10cSrcweir { "TBILLPRICE", "TBILLPRICE", 439, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, 614*cdf0e10cSrcweir { "TBILLYIELD", "TBILLYIELD", 440, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, 615*cdf0e10cSrcweir { "PRICE", "PRICE", 441, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, 616*cdf0e10cSrcweir { "YIELD", "YIELD", 442, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, 617*cdf0e10cSrcweir { "DOLLARDE", "DOLLARDE", 443, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 618*cdf0e10cSrcweir { "DOLLARFR", "DOLLARFR", 444, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 619*cdf0e10cSrcweir { "NOMINAL", "NOMINAL", 445, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 620*cdf0e10cSrcweir { "EFFECT", "EFFECT", 446, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 621*cdf0e10cSrcweir { "CUMPRINC", "CUMPRINC", 447, NOID, 6, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 622*cdf0e10cSrcweir { "CUMIPMT", "CUMIPMT", 448, NOID, 6, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 623*cdf0e10cSrcweir { "EDATE", "EDATE", 449, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 624*cdf0e10cSrcweir { "EOMONTH", "EOMONTH", 450, NOID, 2, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 625*cdf0e10cSrcweir { "YEARFRAC", "YEARFRAC", 451, NOID, 2, 3, V, { RR }, FUNCFLAG_EXTERNAL }, 626*cdf0e10cSrcweir { "COUPDAYBS", "COUPDAYBS", 452, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, 627*cdf0e10cSrcweir { "COUPDAYS", "COUPDAYS", 453, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, 628*cdf0e10cSrcweir { "COUPDAYSNC", "COUPDAYSNC", 454, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, 629*cdf0e10cSrcweir { "COUPNCD", "COUPNCD", 455, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, 630*cdf0e10cSrcweir { "COUPNUM", "COUPNUM", 456, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, 631*cdf0e10cSrcweir { "COUPPCD", "COUPPCD", 457, NOID, 3, 4, V, { RR }, FUNCFLAG_EXTERNAL }, 632*cdf0e10cSrcweir { "DURATION", "DURATION", 458, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 633*cdf0e10cSrcweir { "MDURATION", "MDURATION", 459, NOID, 5, 6, V, { RR }, FUNCFLAG_EXTERNAL }, 634*cdf0e10cSrcweir { "ODDLPRICE", "ODDLPRICE", 460, NOID, 7, 8, V, { RR }, FUNCFLAG_EXTERNAL }, 635*cdf0e10cSrcweir { "ODDLYIELD", "ODDLYIELD", 461, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL }, 636*cdf0e10cSrcweir { "ODDFPRICE", "ODDFPRICE", 462, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL }, 637*cdf0e10cSrcweir { "ODDFYIELD", "ODDFYIELD", 463, NOID, 8, 9, V, { RR }, FUNCFLAG_EXTERNAL }, 638*cdf0e10cSrcweir { "RANDBETWEEN", "RANDBETWEEN", 464, NOID, 2, 2, V, { RR }, FUNCFLAG_VOLATILE | FUNCFLAG_EXTERNAL }, 639*cdf0e10cSrcweir { "WEEKNUM", "WEEKNUM", 465, NOID, 1, 2, V, { RR }, FUNCFLAG_EXTERNAL }, 640*cdf0e10cSrcweir { "AMORDEGRC", "AMORDEGRC", 466, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, 641*cdf0e10cSrcweir { "AMORLINC", "AMORLINC", 467, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, 642*cdf0e10cSrcweir { "CONVERT", "CONVERT", 468, NOID, 3, 3, V, { RR }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 643*cdf0e10cSrcweir { "ACCRINT", "ACCRINT", 469, NOID, 6, 7, V, { RR }, FUNCFLAG_EXTERNAL }, 644*cdf0e10cSrcweir { "ACCRINTM", "ACCRINTM", 470, NOID, 4, 5, V, { RR }, FUNCFLAG_EXTERNAL }, 645*cdf0e10cSrcweir { "WORKDAY", "WORKDAY", 471, NOID, 2, 3, V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL }, 646*cdf0e10cSrcweir { "NETWORKDAYS", "NETWORKDAYS", 472, NOID, 2, 3, V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL }, 647*cdf0e10cSrcweir { "GCD", "GCD", 473, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 648*cdf0e10cSrcweir { "MULTINOMIAL", "MULTINOMIAL", 474, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, 649*cdf0e10cSrcweir { "LCM", "LCM", 475, NOID, 1, MX, V, { RX }, FUNCFLAG_EXTERNAL }, // Calc: builtin and add-in 650*cdf0e10cSrcweir { "FVSCHEDULE", "FVSCHEDULE", 476, NOID, 2, 2, V, { RR, RX }, FUNCFLAG_EXTERNAL }, 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir // *** macro sheet commands *** 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir { 0, "ACTIVATE.NEXT", 104, 104, 0, 1, V, { VR }, FUNCFLAG_MACROCMD }, // BIFF2-3: 0, BIFF4: 0-1 655*cdf0e10cSrcweir { 0, "ACTIVATE.PREV", 105, 105, 0, 1, V, { VR }, FUNCFLAG_MACROCMD } // BIFF2-3: 0, BIFF4: 0-1 656*cdf0e10cSrcweir }; 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir /** Functions new in BIFF5/BIFF7. */ 659*cdf0e10cSrcweir static const FunctionData saFuncTableBiff5[] = 660*cdf0e10cSrcweir { 661*cdf0e10cSrcweir { "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { VR }, 0 }, // BIFF2-4: 1, BIFF5: 1-2 662*cdf0e10cSrcweir { "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 663*cdf0e10cSrcweir { "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 664*cdf0e10cSrcweir { "DAYS360", "DAYS360", 220, 220, 2, 3, V, { VR }, 0 }, // BIFF3-4: 2, BIFF5: 2-3 665*cdf0e10cSrcweir { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL 666*cdf0e10cSrcweir { "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { VR }, 0 }, 667*cdf0e10cSrcweir { "POWER", "POWER", 337, 337, 2, 2, V, { VR }, 0 }, 668*cdf0e10cSrcweir { "RADIANS", "RADIANS", 342, 342, 1, 1, V, { VR }, 0 }, 669*cdf0e10cSrcweir { "DEGREES", "DEGREES", 343, 343, 1, 1, V, { VR }, 0 }, 670*cdf0e10cSrcweir { "SUBTOTAL", "SUBTOTAL", 344, 344, 2, MX, V, { VR, RO }, 0 }, 671*cdf0e10cSrcweir { "SUMIF", "SUMIF", 345, 345, 2, 3, V, { RO, VR, RO }, 0 }, 672*cdf0e10cSrcweir { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { RO, VR }, 0 }, 673*cdf0e10cSrcweir { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 }, 674*cdf0e10cSrcweir { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 }, 675*cdf0e10cSrcweir { 0, "DATEDIF", 351, 351, 3, 3, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc 676*cdf0e10cSrcweir { 0, "DATESTRING", 352, 352, 1, 1, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec 677*cdf0e10cSrcweir { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec 678*cdf0e10cSrcweir { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { VR }, 0 }, 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir // *** EuroTool add-in *** 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir { "EUROCONVERT", "EUROCONVERT", NOID, NOID, 3, 5, V, { VR }, FUNCLIB_TO_FUNCFLAGS( FUNCLIB_EUROTOOL ) }, 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir // *** macro sheet commands *** 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4 687*cdf0e10cSrcweir { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5 688*cdf0e10cSrcweir { 0, "ADD.CHART.AUTOFORMAT", 390, 390, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, 689*cdf0e10cSrcweir { 0, "ADD.LIST.ITEM", 451, 451, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, 690*cdf0e10cSrcweir { 0, "ACTIVE.CELL.FONT", 476, 476, 0, 14, V, { VR }, FUNCFLAG_MACROCMD } 691*cdf0e10cSrcweir }; 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir /** Functions new in BIFF8. */ 694*cdf0e10cSrcweir static const FunctionData saFuncTableBiff8[] = 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir { "GETPIVOTDATA", "GETPIVOTDATA", 358, 358, 2, MX, V, { RR, RR, VR, VR }, FUNCFLAG_IMPORTONLY | FUNCFLAG_PARAMPAIRS }, 697*cdf0e10cSrcweir { "HYPERLINK", "HYPERLINK", 359, 359, 1, 2, V, { VV, VO }, 0 }, 698*cdf0e10cSrcweir { 0, "PHONETIC", 360, 360, 1, 1, V, { RO }, FUNCFLAG_IMPORTONLY }, 699*cdf0e10cSrcweir { "AVERAGEA", "AVERAGEA", 361, 361, 1, MX, V, { RX }, 0 }, 700*cdf0e10cSrcweir { "MAXA", "MAXA", 362, 362, 1, MX, V, { RX }, 0 }, 701*cdf0e10cSrcweir { "MINA", "MINA", 363, 363, 1, MX, V, { RX }, 0 }, 702*cdf0e10cSrcweir { "STDEVPA", "STDEVPA", 364, 364, 1, MX, V, { RX }, 0 }, 703*cdf0e10cSrcweir { "VARPA", "VARPA", 365, 365, 1, MX, V, { RX }, 0 }, 704*cdf0e10cSrcweir { "STDEVA", "STDEVA", 366, 366, 1, MX, V, { RX }, 0 }, 705*cdf0e10cSrcweir { "VARA", "VARA", 367, 367, 1, MX, V, { RX }, 0 }, 706*cdf0e10cSrcweir { "COM.MICROSOFT.BAHTTEXT", "BAHTTEXT", 368, 368, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 707*cdf0e10cSrcweir { 0, "THAIDAYOFWEEK", 369, 369, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 708*cdf0e10cSrcweir { 0, "THAIDIGIT", 370, 370, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 709*cdf0e10cSrcweir { 0, "THAIMONTHOFYEAR", 371, 371, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 710*cdf0e10cSrcweir { 0, "THAINUMSOUND", 372, 372, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 711*cdf0e10cSrcweir { 0, "THAINUMSTRING", 373, 373, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 712*cdf0e10cSrcweir { 0, "THAISTRINGLENGTH", 374, 374, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 713*cdf0e10cSrcweir { 0, "ISTHAIDIGIT", 375, 375, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 714*cdf0e10cSrcweir { 0, "ROUNDBAHTDOWN", 376, 376, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 715*cdf0e10cSrcweir { 0, "ROUNDBAHTUP", 377, 377, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 716*cdf0e10cSrcweir { 0, "THAIYEAR", 378, 378, 1, 1, V, { VR }, FUNCFLAG_MACROCALL }, 717*cdf0e10cSrcweir { 0, "RTD", 379, 379, 3, 3, A, { VR, VR, RO }, 0 } 718*cdf0e10cSrcweir }; 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir /** Functions new in OOXML. */ 721*cdf0e10cSrcweir static const FunctionData saFuncTableOox[] = 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir { 0, "CUBEVALUE", 380, NOID, 1, MX, V, { VR, RX }, 0 }, 724*cdf0e10cSrcweir { 0, "CUBEMEMBER", 381, NOID, 2, 3, V, { VR, RX, VR }, 0 }, 725*cdf0e10cSrcweir { 0, "CUBEMEMBERPROPERTY", 382, NOID, 3, 3, V, { VR }, 0 }, 726*cdf0e10cSrcweir { 0, "CUBERANKEDMEMBER", 383, NOID, 3, 4, V, { VR }, 0 }, 727*cdf0e10cSrcweir { 0, "CUBEKPIMEMBER", 477, NOID, 3, 4, V, { VR }, 0 }, 728*cdf0e10cSrcweir { 0, "CUBESET", 478, NOID, 2, 5, V, { VR, RX, VR }, 0 }, 729*cdf0e10cSrcweir { 0, "CUBESETCOUNT", 479, NOID, 1, 1, V, { VR }, 0 }, 730*cdf0e10cSrcweir { 0, "IFERROR", 480, NOID, 2, 2, V, { VO, RO }, 0 }, 731*cdf0e10cSrcweir { 0, "COUNTIFS", 481, NOID, 2, MX, V, { RO, VR }, FUNCFLAG_PARAMPAIRS }, 732*cdf0e10cSrcweir { 0, "SUMIFS", 482, NOID, 3, MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS }, 733*cdf0e10cSrcweir { 0, "AVERAGEIF", 483, NOID, 2, 3, V, { RO, VR, RO }, 0 }, 734*cdf0e10cSrcweir { 0, "AVERAGEIFS", 484, NOID, 3, MX, V, { RO, RO, VR }, 0 } 735*cdf0e10cSrcweir }; 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir /** Functions defined by OpenFormula, but not supported by Calc or by Excel. */ 738*cdf0e10cSrcweir static const FunctionData saFuncTableOdf[] = 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, 741*cdf0e10cSrcweir { "B", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF }, 742*cdf0e10cSrcweir { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, 743*cdf0e10cSrcweir { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 744*cdf0e10cSrcweir { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 745*cdf0e10cSrcweir { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 746*cdf0e10cSrcweir { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 747*cdf0e10cSrcweir { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 748*cdf0e10cSrcweir { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, 749*cdf0e10cSrcweir { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 750*cdf0e10cSrcweir { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 751*cdf0e10cSrcweir { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 752*cdf0e10cSrcweir { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 753*cdf0e10cSrcweir { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF }, 754*cdf0e10cSrcweir { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, 755*cdf0e10cSrcweir { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, 756*cdf0e10cSrcweir { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, 757*cdf0e10cSrcweir { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, 758*cdf0e10cSrcweir { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, FUNCFLAG_MACROCALLODF }, 759*cdf0e10cSrcweir { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, 760*cdf0e10cSrcweir { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 761*cdf0e10cSrcweir { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, FUNCFLAG_MACROCALLODF }, 762*cdf0e10cSrcweir { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 763*cdf0e10cSrcweir { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, 764*cdf0e10cSrcweir { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 765*cdf0e10cSrcweir { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, 766*cdf0e10cSrcweir { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, 767*cdf0e10cSrcweir { "SHEET", 0, NOID, NOID, 0, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, 768*cdf0e10cSrcweir { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, 769*cdf0e10cSrcweir { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF }, 770*cdf0e10cSrcweir { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, 771*cdf0e10cSrcweir { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, 772*cdf0e10cSrcweir { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF } 773*cdf0e10cSrcweir }; 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 776*cdf0e10cSrcweir 777*cdf0e10cSrcweir const sal_Unicode API_TOKEN_OPEN = '('; 778*cdf0e10cSrcweir const sal_Unicode API_TOKEN_CLOSE = ')'; 779*cdf0e10cSrcweir const sal_Unicode API_TOKEN_SEP = ';'; 780*cdf0e10cSrcweir 781*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_OPEN = '{'; 782*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_CLOSE = '}'; 783*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_ROWSEP = '|'; 784*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_COLSEP = ';'; 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir } // namespace 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir // function info parameter class iterator ===================================== 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir FunctionParamInfoIterator::FunctionParamInfoIterator( const FunctionInfo& rFuncInfo ) : 791*cdf0e10cSrcweir mpParamInfo( rFuncInfo.mpParamInfos ), 792*cdf0e10cSrcweir mpParamInfoEnd( rFuncInfo.mpParamInfos + FUNCINFO_PARAMINFOCOUNT ), 793*cdf0e10cSrcweir mbParamPairs( rFuncInfo.mbParamPairs ) 794*cdf0e10cSrcweir { 795*cdf0e10cSrcweir OSL_ENSURE( !mbParamPairs || (mpParamInfo + 1 < mpParamInfoEnd), 796*cdf0e10cSrcweir "FunctionParamInfoIterator::FunctionParamInfoIterator - expecting at least 2 infos for paired parameters" ); 797*cdf0e10cSrcweir } 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir const FunctionParamInfo& FunctionParamInfoIterator::getParamInfo() const 800*cdf0e10cSrcweir { 801*cdf0e10cSrcweir static const FunctionParamInfo saInvalidInfo = { FUNC_PARAM_NONE, FUNC_PARAMCONV_ORG, false }; 802*cdf0e10cSrcweir return mpParamInfo ? *mpParamInfo : saInvalidInfo; 803*cdf0e10cSrcweir } 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir bool FunctionParamInfoIterator::isCalcOnlyParam() const 806*cdf0e10cSrcweir { 807*cdf0e10cSrcweir return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_CALCONLY); 808*cdf0e10cSrcweir } 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir bool FunctionParamInfoIterator::isExcelOnlyParam() const 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_EXCELONLY); 813*cdf0e10cSrcweir } 814*cdf0e10cSrcweir 815*cdf0e10cSrcweir FunctionParamInfoIterator& FunctionParamInfoIterator::operator++() 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir if( mpParamInfo ) 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir // move pointer to next entry, if something explicit follows 820*cdf0e10cSrcweir if( (mpParamInfo + 1 < mpParamInfoEnd) && (mpParamInfo[ 1 ].meValid != FUNC_PARAM_NONE) ) 821*cdf0e10cSrcweir ++mpParamInfo; 822*cdf0e10cSrcweir // points to last info, but parameter pairs expected, move to previous info 823*cdf0e10cSrcweir else if( mbParamPairs ) 824*cdf0e10cSrcweir --mpParamInfo; 825*cdf0e10cSrcweir // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it 826*cdf0e10cSrcweir else if( isExcelOnlyParam() || isCalcOnlyParam() ) 827*cdf0e10cSrcweir mpParamInfo = 0; 828*cdf0e10cSrcweir // otherwise: repeat last parameter class 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir return *this; 831*cdf0e10cSrcweir } 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir // function provider ========================================================== 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir struct FunctionProviderImpl 836*cdf0e10cSrcweir { 837*cdf0e10cSrcweir typedef RefMap< OUString, FunctionInfo > FuncNameMap; 838*cdf0e10cSrcweir typedef RefMap< sal_uInt16, FunctionInfo > FuncIdMap; 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir FunctionInfoVector maFuncs; /// All function infos in one list. 841*cdf0e10cSrcweir FuncNameMap maOdfFuncs; /// Maps ODF function names to function data. 842*cdf0e10cSrcweir FuncNameMap maOoxFuncs; /// Maps OOXML function names to function data. 843*cdf0e10cSrcweir FuncIdMap maBiff12Funcs; /// Maps BIFF12 function indexes to function data. 844*cdf0e10cSrcweir FuncIdMap maBiffFuncs; /// Maps BIFF2-BIFF8 function indexes to function data. 845*cdf0e10cSrcweir FuncNameMap maMacroFuncs; /// Maps macro function names to function data. 846*cdf0e10cSrcweir 847*cdf0e10cSrcweir explicit FunctionProviderImpl( FilterType eFilter, BiffType eBiff, bool bImportFilter ); 848*cdf0e10cSrcweir 849*cdf0e10cSrcweir private: 850*cdf0e10cSrcweir /** Creates and inserts a function info struct from the passed function data. */ 851*cdf0e10cSrcweir void initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam ); 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir /** Initializes the members from the passed function data list. */ 854*cdf0e10cSrcweir void initFuncs( 855*cdf0e10cSrcweir const FunctionData* pBeg, const FunctionData* pEnd, 856*cdf0e10cSrcweir sal_uInt8 nMaxParam, bool bImportFilter ); 857*cdf0e10cSrcweir }; 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir FunctionProviderImpl::FunctionProviderImpl( FilterType eFilter, BiffType eBiff, bool bImportFilter ) 862*cdf0e10cSrcweir { 863*cdf0e10cSrcweir OSL_ENSURE( bImportFilter, "FunctionProviderImpl::FunctionProviderImpl - need special handling for macro call functions" ); 864*cdf0e10cSrcweir sal_uInt8 nMaxParam = 0; 865*cdf0e10cSrcweir switch( eFilter ) 866*cdf0e10cSrcweir { 867*cdf0e10cSrcweir case FILTER_OOXML: 868*cdf0e10cSrcweir nMaxParam = OOX_MAX_PARAMCOUNT; 869*cdf0e10cSrcweir eBiff = BIFF8; // insert all BIFF function tables, then the OOXML table 870*cdf0e10cSrcweir break; 871*cdf0e10cSrcweir case FILTER_BIFF: 872*cdf0e10cSrcweir nMaxParam = BIFF_MAX_PARAMCOUNT; 873*cdf0e10cSrcweir break; 874*cdf0e10cSrcweir case FILTER_UNKNOWN: 875*cdf0e10cSrcweir OSL_ENSURE( false, "FunctionProviderImpl::FunctionProviderImpl - invalid filter type" ); 876*cdf0e10cSrcweir break; 877*cdf0e10cSrcweir } 878*cdf0e10cSrcweir OSL_ENSURE( eBiff != BIFF_UNKNOWN, "FunctionProviderImpl::FunctionProviderImpl - invalid BIFF type" ); 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir /* Add functions supported in the current BIFF version only. Function 881*cdf0e10cSrcweir tables from later BIFF versions may overwrite single functions from 882*cdf0e10cSrcweir earlier tables. */ 883*cdf0e10cSrcweir if( eBiff >= BIFF2 ) 884*cdf0e10cSrcweir initFuncs( saFuncTableBiff2, STATIC_ARRAY_END( saFuncTableBiff2 ), nMaxParam, bImportFilter ); 885*cdf0e10cSrcweir if( eBiff >= BIFF3 ) 886*cdf0e10cSrcweir initFuncs( saFuncTableBiff3, STATIC_ARRAY_END( saFuncTableBiff3 ), nMaxParam, bImportFilter ); 887*cdf0e10cSrcweir if( eBiff >= BIFF4 ) 888*cdf0e10cSrcweir initFuncs( saFuncTableBiff4, STATIC_ARRAY_END( saFuncTableBiff4 ), nMaxParam, bImportFilter ); 889*cdf0e10cSrcweir if( eBiff >= BIFF5 ) 890*cdf0e10cSrcweir initFuncs( saFuncTableBiff5, STATIC_ARRAY_END( saFuncTableBiff5 ), nMaxParam, bImportFilter ); 891*cdf0e10cSrcweir if( eBiff >= BIFF8 ) 892*cdf0e10cSrcweir initFuncs( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ), nMaxParam, bImportFilter ); 893*cdf0e10cSrcweir if( eFilter == FILTER_OOXML ) 894*cdf0e10cSrcweir initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter ); 895*cdf0e10cSrcweir initFuncs( saFuncTableOdf, STATIC_ARRAY_END( saFuncTableOdf ), nMaxParam, bImportFilter ); 896*cdf0e10cSrcweir } 897*cdf0e10cSrcweir 898*cdf0e10cSrcweir void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam ) 899*cdf0e10cSrcweir { 900*cdf0e10cSrcweir // create a function info object 901*cdf0e10cSrcweir FunctionInfoRef xFuncInfo( new FunctionInfo ); 902*cdf0e10cSrcweir if( rFuncData.mpcOdfFuncName ) 903*cdf0e10cSrcweir xFuncInfo->maOdfFuncName = OUString::createFromAscii( rFuncData.mpcOdfFuncName ); 904*cdf0e10cSrcweir if( rFuncData.mpcOoxFuncName ) 905*cdf0e10cSrcweir xFuncInfo->maOoxFuncName = OUString::createFromAscii( rFuncData.mpcOoxFuncName ); 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALL ) ) 908*cdf0e10cSrcweir { 909*cdf0e10cSrcweir OSL_ENSURE( xFuncInfo->maOoxFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing OOXML function name" ); 910*cdf0e10cSrcweir OSL_ENSURE( !getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ), "FunctionProviderImpl::initFunc - unexpected flag FUNCFLAG_MACROCALLODF" ); 911*cdf0e10cSrcweir xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfn." ) + xFuncInfo->maOoxFuncName; 912*cdf0e10cSrcweir } 913*cdf0e10cSrcweir else if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ) ) 914*cdf0e10cSrcweir { 915*cdf0e10cSrcweir OSL_ENSURE( xFuncInfo->maOdfFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing ODF function name" ); 916*cdf0e10cSrcweir xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName; 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir xFuncInfo->meFuncLibType = FUNCFLAGS_TO_FUNCLIB( rFuncData.mnFlags ); 920*cdf0e10cSrcweir xFuncInfo->mnApiOpCode = -1; 921*cdf0e10cSrcweir xFuncInfo->mnBiff12FuncId = rFuncData.mnBiff12FuncId; 922*cdf0e10cSrcweir xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId; 923*cdf0e10cSrcweir xFuncInfo->mnMinParamCount = rFuncData.mnMinParamCount; 924*cdf0e10cSrcweir xFuncInfo->mnMaxParamCount = (rFuncData.mnMaxParamCount == MX) ? nMaxParam : rFuncData.mnMaxParamCount; 925*cdf0e10cSrcweir xFuncInfo->mnRetClass = rFuncData.mnRetClass; 926*cdf0e10cSrcweir xFuncInfo->mpParamInfos = rFuncData.mpParamInfos; 927*cdf0e10cSrcweir xFuncInfo->mbParamPairs = getFlag( rFuncData.mnFlags, FUNCFLAG_PARAMPAIRS ); 928*cdf0e10cSrcweir xFuncInfo->mbVolatile = getFlag( rFuncData.mnFlags, FUNCFLAG_VOLATILE ); 929*cdf0e10cSrcweir xFuncInfo->mbExternal = getFlag( rFuncData.mnFlags, FUNCFLAG_EXTERNAL ); 930*cdf0e10cSrcweir bool bMacroCmd = getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCMD ); 931*cdf0e10cSrcweir xFuncInfo->mbMacroFunc = bMacroCmd || getFlag( rFuncData.mnFlags, FUNCFLAG_MACROFUNC ); 932*cdf0e10cSrcweir xFuncInfo->mbVarParam = bMacroCmd || (rFuncData.mnMinParamCount != rFuncData.mnMaxParamCount) || getFlag( rFuncData.mnFlags, FUNCFLAG_ALWAYSVAR ); 933*cdf0e10cSrcweir 934*cdf0e10cSrcweir setFlag( xFuncInfo->mnBiff12FuncId, BIFF_TOK_FUNCVAR_CMD, bMacroCmd ); 935*cdf0e10cSrcweir setFlag( xFuncInfo->mnBiffFuncId, BIFF_TOK_FUNCVAR_CMD, bMacroCmd ); 936*cdf0e10cSrcweir 937*cdf0e10cSrcweir // insert the function info into the member maps 938*cdf0e10cSrcweir maFuncs.push_back( xFuncInfo ); 939*cdf0e10cSrcweir if( xFuncInfo->maOdfFuncName.getLength() > 0 ) 940*cdf0e10cSrcweir maOdfFuncs[ xFuncInfo->maOdfFuncName ] = xFuncInfo; 941*cdf0e10cSrcweir if( xFuncInfo->maOoxFuncName.getLength() > 0 ) 942*cdf0e10cSrcweir maOoxFuncs[ xFuncInfo->maOoxFuncName ] = xFuncInfo; 943*cdf0e10cSrcweir if( xFuncInfo->mnBiff12FuncId != NOID ) 944*cdf0e10cSrcweir maBiff12Funcs[ xFuncInfo->mnBiff12FuncId ] = xFuncInfo; 945*cdf0e10cSrcweir if( xFuncInfo->mnBiffFuncId != NOID ) 946*cdf0e10cSrcweir maBiffFuncs[ xFuncInfo->mnBiffFuncId ] = xFuncInfo; 947*cdf0e10cSrcweir if( xFuncInfo->maBiffMacroName.getLength() > 0 ) 948*cdf0e10cSrcweir maMacroFuncs[ xFuncInfo->maBiffMacroName ] = xFuncInfo; 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir 951*cdf0e10cSrcweir void FunctionProviderImpl::initFuncs( const FunctionData* pBeg, const FunctionData* pEnd, sal_uInt8 nMaxParam, bool bImportFilter ) 952*cdf0e10cSrcweir { 953*cdf0e10cSrcweir for( const FunctionData* pIt = pBeg; pIt != pEnd; ++pIt ) 954*cdf0e10cSrcweir if( pIt->isSupported( bImportFilter ) ) 955*cdf0e10cSrcweir initFunc( *pIt, nMaxParam ); 956*cdf0e10cSrcweir } 957*cdf0e10cSrcweir 958*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 959*cdf0e10cSrcweir 960*cdf0e10cSrcweir FunctionProvider::FunctionProvider( FilterType eFilter, BiffType eBiff, bool bImportFilter ) : 961*cdf0e10cSrcweir mxFuncImpl( new FunctionProviderImpl( eFilter, eBiff, bImportFilter ) ) 962*cdf0e10cSrcweir { 963*cdf0e10cSrcweir } 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir FunctionProvider::~FunctionProvider() 966*cdf0e10cSrcweir { 967*cdf0e10cSrcweir } 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromOdfFuncName( const OUString& rFuncName ) const 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir return mxFuncImpl->maOdfFuncs.get( rFuncName ).get(); 972*cdf0e10cSrcweir } 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromOoxFuncName( const OUString& rFuncName ) const 975*cdf0e10cSrcweir { 976*cdf0e10cSrcweir return mxFuncImpl->maOoxFuncs.get( rFuncName ).get(); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir 979*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromBiff12FuncId( sal_uInt16 nFuncId ) const 980*cdf0e10cSrcweir { 981*cdf0e10cSrcweir return mxFuncImpl->maBiff12Funcs.get( nFuncId ).get(); 982*cdf0e10cSrcweir } 983*cdf0e10cSrcweir 984*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const 985*cdf0e10cSrcweir { 986*cdf0e10cSrcweir return mxFuncImpl->maBiffFuncs.get( nFuncId ).get(); 987*cdf0e10cSrcweir } 988*cdf0e10cSrcweir 989*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromMacroName( const OUString& rFuncName ) const 990*cdf0e10cSrcweir { 991*cdf0e10cSrcweir return mxFuncImpl->maMacroFuncs.get( rFuncName ).get(); 992*cdf0e10cSrcweir } 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir FunctionLibraryType FunctionProvider::getFuncLibTypeFromLibraryName( const OUString& rLibraryName ) const 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir #define OOX_XLS_IS_LIBNAME( libname, basename ) (libname.equalsIgnoreAsciiCaseAscii( basename ".XLA" ) || libname.equalsIgnoreAsciiCaseAscii( basename ".XLAM" )) 997*cdf0e10cSrcweir 998*cdf0e10cSrcweir // the EUROTOOL add-in containing the EUROCONVERT function 999*cdf0e10cSrcweir if( OOX_XLS_IS_LIBNAME( rLibraryName, "EUROTOOL" ) ) 1000*cdf0e10cSrcweir return FUNCLIB_EUROTOOL; 1001*cdf0e10cSrcweir 1002*cdf0e10cSrcweir #undef OOX_XLS_IS_LIBNAME 1003*cdf0e10cSrcweir 1004*cdf0e10cSrcweir // default: unknown library 1005*cdf0e10cSrcweir return FUNCLIB_UNKNOWN; 1006*cdf0e10cSrcweir } 1007*cdf0e10cSrcweir 1008*cdf0e10cSrcweir const FunctionInfoVector& FunctionProvider::getFuncs() const 1009*cdf0e10cSrcweir { 1010*cdf0e10cSrcweir return mxFuncImpl->maFuncs; 1011*cdf0e10cSrcweir } 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir // op-code and function provider ============================================== 1014*cdf0e10cSrcweir 1015*cdf0e10cSrcweir struct OpCodeProviderImpl : public ApiOpCodes 1016*cdf0e10cSrcweir { 1017*cdf0e10cSrcweir typedef RefMap< sal_Int32, FunctionInfo > OpCodeFuncMap; 1018*cdf0e10cSrcweir typedef RefMap< OUString, FunctionInfo > FuncNameMap; 1019*cdf0e10cSrcweir typedef ::std::vector< FormulaOpCodeMapEntry > OpCodeEntryVector; 1020*cdf0e10cSrcweir 1021*cdf0e10cSrcweir OpCodeFuncMap maOpCodeFuncs; /// Maps API function op-codes to function data. 1022*cdf0e10cSrcweir FuncNameMap maExtProgFuncs; /// Maps programmatical API function names to function data. 1023*cdf0e10cSrcweir OpCodeEntryVector maParserMap; /// OOXML token mapping for formula parser service. 1024*cdf0e10cSrcweir 1025*cdf0e10cSrcweir explicit OpCodeProviderImpl( 1026*cdf0e10cSrcweir const FunctionInfoVector& rFuncInfos, 1027*cdf0e10cSrcweir const Reference< XMultiServiceFactory >& rxModelFactory ); 1028*cdf0e10cSrcweir 1029*cdf0e10cSrcweir private: 1030*cdf0e10cSrcweir typedef ::std::map< OUString, ApiToken > ApiTokenMap; 1031*cdf0e10cSrcweir typedef Sequence< FormulaOpCodeMapEntry > OpCodeEntrySequence; 1032*cdf0e10cSrcweir 1033*cdf0e10cSrcweir static bool fillEntrySeq( OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup ); 1034*cdf0e10cSrcweir static bool fillTokenMap( ApiTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup ); 1035*cdf0e10cSrcweir bool fillFuncTokenMaps( ApiTokenMap& orIntFuncTokenMap, ApiTokenMap& orExtFuncTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper ) const; 1036*cdf0e10cSrcweir 1037*cdf0e10cSrcweir static bool initOpCode( sal_Int32& ornOpCode, const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId ); 1038*cdf0e10cSrcweir bool initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const OUString& rOdfName, const OUString& rOoxName ); 1039*cdf0e10cSrcweir bool initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName ); 1040*cdf0e10cSrcweir bool initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, sal_Unicode cOdfName, sal_Unicode cOoxName ); 1041*cdf0e10cSrcweir 1042*cdf0e10cSrcweir bool initFuncOpCode( FunctionInfo& orFuncInfo, const ApiTokenMap& rFuncTokenMap ); 1043*cdf0e10cSrcweir bool initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, const ApiTokenMap& rExtFuncTokenMap, const FunctionInfoVector& rFuncInfos ); 1044*cdf0e10cSrcweir }; 1045*cdf0e10cSrcweir 1046*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 1047*cdf0e10cSrcweir 1048*cdf0e10cSrcweir OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos, 1049*cdf0e10cSrcweir const Reference< XMultiServiceFactory >& rxModelFactory ) 1050*cdf0e10cSrcweir { 1051*cdf0e10cSrcweir if( rxModelFactory.is() ) try 1052*cdf0e10cSrcweir { 1053*cdf0e10cSrcweir Reference< XFormulaOpCodeMapper > xMapper( rxModelFactory->createInstance( 1054*cdf0e10cSrcweir CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW ); 1055*cdf0e10cSrcweir 1056*cdf0e10cSrcweir // op-codes provided as attributes 1057*cdf0e10cSrcweir OPCODE_UNKNOWN = xMapper->getOpCodeUnknown(); 1058*cdf0e10cSrcweir OPCODE_EXTERNAL = xMapper->getOpCodeExternal(); 1059*cdf0e10cSrcweir 1060*cdf0e10cSrcweir using namespace ::com::sun::star::sheet::FormulaMapGroup; 1061*cdf0e10cSrcweir using namespace ::com::sun::star::sheet::FormulaMapGroupSpecialOffset; 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir OpCodeEntrySequence aEntrySeq; 1064*cdf0e10cSrcweir ApiTokenMap aTokenMap, aExtFuncTokenMap; 1065*cdf0e10cSrcweir bool bIsValid = 1066*cdf0e10cSrcweir // special 1067*cdf0e10cSrcweir fillEntrySeq( aEntrySeq, xMapper, SPECIAL ) && 1068*cdf0e10cSrcweir initOpCode( OPCODE_PUSH, aEntrySeq, PUSH ) && 1069*cdf0e10cSrcweir initOpCode( OPCODE_MISSING, aEntrySeq, MISSING ) && 1070*cdf0e10cSrcweir initOpCode( OPCODE_SPACES, aEntrySeq, SPACES ) && 1071*cdf0e10cSrcweir initOpCode( OPCODE_NAME, aEntrySeq, NAME ) && 1072*cdf0e10cSrcweir initOpCode( OPCODE_DBAREA, aEntrySeq, DB_AREA ) && 1073*cdf0e10cSrcweir initOpCode( OPCODE_NLR, aEntrySeq, COL_ROW_NAME ) && 1074*cdf0e10cSrcweir initOpCode( OPCODE_MACRO, aEntrySeq, MACRO ) && 1075*cdf0e10cSrcweir initOpCode( OPCODE_BAD, aEntrySeq, BAD ) && 1076*cdf0e10cSrcweir initOpCode( OPCODE_NONAME, aEntrySeq, NO_NAME ) && 1077*cdf0e10cSrcweir // separators 1078*cdf0e10cSrcweir fillTokenMap( aTokenMap, aEntrySeq, xMapper, SEPARATORS ) && 1079*cdf0e10cSrcweir initOpCode( OPCODE_OPEN, aTokenMap, API_TOKEN_OPEN, '(' ) && 1080*cdf0e10cSrcweir initOpCode( OPCODE_CLOSE, aTokenMap, API_TOKEN_CLOSE, ')' ) && 1081*cdf0e10cSrcweir initOpCode( OPCODE_SEP, aTokenMap, API_TOKEN_SEP, ',' ) && 1082*cdf0e10cSrcweir // array separators 1083*cdf0e10cSrcweir fillTokenMap( aTokenMap, aEntrySeq, xMapper, ARRAY_SEPARATORS ) && 1084*cdf0e10cSrcweir initOpCode( OPCODE_ARRAY_OPEN, aTokenMap, API_TOKEN_ARRAY_OPEN, '{' ) && 1085*cdf0e10cSrcweir initOpCode( OPCODE_ARRAY_CLOSE, aTokenMap, API_TOKEN_ARRAY_CLOSE, '}' ) && 1086*cdf0e10cSrcweir initOpCode( OPCODE_ARRAY_ROWSEP, aTokenMap, API_TOKEN_ARRAY_ROWSEP, ';' ) && 1087*cdf0e10cSrcweir initOpCode( OPCODE_ARRAY_COLSEP, aTokenMap, API_TOKEN_ARRAY_COLSEP, ',' ) && 1088*cdf0e10cSrcweir // unary operators 1089*cdf0e10cSrcweir fillTokenMap( aTokenMap, aEntrySeq, xMapper, UNARY_OPERATORS ) && 1090*cdf0e10cSrcweir initOpCode( OPCODE_PLUS_SIGN, aTokenMap, '+', '\0' ) && // same op-code as OPCODE_ADD 1091*cdf0e10cSrcweir initOpCode( OPCODE_MINUS_SIGN, aTokenMap, '-', '-' ) && 1092*cdf0e10cSrcweir initOpCode( OPCODE_PERCENT, aTokenMap, '%', '%' ) && 1093*cdf0e10cSrcweir // binary operators 1094*cdf0e10cSrcweir fillTokenMap( aTokenMap, aEntrySeq, xMapper, BINARY_OPERATORS ) && 1095*cdf0e10cSrcweir initOpCode( OPCODE_ADD, aTokenMap, '+', '+' ) && 1096*cdf0e10cSrcweir initOpCode( OPCODE_SUB, aTokenMap, '-', '-' ) && 1097*cdf0e10cSrcweir initOpCode( OPCODE_MULT, aTokenMap, '*', '*' ) && 1098*cdf0e10cSrcweir initOpCode( OPCODE_DIV, aTokenMap, '/', '/' ) && 1099*cdf0e10cSrcweir initOpCode( OPCODE_POWER, aTokenMap, '^', '^' ) && 1100*cdf0e10cSrcweir initOpCode( OPCODE_CONCAT, aTokenMap, '&', '&' ) && 1101*cdf0e10cSrcweir initOpCode( OPCODE_EQUAL, aTokenMap, '=', '=' ) && 1102*cdf0e10cSrcweir initOpCode( OPCODE_NOT_EQUAL, aTokenMap, "<>", "<>" ) && 1103*cdf0e10cSrcweir initOpCode( OPCODE_LESS, aTokenMap, '<', '<' ) && 1104*cdf0e10cSrcweir initOpCode( OPCODE_LESS_EQUAL, aTokenMap, "<=", "<=" ) && 1105*cdf0e10cSrcweir initOpCode( OPCODE_GREATER, aTokenMap, '>', '>' ) && 1106*cdf0e10cSrcweir initOpCode( OPCODE_GREATER_EQUAL, aTokenMap, ">=", ">=" ) && 1107*cdf0e10cSrcweir initOpCode( OPCODE_INTERSECT, aTokenMap, '!', ' ' ) && 1108*cdf0e10cSrcweir initOpCode( OPCODE_LIST, aTokenMap, '~', ',' ) && 1109*cdf0e10cSrcweir initOpCode( OPCODE_RANGE, aTokenMap, ':', ':' ) && 1110*cdf0e10cSrcweir // functions 1111*cdf0e10cSrcweir fillFuncTokenMaps( aTokenMap, aExtFuncTokenMap, aEntrySeq, xMapper ) && 1112*cdf0e10cSrcweir initFuncOpCodes( aTokenMap, aExtFuncTokenMap, rFuncInfos ) && 1113*cdf0e10cSrcweir initOpCode( OPCODE_DDE, aTokenMap, "DDE", 0 ); 1114*cdf0e10cSrcweir 1115*cdf0e10cSrcweir OSL_ENSURE( bIsValid, "OpCodeProviderImpl::OpCodeProviderImpl - opcodes not initialized" ); 1116*cdf0e10cSrcweir (void)bIsValid; 1117*cdf0e10cSrcweir 1118*cdf0e10cSrcweir // OPCODE_PLUS_SIGN and OPCODE_ADD should be equal, otherwise "+" has to be passed above 1119*cdf0e10cSrcweir OSL_ENSURE( OPCODE_PLUS_SIGN == OPCODE_ADD, "OpCodeProviderImpl::OpCodeProviderImpl - need opcode mapping for OPCODE_PLUS_SIGN" ); 1120*cdf0e10cSrcweir } 1121*cdf0e10cSrcweir catch( Exception& ) 1122*cdf0e10cSrcweir { 1123*cdf0e10cSrcweir OSL_ENSURE( false, "OpCodeProviderImpl::OpCodeProviderImpl - cannot receive formula opcode mapper" ); 1124*cdf0e10cSrcweir } 1125*cdf0e10cSrcweir } 1126*cdf0e10cSrcweir 1127*cdf0e10cSrcweir bool OpCodeProviderImpl::fillEntrySeq( OpCodeEntrySequence& orEntrySeq, 1128*cdf0e10cSrcweir const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup ) 1129*cdf0e10cSrcweir { 1130*cdf0e10cSrcweir try 1131*cdf0e10cSrcweir { 1132*cdf0e10cSrcweir orEntrySeq = rxMapper->getAvailableMappings( ::com::sun::star::sheet::FormulaLanguage::ODFF, nMapGroup ); 1133*cdf0e10cSrcweir return orEntrySeq.hasElements(); 1134*cdf0e10cSrcweir } 1135*cdf0e10cSrcweir catch( Exception& ) 1136*cdf0e10cSrcweir { 1137*cdf0e10cSrcweir } 1138*cdf0e10cSrcweir return false; 1139*cdf0e10cSrcweir } 1140*cdf0e10cSrcweir 1141*cdf0e10cSrcweir bool OpCodeProviderImpl::fillTokenMap( ApiTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq, 1142*cdf0e10cSrcweir const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup ) 1143*cdf0e10cSrcweir { 1144*cdf0e10cSrcweir orTokenMap.clear(); 1145*cdf0e10cSrcweir if( fillEntrySeq( orEntrySeq, rxMapper, nMapGroup ) ) 1146*cdf0e10cSrcweir { 1147*cdf0e10cSrcweir const FormulaOpCodeMapEntry* pEntry = orEntrySeq.getConstArray(); 1148*cdf0e10cSrcweir const FormulaOpCodeMapEntry* pEntryEnd = pEntry + orEntrySeq.getLength(); 1149*cdf0e10cSrcweir for( ; pEntry != pEntryEnd; ++pEntry ) 1150*cdf0e10cSrcweir orTokenMap[ pEntry->Name ] = pEntry->Token; 1151*cdf0e10cSrcweir } 1152*cdf0e10cSrcweir return orEntrySeq.hasElements(); 1153*cdf0e10cSrcweir } 1154*cdf0e10cSrcweir 1155*cdf0e10cSrcweir bool OpCodeProviderImpl::fillFuncTokenMaps( ApiTokenMap& orIntFuncTokenMap, ApiTokenMap& orExtFuncTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper ) const 1156*cdf0e10cSrcweir { 1157*cdf0e10cSrcweir orIntFuncTokenMap.clear(); 1158*cdf0e10cSrcweir orExtFuncTokenMap.clear(); 1159*cdf0e10cSrcweir if( fillEntrySeq( orEntrySeq, rxMapper, ::com::sun::star::sheet::FormulaMapGroup::FUNCTIONS ) ) 1160*cdf0e10cSrcweir { 1161*cdf0e10cSrcweir const FormulaOpCodeMapEntry* pEntry = orEntrySeq.getConstArray(); 1162*cdf0e10cSrcweir const FormulaOpCodeMapEntry* pEntryEnd = pEntry + orEntrySeq.getLength(); 1163*cdf0e10cSrcweir for( ; pEntry != pEntryEnd; ++pEntry ) 1164*cdf0e10cSrcweir ((pEntry->Token.OpCode == OPCODE_EXTERNAL) ? orExtFuncTokenMap : orIntFuncTokenMap)[ pEntry->Name ] = pEntry->Token; 1165*cdf0e10cSrcweir } 1166*cdf0e10cSrcweir return orEntrySeq.hasElements(); 1167*cdf0e10cSrcweir } 1168*cdf0e10cSrcweir 1169*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId ) 1170*cdf0e10cSrcweir { 1171*cdf0e10cSrcweir if( (0 <= nSpecialId) && (nSpecialId < rEntrySeq.getLength()) ) 1172*cdf0e10cSrcweir { 1173*cdf0e10cSrcweir ornOpCode = rEntrySeq[ nSpecialId ].Token.OpCode; 1174*cdf0e10cSrcweir return true; 1175*cdf0e10cSrcweir } 1176*cdf0e10cSrcweir OSL_ENSURE( false, 1177*cdf0e10cSrcweir OStringBuffer( "OpCodeProviderImpl::initOpCode - opcode for special offset " ). 1178*cdf0e10cSrcweir append( nSpecialId ).append( " not found" ).getStr() ); 1179*cdf0e10cSrcweir return false; 1180*cdf0e10cSrcweir } 1181*cdf0e10cSrcweir 1182*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const OUString& rOdfName, const OUString& rOoxName ) 1183*cdf0e10cSrcweir { 1184*cdf0e10cSrcweir ApiTokenMap::const_iterator aIt = rTokenMap.find( rOdfName ); 1185*cdf0e10cSrcweir if( aIt != rTokenMap.end() ) 1186*cdf0e10cSrcweir { 1187*cdf0e10cSrcweir ornOpCode = aIt->second.OpCode; 1188*cdf0e10cSrcweir if( rOoxName.getLength() > 0 ) 1189*cdf0e10cSrcweir { 1190*cdf0e10cSrcweir FormulaOpCodeMapEntry aEntry; 1191*cdf0e10cSrcweir aEntry.Name = rOoxName; 1192*cdf0e10cSrcweir aEntry.Token.OpCode = ornOpCode; 1193*cdf0e10cSrcweir maParserMap.push_back( aEntry ); 1194*cdf0e10cSrcweir } 1195*cdf0e10cSrcweir return true; 1196*cdf0e10cSrcweir } 1197*cdf0e10cSrcweir OSL_ENSURE( false, 1198*cdf0e10cSrcweir OStringBuffer( "OpCodeProviderImpl::initOpCode - opcode for \"" ). 1199*cdf0e10cSrcweir append( OUStringToOString( rOdfName, RTL_TEXTENCODING_ASCII_US ) ). 1200*cdf0e10cSrcweir append( "\" not found" ).getStr() ); 1201*cdf0e10cSrcweir return false; 1202*cdf0e10cSrcweir } 1203*cdf0e10cSrcweir 1204*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName ) 1205*cdf0e10cSrcweir { 1206*cdf0e10cSrcweir OUString aOoxName; 1207*cdf0e10cSrcweir if( pcOoxName ) aOoxName = OUString::createFromAscii( pcOoxName ); 1208*cdf0e10cSrcweir return initOpCode( ornOpCode, rTokenMap, OUString::createFromAscii( pcOdfName ), aOoxName ); 1209*cdf0e10cSrcweir } 1210*cdf0e10cSrcweir 1211*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, sal_Unicode cOdfName, sal_Unicode cOoxName ) 1212*cdf0e10cSrcweir { 1213*cdf0e10cSrcweir OUString aOoxName; 1214*cdf0e10cSrcweir if( cOoxName ) aOoxName = OUString( cOoxName ); 1215*cdf0e10cSrcweir return initOpCode( ornOpCode, rTokenMap, OUString( cOdfName ), aOoxName ); 1216*cdf0e10cSrcweir } 1217*cdf0e10cSrcweir 1218*cdf0e10cSrcweir bool OpCodeProviderImpl::initFuncOpCode( FunctionInfo& orFuncInfo, const ApiTokenMap& rFuncTokenMap ) 1219*cdf0e10cSrcweir { 1220*cdf0e10cSrcweir bool bIsValid = false; 1221*cdf0e10cSrcweir if( orFuncInfo.maOdfFuncName.getLength() > 0 ) 1222*cdf0e10cSrcweir { 1223*cdf0e10cSrcweir ApiTokenMap::const_iterator aIt = rFuncTokenMap.find( orFuncInfo.maOdfFuncName ); 1224*cdf0e10cSrcweir if( aIt != rFuncTokenMap.end() ) 1225*cdf0e10cSrcweir { 1226*cdf0e10cSrcweir orFuncInfo.mnApiOpCode = aIt->second.OpCode; 1227*cdf0e10cSrcweir bIsValid = 1228*cdf0e10cSrcweir (orFuncInfo.mnApiOpCode >= 0) && 1229*cdf0e10cSrcweir (orFuncInfo.mnApiOpCode != OPCODE_UNKNOWN) && 1230*cdf0e10cSrcweir (orFuncInfo.mnApiOpCode != OPCODE_NONAME); 1231*cdf0e10cSrcweir OSL_ENSURE( bIsValid, 1232*cdf0e10cSrcweir OStringBuffer( "OpCodeProviderImpl::initFuncOpCode - no valid opcode for ODF function \"" ). 1233*cdf0e10cSrcweir append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ). 1234*cdf0e10cSrcweir append( '"' ).getStr() ); 1235*cdf0e10cSrcweir 1236*cdf0e10cSrcweir if( bIsValid && (orFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) ) 1237*cdf0e10cSrcweir { 1238*cdf0e10cSrcweir bIsValid = (aIt->second.Data >>= orFuncInfo.maExtProgName) && (orFuncInfo.maExtProgName.getLength() > 0); 1239*cdf0e10cSrcweir OSL_ENSURE( bIsValid, 1240*cdf0e10cSrcweir OStringBuffer( "OpCodeProviderImpl::initFuncOpCode - no programmatical name for external function \"" ). 1241*cdf0e10cSrcweir append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ). 1242*cdf0e10cSrcweir append( '"' ).getStr() ); 1243*cdf0e10cSrcweir } 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir // add to parser map, if OOXML function name exists 1246*cdf0e10cSrcweir if( bIsValid && (orFuncInfo.maOoxFuncName.getLength() > 0) ) 1247*cdf0e10cSrcweir { 1248*cdf0e10cSrcweir // create the parser map entry 1249*cdf0e10cSrcweir FormulaOpCodeMapEntry aEntry; 1250*cdf0e10cSrcweir aEntry.Name = orFuncInfo.maOoxFuncName; 1251*cdf0e10cSrcweir aEntry.Token = aIt->second; 1252*cdf0e10cSrcweir maParserMap.push_back( aEntry ); 1253*cdf0e10cSrcweir } 1254*cdf0e10cSrcweir } 1255*cdf0e10cSrcweir else 1256*cdf0e10cSrcweir { 1257*cdf0e10cSrcweir // ignore entries for functions unknown by Calc *and* by Excel 1258*cdf0e10cSrcweir bIsValid = orFuncInfo.maOoxFuncName.getLength() == 0; 1259*cdf0e10cSrcweir } 1260*cdf0e10cSrcweir } 1261*cdf0e10cSrcweir else if( orFuncInfo.mnBiffFuncId == BIFF_FUNC_EXTERNCALL ) 1262*cdf0e10cSrcweir { 1263*cdf0e10cSrcweir orFuncInfo.mnApiOpCode = OPCODE_EXTERNAL; 1264*cdf0e10cSrcweir bIsValid = true; 1265*cdf0e10cSrcweir } 1266*cdf0e10cSrcweir else if( orFuncInfo.maOoxFuncName.getLength() > 0 ) 1267*cdf0e10cSrcweir { 1268*cdf0e10cSrcweir orFuncInfo.mnApiOpCode = OPCODE_BAD; 1269*cdf0e10cSrcweir bIsValid = true; 1270*cdf0e10cSrcweir } 1271*cdf0e10cSrcweir 1272*cdf0e10cSrcweir if( !bIsValid || (orFuncInfo.mnApiOpCode == OPCODE_UNKNOWN) || (orFuncInfo.mnApiOpCode < 0) ) 1273*cdf0e10cSrcweir orFuncInfo.mnApiOpCode = OPCODE_NONAME; 1274*cdf0e10cSrcweir return bIsValid; 1275*cdf0e10cSrcweir } 1276*cdf0e10cSrcweir 1277*cdf0e10cSrcweir bool OpCodeProviderImpl::initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, const ApiTokenMap& rExtFuncTokenMap, const FunctionInfoVector& rFuncInfos ) 1278*cdf0e10cSrcweir { 1279*cdf0e10cSrcweir bool bIsValid = true; 1280*cdf0e10cSrcweir for( FunctionInfoVector::const_iterator aIt = rFuncInfos.begin(), aEnd = rFuncInfos.end(); aIt != aEnd; ++aIt ) 1281*cdf0e10cSrcweir { 1282*cdf0e10cSrcweir FunctionInfoRef xFuncInfo = *aIt; 1283*cdf0e10cSrcweir // set API opcode from ODF function name 1284*cdf0e10cSrcweir bIsValid &= initFuncOpCode( *xFuncInfo, xFuncInfo->mbExternal ? rExtFuncTokenMap : rIntFuncTokenMap ); 1285*cdf0e10cSrcweir // insert the function info into the maps 1286*cdf0e10cSrcweir if( (xFuncInfo->mnApiOpCode != OPCODE_NONAME) && (xFuncInfo->mnApiOpCode != OPCODE_BAD) ) 1287*cdf0e10cSrcweir { 1288*cdf0e10cSrcweir if( (xFuncInfo->mnApiOpCode == OPCODE_EXTERNAL) && (xFuncInfo->maExtProgName.getLength() > 0) ) 1289*cdf0e10cSrcweir maExtProgFuncs[ xFuncInfo->maExtProgName ] = xFuncInfo; 1290*cdf0e10cSrcweir else 1291*cdf0e10cSrcweir maOpCodeFuncs[ xFuncInfo->mnApiOpCode ] = xFuncInfo; 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir } 1294*cdf0e10cSrcweir return bIsValid; 1295*cdf0e10cSrcweir } 1296*cdf0e10cSrcweir 1297*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 1298*cdf0e10cSrcweir 1299*cdf0e10cSrcweir OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxModelFactory, 1300*cdf0e10cSrcweir FilterType eFilter, BiffType eBiff, bool bImportFilter ) : 1301*cdf0e10cSrcweir FunctionProvider( eFilter, eBiff, bImportFilter ), 1302*cdf0e10cSrcweir mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxModelFactory ) ) 1303*cdf0e10cSrcweir { 1304*cdf0e10cSrcweir } 1305*cdf0e10cSrcweir 1306*cdf0e10cSrcweir OpCodeProvider::~OpCodeProvider() 1307*cdf0e10cSrcweir { 1308*cdf0e10cSrcweir } 1309*cdf0e10cSrcweir 1310*cdf0e10cSrcweir const ApiOpCodes& OpCodeProvider::getOpCodes() const 1311*cdf0e10cSrcweir { 1312*cdf0e10cSrcweir return *mxOpCodeImpl; 1313*cdf0e10cSrcweir } 1314*cdf0e10cSrcweir 1315*cdf0e10cSrcweir const FunctionInfo* OpCodeProvider::getFuncInfoFromApiToken( const ApiToken& rToken ) const 1316*cdf0e10cSrcweir { 1317*cdf0e10cSrcweir const FunctionInfo* pFuncInfo = 0; 1318*cdf0e10cSrcweir if( (rToken.OpCode == mxOpCodeImpl->OPCODE_EXTERNAL) && rToken.Data.has< OUString >() ) 1319*cdf0e10cSrcweir pFuncInfo = mxOpCodeImpl->maExtProgFuncs.get( rToken.Data.get< OUString >() ).get(); 1320*cdf0e10cSrcweir else if( (rToken.OpCode == mxOpCodeImpl->OPCODE_MACRO) && rToken.Data.has< OUString >() ) 1321*cdf0e10cSrcweir pFuncInfo = getFuncInfoFromMacroName( rToken.Data.get< OUString >() ); 1322*cdf0e10cSrcweir else if( (rToken.OpCode == mxOpCodeImpl->OPCODE_BAD) && rToken.Data.has< OUString >() ) 1323*cdf0e10cSrcweir pFuncInfo = getFuncInfoFromOoxFuncName( rToken.Data.get< OUString >() ); 1324*cdf0e10cSrcweir else 1325*cdf0e10cSrcweir pFuncInfo = mxOpCodeImpl->maOpCodeFuncs.get( rToken.OpCode ).get(); 1326*cdf0e10cSrcweir return pFuncInfo; 1327*cdf0e10cSrcweir } 1328*cdf0e10cSrcweir 1329*cdf0e10cSrcweir Sequence< FormulaOpCodeMapEntry > OpCodeProvider::getOoxParserMap() const 1330*cdf0e10cSrcweir { 1331*cdf0e10cSrcweir return ContainerHelper::vectorToSequence( mxOpCodeImpl->maParserMap ); 1332*cdf0e10cSrcweir } 1333*cdf0e10cSrcweir 1334*cdf0e10cSrcweir // API formula parser wrapper ================================================= 1335*cdf0e10cSrcweir 1336*cdf0e10cSrcweir ApiParserWrapper::ApiParserWrapper( 1337*cdf0e10cSrcweir const Reference< XMultiServiceFactory >& rxModelFactory, const OpCodeProvider& rOpCodeProv ) : 1338*cdf0e10cSrcweir OpCodeProvider( rOpCodeProv ) 1339*cdf0e10cSrcweir { 1340*cdf0e10cSrcweir if( rxModelFactory.is() ) try 1341*cdf0e10cSrcweir { 1342*cdf0e10cSrcweir mxParser.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW ); 1343*cdf0e10cSrcweir } 1344*cdf0e10cSrcweir catch( Exception& ) 1345*cdf0e10cSrcweir { 1346*cdf0e10cSrcweir } 1347*cdf0e10cSrcweir OSL_ENSURE( mxParser.is(), "ApiParserWrapper::ApiParserWrapper - cannot create API formula parser object" ); 1348*cdf0e10cSrcweir maParserProps.set( mxParser ); 1349*cdf0e10cSrcweir maParserProps.setProperty( PROP_CompileEnglish, true ); 1350*cdf0e10cSrcweir maParserProps.setProperty( PROP_FormulaConvention, ::com::sun::star::sheet::AddressConvention::XL_OOX ); 1351*cdf0e10cSrcweir maParserProps.setProperty( PROP_IgnoreLeadingSpaces, false ); 1352*cdf0e10cSrcweir maParserProps.setProperty( PROP_OpCodeMap, getOoxParserMap() ); 1353*cdf0e10cSrcweir } 1354*cdf0e10cSrcweir 1355*cdf0e10cSrcweir ApiTokenSequence ApiParserWrapper::parseFormula( const OUString& rFormula, const CellAddress& rRefPos ) 1356*cdf0e10cSrcweir { 1357*cdf0e10cSrcweir ApiTokenSequence aTokenSeq; 1358*cdf0e10cSrcweir if( mxParser.is() ) try 1359*cdf0e10cSrcweir { 1360*cdf0e10cSrcweir aTokenSeq = mxParser->parseFormula( rFormula, rRefPos ); 1361*cdf0e10cSrcweir } 1362*cdf0e10cSrcweir catch( Exception& ) 1363*cdf0e10cSrcweir { 1364*cdf0e10cSrcweir } 1365*cdf0e10cSrcweir return aTokenSeq; 1366*cdf0e10cSrcweir } 1367*cdf0e10cSrcweir 1368*cdf0e10cSrcweir // formula parser/printer base class for filters ============================== 1369*cdf0e10cSrcweir 1370*cdf0e10cSrcweir namespace { 1371*cdf0e10cSrcweir 1372*cdf0e10cSrcweir bool lclConvertToCellAddress( CellAddress& orAddress, const SingleReference& rSingleRef, sal_Int32 nForbiddenFlags, sal_Int32 nFilterBySheet ) 1373*cdf0e10cSrcweir { 1374*cdf0e10cSrcweir orAddress = CellAddress( static_cast< sal_Int16 >( rSingleRef.Sheet ), 1375*cdf0e10cSrcweir rSingleRef.Column, rSingleRef.Row ); 1376*cdf0e10cSrcweir return 1377*cdf0e10cSrcweir !getFlag( rSingleRef.Flags, nForbiddenFlags ) && 1378*cdf0e10cSrcweir ((nFilterBySheet < 0) || (nFilterBySheet == rSingleRef.Sheet)); 1379*cdf0e10cSrcweir } 1380*cdf0e10cSrcweir 1381*cdf0e10cSrcweir bool lclConvertToCellRange( CellRangeAddress& orRange, const ComplexReference& rComplexRef, sal_Int32 nForbiddenFlags, sal_Int32 nFilterBySheet ) 1382*cdf0e10cSrcweir { 1383*cdf0e10cSrcweir orRange = CellRangeAddress( static_cast< sal_Int16 >( rComplexRef.Reference1.Sheet ), 1384*cdf0e10cSrcweir rComplexRef.Reference1.Column, rComplexRef.Reference1.Row, 1385*cdf0e10cSrcweir rComplexRef.Reference2.Column, rComplexRef.Reference2.Row ); 1386*cdf0e10cSrcweir return 1387*cdf0e10cSrcweir !getFlag( rComplexRef.Reference1.Flags, nForbiddenFlags ) && 1388*cdf0e10cSrcweir !getFlag( rComplexRef.Reference2.Flags, nForbiddenFlags ) && 1389*cdf0e10cSrcweir (rComplexRef.Reference1.Sheet == rComplexRef.Reference2.Sheet) && 1390*cdf0e10cSrcweir ((nFilterBySheet < 0) || (nFilterBySheet == rComplexRef.Reference1.Sheet)); 1391*cdf0e10cSrcweir } 1392*cdf0e10cSrcweir 1393*cdf0e10cSrcweir enum TokenToRangeListState { STATE_REF, STATE_SEP, STATE_OPEN, STATE_CLOSE, STATE_ERROR }; 1394*cdf0e10cSrcweir 1395*cdf0e10cSrcweir TokenToRangeListState lclProcessRef( ApiCellRangeList& orRanges, const Any& rData, bool bAllowRelative, sal_Int32 nFilterBySheet ) 1396*cdf0e10cSrcweir { 1397*cdf0e10cSrcweir using namespace ::com::sun::star::sheet::ReferenceFlags; 1398*cdf0e10cSrcweir const sal_Int32 FORBIDDEN_FLAGS_DEL = COLUMN_DELETED | ROW_DELETED | SHEET_DELETED; 1399*cdf0e10cSrcweir const sal_Int32 FORBIDDEN_FLAGS_REL = FORBIDDEN_FLAGS_DEL | COLUMN_RELATIVE | ROW_RELATIVE | SHEET_RELATIVE | RELATIVE_NAME; 1400*cdf0e10cSrcweir 1401*cdf0e10cSrcweir sal_Int32 nForbiddenFlags = bAllowRelative ? FORBIDDEN_FLAGS_DEL : FORBIDDEN_FLAGS_REL; 1402*cdf0e10cSrcweir SingleReference aSingleRef; 1403*cdf0e10cSrcweir if( rData >>= aSingleRef ) 1404*cdf0e10cSrcweir { 1405*cdf0e10cSrcweir CellAddress aAddress; 1406*cdf0e10cSrcweir // ignore invalid addresses (with #REF! errors), but do not stop parsing 1407*cdf0e10cSrcweir if( lclConvertToCellAddress( aAddress, aSingleRef, nForbiddenFlags, nFilterBySheet ) ) 1408*cdf0e10cSrcweir orRanges.push_back( CellRangeAddress( aAddress.Sheet, aAddress.Column, aAddress.Row, aAddress.Column, aAddress.Row ) ); 1409*cdf0e10cSrcweir return STATE_REF; 1410*cdf0e10cSrcweir } 1411*cdf0e10cSrcweir ComplexReference aComplexRef; 1412*cdf0e10cSrcweir if( rData >>= aComplexRef ) 1413*cdf0e10cSrcweir { 1414*cdf0e10cSrcweir CellRangeAddress aRange; 1415*cdf0e10cSrcweir // ignore invalid ranges (with #REF! errors), but do not stop parsing 1416*cdf0e10cSrcweir if( lclConvertToCellRange( aRange, aComplexRef, nForbiddenFlags, nFilterBySheet ) ) 1417*cdf0e10cSrcweir orRanges.push_back( aRange ); 1418*cdf0e10cSrcweir return STATE_REF; 1419*cdf0e10cSrcweir } 1420*cdf0e10cSrcweir return STATE_ERROR; 1421*cdf0e10cSrcweir } 1422*cdf0e10cSrcweir 1423*cdf0e10cSrcweir TokenToRangeListState lclProcessOpen( sal_Int32& ornParenLevel ) 1424*cdf0e10cSrcweir { 1425*cdf0e10cSrcweir ++ornParenLevel; 1426*cdf0e10cSrcweir return STATE_OPEN; 1427*cdf0e10cSrcweir } 1428*cdf0e10cSrcweir 1429*cdf0e10cSrcweir TokenToRangeListState lclProcessClose( sal_Int32& ornParenLevel ) 1430*cdf0e10cSrcweir { 1431*cdf0e10cSrcweir --ornParenLevel; 1432*cdf0e10cSrcweir return (ornParenLevel >= 0) ? STATE_CLOSE : STATE_ERROR; 1433*cdf0e10cSrcweir } 1434*cdf0e10cSrcweir 1435*cdf0e10cSrcweir } // namespace 1436*cdf0e10cSrcweir 1437*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 1438*cdf0e10cSrcweir 1439*cdf0e10cSrcweir FormulaProcessorBase::FormulaProcessorBase( const WorkbookHelper& rHelper ) : 1440*cdf0e10cSrcweir OpCodeProvider( rHelper.getBaseFilter().getModelFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ), 1441*cdf0e10cSrcweir ApiOpCodes( getOpCodes() ), 1442*cdf0e10cSrcweir WorkbookHelper( rHelper ) 1443*cdf0e10cSrcweir { 1444*cdf0e10cSrcweir } 1445*cdf0e10cSrcweir 1446*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 1447*cdf0e10cSrcweir 1448*cdf0e10cSrcweir OUString FormulaProcessorBase::generateAddress2dString( const CellAddress& rAddress, bool bAbsolute ) 1449*cdf0e10cSrcweir { 1450*cdf0e10cSrcweir return generateAddress2dString( BinAddress( rAddress ), bAbsolute ); 1451*cdf0e10cSrcweir } 1452*cdf0e10cSrcweir 1453*cdf0e10cSrcweir OUString FormulaProcessorBase::generateAddress2dString( const BinAddress& rAddress, bool bAbsolute ) 1454*cdf0e10cSrcweir { 1455*cdf0e10cSrcweir OUStringBuffer aBuffer; 1456*cdf0e10cSrcweir // column 1457*cdf0e10cSrcweir for( sal_Int32 nTemp = rAddress.mnCol; nTemp >= 0; (nTemp /= 26) -= 1 ) 1458*cdf0e10cSrcweir aBuffer.insert( 0, sal_Unicode( 'A' + (nTemp % 26) ) ); 1459*cdf0e10cSrcweir if( bAbsolute ) 1460*cdf0e10cSrcweir aBuffer.insert( 0, sal_Unicode( '$' ) ); 1461*cdf0e10cSrcweir // row 1462*cdf0e10cSrcweir if( bAbsolute ) 1463*cdf0e10cSrcweir aBuffer.append( sal_Unicode( '$' ) ); 1464*cdf0e10cSrcweir aBuffer.append( static_cast< sal_Int32 >( rAddress.mnRow + 1 ) ); 1465*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 1466*cdf0e10cSrcweir } 1467*cdf0e10cSrcweir 1468*cdf0e10cSrcweir OUString FormulaProcessorBase::generateRange2dString( const CellRangeAddress& rRange, bool bAbsolute ) 1469*cdf0e10cSrcweir { 1470*cdf0e10cSrcweir return generateRange2dString( BinRange( rRange ), bAbsolute ); 1471*cdf0e10cSrcweir } 1472*cdf0e10cSrcweir 1473*cdf0e10cSrcweir OUString FormulaProcessorBase::generateRange2dString( const BinRange& rRange, bool bAbsolute ) 1474*cdf0e10cSrcweir { 1475*cdf0e10cSrcweir OUStringBuffer aBuffer( generateAddress2dString( rRange.maFirst, bAbsolute ) ); 1476*cdf0e10cSrcweir if( (rRange.getColCount() > 1) || (rRange.getRowCount() > 1) ) 1477*cdf0e10cSrcweir aBuffer.append( sal_Unicode( ':' ) ).append( generateAddress2dString( rRange.maLast, bAbsolute ) ); 1478*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 1479*cdf0e10cSrcweir } 1480*cdf0e10cSrcweir 1481*cdf0e10cSrcweir OUString FormulaProcessorBase::generateRangeList2dString( const ApiCellRangeList& rRanges, 1482*cdf0e10cSrcweir bool bAbsolute, sal_Unicode cSeparator, bool bEncloseMultiple ) 1483*cdf0e10cSrcweir { 1484*cdf0e10cSrcweir OUStringBuffer aBuffer; 1485*cdf0e10cSrcweir for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt ) 1486*cdf0e10cSrcweir { 1487*cdf0e10cSrcweir if( aBuffer.getLength() > 0 ) 1488*cdf0e10cSrcweir aBuffer.append( cSeparator ); 1489*cdf0e10cSrcweir aBuffer.append( generateRange2dString( *aIt, bAbsolute ) ); 1490*cdf0e10cSrcweir } 1491*cdf0e10cSrcweir if( bEncloseMultiple && (rRanges.size() > 1) ) 1492*cdf0e10cSrcweir aBuffer.insert( 0, sal_Unicode( '(' ) ).append( sal_Unicode( ')' ) ); 1493*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 1494*cdf0e10cSrcweir } 1495*cdf0e10cSrcweir 1496*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 1497*cdf0e10cSrcweir 1498*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiAddressString( const CellAddress& rAddress ) const 1499*cdf0e10cSrcweir { 1500*cdf0e10cSrcweir OUString aCellName; 1501*cdf0e10cSrcweir PropertySet aCellProp( getCellFromDoc( rAddress ) ); 1502*cdf0e10cSrcweir aCellProp.getProperty( aCellName, PROP_AbsoluteName ); 1503*cdf0e10cSrcweir OSL_ENSURE( aCellName.getLength() > 0, "FormulaProcessorBase::generateApiAddressString - cannot create cell address string" ); 1504*cdf0e10cSrcweir return aCellName; 1505*cdf0e10cSrcweir } 1506*cdf0e10cSrcweir 1507*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiRangeString( const CellRangeAddress& rRange ) const 1508*cdf0e10cSrcweir { 1509*cdf0e10cSrcweir OUString aRangeName; 1510*cdf0e10cSrcweir PropertySet aRangeProp( getCellRangeFromDoc( rRange ) ); 1511*cdf0e10cSrcweir aRangeProp.getProperty( aRangeName, PROP_AbsoluteName ); 1512*cdf0e10cSrcweir OSL_ENSURE( aRangeName.getLength() > 0, "FormulaProcessorBase::generateApiRangeString - cannot create cell range string" ); 1513*cdf0e10cSrcweir return aRangeName; 1514*cdf0e10cSrcweir } 1515*cdf0e10cSrcweir 1516*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiRangeListString( const ApiCellRangeList& rRanges ) const 1517*cdf0e10cSrcweir { 1518*cdf0e10cSrcweir OUStringBuffer aBuffer; 1519*cdf0e10cSrcweir for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt ) 1520*cdf0e10cSrcweir { 1521*cdf0e10cSrcweir OUString aRangeName = generateApiRangeString( *aIt ); 1522*cdf0e10cSrcweir if( aRangeName.getLength() > 0 ) 1523*cdf0e10cSrcweir { 1524*cdf0e10cSrcweir if( aBuffer.getLength() > 0 ) 1525*cdf0e10cSrcweir aBuffer.append( API_TOKEN_SEP ); 1526*cdf0e10cSrcweir aBuffer.append( aRangeName ); 1527*cdf0e10cSrcweir } 1528*cdf0e10cSrcweir } 1529*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 1530*cdf0e10cSrcweir } 1531*cdf0e10cSrcweir 1532*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiString( const OUString& rString ) 1533*cdf0e10cSrcweir { 1534*cdf0e10cSrcweir OUString aRetString = rString; 1535*cdf0e10cSrcweir sal_Int32 nQuotePos = aRetString.getLength(); 1536*cdf0e10cSrcweir while( (nQuotePos = aRetString.lastIndexOf( '"', nQuotePos )) >= 0 ) 1537*cdf0e10cSrcweir aRetString = aRetString.replaceAt( nQuotePos, 1, CREATE_OUSTRING( "\"\"" ) ); 1538*cdf0e10cSrcweir return OUStringBuffer().append( sal_Unicode( '"' ) ).append( aRetString ).append( sal_Unicode( '"' ) ).makeStringAndClear(); 1539*cdf0e10cSrcweir } 1540*cdf0e10cSrcweir 1541*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiArray( const Matrix< Any >& rMatrix ) 1542*cdf0e10cSrcweir { 1543*cdf0e10cSrcweir OSL_ENSURE( !rMatrix.empty(), "FormulaProcessorBase::generateApiArray - missing matrix values" ); 1544*cdf0e10cSrcweir OUStringBuffer aBuffer; 1545*cdf0e10cSrcweir aBuffer.append( API_TOKEN_ARRAY_OPEN ); 1546*cdf0e10cSrcweir for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow ) 1547*cdf0e10cSrcweir { 1548*cdf0e10cSrcweir if( nRow > 0 ) 1549*cdf0e10cSrcweir aBuffer.append( API_TOKEN_ARRAY_ROWSEP ); 1550*cdf0e10cSrcweir for( Matrix< Any >::const_iterator aBeg = rMatrix.row_begin( nRow ), aIt = aBeg, aEnd = rMatrix.row_end( nRow ); aIt != aEnd; ++aIt ) 1551*cdf0e10cSrcweir { 1552*cdf0e10cSrcweir double fValue = 0.0; 1553*cdf0e10cSrcweir OUString aString; 1554*cdf0e10cSrcweir if( aIt != aBeg ) 1555*cdf0e10cSrcweir aBuffer.append( API_TOKEN_ARRAY_COLSEP ); 1556*cdf0e10cSrcweir if( *aIt >>= fValue ) 1557*cdf0e10cSrcweir aBuffer.append( fValue ); 1558*cdf0e10cSrcweir else if( *aIt >>= aString ) 1559*cdf0e10cSrcweir aBuffer.append( generateApiString( aString ) ); 1560*cdf0e10cSrcweir else 1561*cdf0e10cSrcweir aBuffer.appendAscii( "\"\"" ); 1562*cdf0e10cSrcweir } 1563*cdf0e10cSrcweir } 1564*cdf0e10cSrcweir aBuffer.append( API_TOKEN_ARRAY_CLOSE ); 1565*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 1566*cdf0e10cSrcweir } 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir // ---------------------------------------------------------------------------- 1569*cdf0e10cSrcweir 1570*cdf0e10cSrcweir Any FormulaProcessorBase::extractReference( const ApiTokenSequence& rTokens ) const 1571*cdf0e10cSrcweir { 1572*cdf0e10cSrcweir ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true ); 1573*cdf0e10cSrcweir if( aTokenIt.is() && (aTokenIt->OpCode == OPCODE_PUSH) ) 1574*cdf0e10cSrcweir { 1575*cdf0e10cSrcweir Any aRefAny = aTokenIt->Data; 1576*cdf0e10cSrcweir if( !(++aTokenIt).is() && (aRefAny.has< SingleReference >() || aRefAny.has< ComplexReference >()) ) 1577*cdf0e10cSrcweir return aRefAny; 1578*cdf0e10cSrcweir } 1579*cdf0e10cSrcweir return Any(); 1580*cdf0e10cSrcweir } 1581*cdf0e10cSrcweir 1582*cdf0e10cSrcweir bool FormulaProcessorBase::extractCellAddress( CellAddress& orAddress, 1583*cdf0e10cSrcweir const ApiTokenSequence& rTokens, bool bAllowRelative ) const 1584*cdf0e10cSrcweir { 1585*cdf0e10cSrcweir CellRangeAddress aRange; 1586*cdf0e10cSrcweir if( extractCellRange( aRange, rTokens, bAllowRelative ) && (aRange.StartColumn == aRange.EndColumn) && (aRange.StartRow == aRange.EndRow) ) 1587*cdf0e10cSrcweir { 1588*cdf0e10cSrcweir orAddress.Sheet = aRange.Sheet; 1589*cdf0e10cSrcweir orAddress.Column = aRange.StartColumn; 1590*cdf0e10cSrcweir orAddress.Row = aRange.StartRow; 1591*cdf0e10cSrcweir return true; 1592*cdf0e10cSrcweir } 1593*cdf0e10cSrcweir return false; 1594*cdf0e10cSrcweir } 1595*cdf0e10cSrcweir 1596*cdf0e10cSrcweir bool FormulaProcessorBase::extractCellRange( CellRangeAddress& orRange, 1597*cdf0e10cSrcweir const ApiTokenSequence& rTokens, bool bAllowRelative ) const 1598*cdf0e10cSrcweir { 1599*cdf0e10cSrcweir ApiCellRangeList aRanges; 1600*cdf0e10cSrcweir lclProcessRef( aRanges, extractReference( rTokens ), bAllowRelative, -1 ); 1601*cdf0e10cSrcweir if( !aRanges.empty() ) 1602*cdf0e10cSrcweir { 1603*cdf0e10cSrcweir orRange = aRanges.front(); 1604*cdf0e10cSrcweir return true; 1605*cdf0e10cSrcweir } 1606*cdf0e10cSrcweir return false; 1607*cdf0e10cSrcweir } 1608*cdf0e10cSrcweir 1609*cdf0e10cSrcweir void FormulaProcessorBase::extractCellRangeList( ApiCellRangeList& orRanges, 1610*cdf0e10cSrcweir const ApiTokenSequence& rTokens, bool bAllowRelative, sal_Int32 nFilterBySheet ) const 1611*cdf0e10cSrcweir { 1612*cdf0e10cSrcweir orRanges.clear(); 1613*cdf0e10cSrcweir TokenToRangeListState eState = STATE_OPEN; 1614*cdf0e10cSrcweir sal_Int32 nParenLevel = 0; 1615*cdf0e10cSrcweir for( ApiTokenIterator aIt( rTokens, OPCODE_SPACES, true ); aIt.is() && (eState != STATE_ERROR); ++aIt ) 1616*cdf0e10cSrcweir { 1617*cdf0e10cSrcweir sal_Int32 nOpCode = aIt->OpCode; 1618*cdf0e10cSrcweir switch( eState ) 1619*cdf0e10cSrcweir { 1620*cdf0e10cSrcweir // #i107275# accept OPCODE_SEP and OPCODE_LIST as separator token 1621*cdf0e10cSrcweir case STATE_REF: 1622*cdf0e10cSrcweir if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; 1623*cdf0e10cSrcweir else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; 1624*cdf0e10cSrcweir else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); 1625*cdf0e10cSrcweir else eState = STATE_ERROR; 1626*cdf0e10cSrcweir break; 1627*cdf0e10cSrcweir case STATE_SEP: 1628*cdf0e10cSrcweir if( nOpCode == OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet ); 1629*cdf0e10cSrcweir else if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; 1630*cdf0e10cSrcweir else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; 1631*cdf0e10cSrcweir else if( nOpCode == OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel ); 1632*cdf0e10cSrcweir else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); 1633*cdf0e10cSrcweir else eState = STATE_ERROR; 1634*cdf0e10cSrcweir break; 1635*cdf0e10cSrcweir case STATE_OPEN: 1636*cdf0e10cSrcweir if( nOpCode == OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet ); 1637*cdf0e10cSrcweir else if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; 1638*cdf0e10cSrcweir else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; 1639*cdf0e10cSrcweir else if( nOpCode == OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel ); 1640*cdf0e10cSrcweir else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); 1641*cdf0e10cSrcweir else eState = STATE_ERROR; 1642*cdf0e10cSrcweir break; 1643*cdf0e10cSrcweir case STATE_CLOSE: 1644*cdf0e10cSrcweir if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; 1645*cdf0e10cSrcweir else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; 1646*cdf0e10cSrcweir else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); 1647*cdf0e10cSrcweir else eState = STATE_ERROR; 1648*cdf0e10cSrcweir break; 1649*cdf0e10cSrcweir default:; 1650*cdf0e10cSrcweir } 1651*cdf0e10cSrcweir } 1652*cdf0e10cSrcweir 1653*cdf0e10cSrcweir if( eState == STATE_ERROR ) 1654*cdf0e10cSrcweir orRanges.clear(); 1655*cdf0e10cSrcweir else 1656*cdf0e10cSrcweir getAddressConverter().validateCellRangeList( orRanges, false ); 1657*cdf0e10cSrcweir } 1658*cdf0e10cSrcweir 1659*cdf0e10cSrcweir bool FormulaProcessorBase::extractString( OUString& orString, const ApiTokenSequence& rTokens ) const 1660*cdf0e10cSrcweir { 1661*cdf0e10cSrcweir ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true ); 1662*cdf0e10cSrcweir return aTokenIt.is() && (aTokenIt->OpCode == OPCODE_PUSH) && (aTokenIt->Data >>= orString) && !(++aTokenIt).is(); 1663*cdf0e10cSrcweir } 1664*cdf0e10cSrcweir 1665*cdf0e10cSrcweir bool FormulaProcessorBase::extractSpecialTokenInfo( ApiSpecialTokenInfo& orTokenInfo, const ApiTokenSequence& rTokens ) const 1666*cdf0e10cSrcweir { 1667*cdf0e10cSrcweir ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true ); 1668*cdf0e10cSrcweir return aTokenIt.is() && (aTokenIt->OpCode == OPCODE_BAD) && (aTokenIt->Data >>= orTokenInfo); 1669*cdf0e10cSrcweir } 1670*cdf0e10cSrcweir 1671*cdf0e10cSrcweir void FormulaProcessorBase::convertStringToStringList( 1672*cdf0e10cSrcweir ApiTokenSequence& orTokens, sal_Unicode cStringSep, bool bTrimLeadingSpaces ) const 1673*cdf0e10cSrcweir { 1674*cdf0e10cSrcweir OUString aString; 1675*cdf0e10cSrcweir if( extractString( aString, orTokens ) && (aString.getLength() > 0) ) 1676*cdf0e10cSrcweir { 1677*cdf0e10cSrcweir ::std::vector< ApiToken > aNewTokens; 1678*cdf0e10cSrcweir sal_Int32 nPos = 0; 1679*cdf0e10cSrcweir sal_Int32 nLen = aString.getLength(); 1680*cdf0e10cSrcweir while( (0 <= nPos) && (nPos < nLen) ) 1681*cdf0e10cSrcweir { 1682*cdf0e10cSrcweir OUString aEntry = aString.getToken( 0, cStringSep, nPos ); 1683*cdf0e10cSrcweir if( bTrimLeadingSpaces ) 1684*cdf0e10cSrcweir { 1685*cdf0e10cSrcweir sal_Int32 nStart = 0; 1686*cdf0e10cSrcweir while( (nStart < aEntry.getLength()) && (aEntry[ nStart ] == ' ') ) ++nStart; 1687*cdf0e10cSrcweir aEntry = aEntry.copy( nStart ); 1688*cdf0e10cSrcweir } 1689*cdf0e10cSrcweir if( !aNewTokens.empty() ) 1690*cdf0e10cSrcweir aNewTokens.push_back( ApiToken( OPCODE_SEP, Any() ) ); 1691*cdf0e10cSrcweir aNewTokens.push_back( ApiToken( OPCODE_PUSH, Any( aEntry ) ) ); 1692*cdf0e10cSrcweir } 1693*cdf0e10cSrcweir orTokens = ContainerHelper::vectorToSequence( aNewTokens ); 1694*cdf0e10cSrcweir } 1695*cdf0e10cSrcweir } 1696*cdf0e10cSrcweir 1697*cdf0e10cSrcweir // ============================================================================ 1698*cdf0e10cSrcweir 1699*cdf0e10cSrcweir } // namespace xls 1700*cdf0e10cSrcweir } // namespace oox 1701