Hi, I have submitted a patch for review:
https://gerrit.libreoffice.org/1522 To pull it, you can do: git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/22/1522/1 fdo#56124 add functions IFERROR and IFNA to calc as in ODFF1.2 Change-Id: I6403b51ac8c710ad3b8d2625e1482971f50e6b1d --- M dictionaries M formula/inc/formula/compiler.hrc M formula/inc/formula/opcode.hxx M formula/source/core/api/FormulaCompiler.cxx M formula/source/core/api/token.cxx M formula/source/core/resource/core_resource.src M helpcontent2 M sc/inc/helpids.h M sc/qa/unit/ucalc.cxx M sc/source/core/inc/interpre.hxx M sc/source/core/tool/interpr1.cxx M sc/source/core/tool/interpr4.cxx M sc/source/core/tool/parclass.cxx M sc/source/core/tool/token.cxx M sc/source/ui/src/scfuncs.src M sc/util/hidother.src 16 files changed, 284 insertions(+), 40 deletions(-) diff --git a/dictionaries b/dictionaries index f0c914a..1595bf1 160000 --- a/dictionaries +++ b/dictionaries -Subproject commit f0c914a43e7e6540300da25c935a77aebb672094 +Subproject commit 1595bf11e295d96123fcb327ba9919307aa5b127 diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc index 582e3a5..7f976ae 100644 --- a/formula/inc/formula/compiler.hrc +++ b/formula/inc/formula/compiler.hrc @@ -29,26 +29,28 @@ #define SC_OPCODE_NAME 4 #define SC_OPCODE_EXTERNAL_REF 5 #define SC_OPCODE_IF 6 /* jump commands */ -#define SC_OPCODE_CHOSE 7 -#define SC_OPCODE_OPEN 8 /* parentheses and separators */ -#define SC_OPCODE_CLOSE 9 -#define SC_OPCODE_SEP 10 -#define SC_OPCODE_MISSING 11 /* special OpCodes */ -#define SC_OPCODE_BAD 12 -#define SC_OPCODE_STRINGXML 13 -#define SC_OPCODE_SPACES 14 -#define SC_OPCODE_MAT_REF 15 -#define SC_OPCODE_DB_AREA 16 /* additional access operators */ -#define SC_OPCODE_MACRO 17 -#define SC_OPCODE_COL_ROW_NAME 18 -#define SC_OPCODE_COL_ROW_NAME_AUTO 19 -#define SC_OPCODE_PERCENT_SIGN 20 /* operator _follows_ value */ -#define SC_OPCODE_ARRAY_OPEN 21 -#define SC_OPCODE_ARRAY_CLOSE 22 -#define SC_OPCODE_ARRAY_ROW_SEP 23 -#define SC_OPCODE_ARRAY_COL_SEP 24 /* some convs use sep != col_sep */ -#define SC_OPCODE_STOP_DIV 25 -#define SC_OPCODE_SKIP 26 /* used to skip raw tokens during string compilation */ +#define SC_OPCODE_IF_ERROR 7 +#define SC_OPCODE_IF_NA 8 +#define SC_OPCODE_CHOSE 9 +#define SC_OPCODE_OPEN 10 /* parentheses and separators */ +#define SC_OPCODE_CLOSE 11 +#define SC_OPCODE_SEP 12 +#define SC_OPCODE_MISSING 13 /* special OpCodes */ +#define SC_OPCODE_BAD 14 +#define SC_OPCODE_STRINGXML 15 +#define SC_OPCODE_SPACES 16 +#define SC_OPCODE_MAT_REF 17 +#define SC_OPCODE_DB_AREA 18 /* additional access operators */ +#define SC_OPCODE_MACRO 19 +#define SC_OPCODE_COL_ROW_NAME 20 +#define SC_OPCODE_COL_ROW_NAME_AUTO 21 +#define SC_OPCODE_PERCENT_SIGN 22 /* operator _follows_ value */ +#define SC_OPCODE_ARRAY_OPEN 23 +#define SC_OPCODE_ARRAY_CLOSE 24 +#define SC_OPCODE_ARRAY_ROW_SEP 25 +#define SC_OPCODE_ARRAY_COL_SEP 26 /* some convs use sep != col_sep */ +#define SC_OPCODE_STOP_DIV 27 +#define SC_OPCODE_SKIP 28 /* used to skip raw tokens during string compilation */ /*** error constants #... ***/ #define SC_OPCODE_START_ERRORS 30 diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx index cd1831b..e37395e 100644 --- a/formula/inc/formula/opcode.hxx +++ b/formula/inc/formula/opcode.hxx @@ -34,6 +34,8 @@ ocExternalRef = SC_OPCODE_EXTERNAL_REF, // Jump commands ocIf = SC_OPCODE_IF, + ocIfError = SC_OPCODE_IF_ERROR, + ocIfNA = SC_OPCODE_IF_NA, ocChose = SC_OPCODE_CHOSE, // Parentheses and separators ocOpen = SC_OPCODE_OPEN, diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 29b6694..f51f606 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -824,7 +824,7 @@ { switch ((*iLook).second) { - // Not all may make sense in a formula, but these we know as + // Not all may make sense in a formula, but these we know as // opcodes. case ocErrNull: nError = errNoCode; @@ -1125,7 +1125,8 @@ || eOp == ocOr || eOp == ocBad || ( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) - || (bCompileForFAP && ((eOp == ocIf) || (eOp == ocChose))) + || ( bCompileForFAP + && ( eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChose ) ) ) { pFacToken = mpToken; @@ -1174,14 +1175,16 @@ pFacToken->SetByte( nSepCount ); PutCode( pFacToken ); } - else if (eOp == ocIf || eOp == ocChose) + else if (eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChose) { // the PC counters are -1 pFacToken = mpToken; if ( eOp == ocIf ) pFacToken->GetJump()[ 0 ] = 3; // if, else, behind - else + else if ( eOp == ocChose ) pFacToken->GetJump()[ 0 ] = MAXJUMPCOUNT+1; + else + pFacToken->GetJump()[ 0 ] = 2; // if, else eOp = NextToken(); if (eOp == ocOpen) { @@ -1195,9 +1198,10 @@ // during AutoCorrect (since pArr->GetCodeError() is // ignored) an unlimited ocIf would crash because // ScRawToken::Clone() allocates the JumpBuffer according to - // nJump[0]*2+2, which is 3*2+2 on ocIf. - const short nJumpMax = - (pFacToken->GetOpCode() == ocIf ? 3 : MAXJUMPCOUNT); + // nJump[0]*2+2, which is 3*2+2 on ocIf and 2*2+2 ocIfError and ocIfNA. + OpCode eFacOpCode = pFacToken->GetOpCode(); + const short nJumpMax = ( eFacOpCode == ocIf ? 3 : + ( eFacOpCode == ocChose ? MAXJUMPCOUNT : 2 ) ); while ( (nJumpCount < (MAXJUMPCOUNT - 1)) && (eOp == ocSep) && (!pArr->GetCodeError() || bIgnoreErrors) ) { @@ -1216,8 +1220,10 @@ // always limit to nJumpMax, no arbitrary overwrites if ( ++nJumpCount <= nJumpMax ) pFacToken->GetJump()[ nJumpCount ] = pc-1; - if ((pFacToken->GetOpCode() == ocIf && (nJumpCount > 3)) || - (nJumpCount >= MAXJUMPCOUNT)) + eFacOpCode = pFacToken->GetOpCode(); + if ( ( eFacOpCode == ocIf && nJumpCount > 3) || + ( ( eFacOpCode == ocIfError || eFacOpCode == ocIfNA ) && nJumpCount > 2 ) || + ( nJumpCount >= MAXJUMPCOUNT ) ) SetError(errIllegalParameter); else pFacToken->GetJump()[ 0 ] = nJumpCount; diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index d187073..f6110e7c 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -76,7 +76,7 @@ eOp != ocColRowNameAuto && eOp != ocName && eOp != ocDBArea && (GetByte() != 0 // x parameters || (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) // no parameter - || (ocIf == eOp || ocChose == eOp ) // @ jump commands + || (ocIf == eOp || ocIfError == eOp || ocIfNA == eOp || ocChose == eOp ) // @ jump commands || (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) // one parameter || (SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) // x parameters (cByte==0 in // FuncAutoPilot) @@ -91,9 +91,10 @@ sal_uInt8 FormulaToken::GetParamCount() const { if ( eOp < SC_OPCODE_STOP_DIV && eOp != ocExternal && eOp != ocMacro && - eOp != ocIf && eOp != ocChose && eOp != ocPercentSign ) + eOp != ocIf && eOp != ocIfError && eOp != ocIfNA && eOp != ocChose && + eOp != ocPercentSign ) return 0; // parameters and specials - // ocIf and ocChose not for FAP, have cByte then + // ocIf, ocIfError, ocIfNA and ocChose not for FAP, have cByte then //2do: bool parameter whether FAP or not? else if ( GetByte() ) return GetByte(); // all functions, also ocExternal and ocMacro @@ -106,7 +107,7 @@ return 0; // no parameter else if (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) return 1; // one parameter - else if ( eOp == ocIf || eOp == ocChose ) + else if ( eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChose ) return 1; // only the condition counts as parameter else return 0; // all the rest, no Parameter, or @@ -842,8 +843,8 @@ } if ( eOp == ocPush || lcl_IsReference( eOp, t->GetType() ) ) pStack[sp++] = t; - else if ( eOp == ocIf || eOp == ocChose ) - { // Jumps ignorieren, vorheriges Result (Condition) poppen + else if ( eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChose ) + { // ignore Jumps, pop previous Result (Condition) if ( sp ) --sp; } @@ -1178,10 +1179,17 @@ pRet = new FormulaToken( svSep,eOp ); break; case ocIf: + case ocIfError: + case ocIfNA: case ocChose: { short nJump[MAXJUMPCOUNT + 1]; - nJump[ 0 ] = ocIf == eOp ? 3 : MAXJUMPCOUNT+1; + if ( eOp == ocIf ) + nJump[ 0 ] = 3; + else if ( eOp == ocChose ) + nJump[ 0 ] = MAXJUMPCOUNT + 1; + else + nJump[ 0 ] = 2; pRet = new FormulaJumpToken( eOp, (short*)nJump ); } break; diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src index 8b0ee14..1852d58 100644 --- a/formula/source/core/resource/core_resource.src +++ b/formula/source/core/resource/core_resource.src @@ -24,6 +24,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF { String SC_OPCODE_IF { Text = "IF" ; }; + String SC_OPCODE_IF_NA { Text = "IFERROR" ; }; + String SC_OPCODE_IF_ERROR { Text = "IFNA" ; }; String SC_OPCODE_CHOSE { Text = "CHOOSE" ; }; String SC_OPCODE_OPEN { Text = "(" ; }; String SC_OPCODE_CLOSE { Text = ")" ; }; @@ -362,6 +364,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH { String SC_OPCODE_IF { Text = "IF" ; }; + String SC_OPCODE_IF_ERROR { Text = "IFERROR" ; }; + String SC_OPCODE_IF_NA { Text = "IFNA" ; }; String SC_OPCODE_CHOSE { Text = "CHOOSE" ; }; String SC_OPCODE_OPEN { Text = "(" ; }; String SC_OPCODE_CLOSE { Text = ")" ; }; @@ -700,6 +704,14 @@ { Text [ en-US ] = "IF" ; }; + String SC_OPCODE_IF_ERROR + { + Text [ en-US ] = "IFERROR" ; + }; + String SC_OPCODE_IF_NA + { + Text [ en-US ] = "IFNA" ; + }; String SC_OPCODE_CHOSE { Text [ en-US ] = "CHOOSE" ; diff --git a/helpcontent2 b/helpcontent2 index d5d84f0..1909df0 160000 --- a/helpcontent2 +++ b/helpcontent2 -Subproject commit d5d84f0ec4584e32147eeab355d0ab73e7dd9172 +Subproject commit 1909df07cbd54bf753514cc6dc4137b7b69af63c diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h index 2e2aa4c..e273ce4 100644 --- a/sc/inc/helpids.h +++ b/sc/inc/helpids.h @@ -433,6 +433,8 @@ #define HID_FUNC_NICHT "SC_HID_FUNC_NICHT" #define HID_FUNC_WAHR "SC_HID_FUNC_WAHR" #define HID_FUNC_WENN "SC_HID_FUNC_WENN" +#define HID_FUNC_IFERROR "SC_HID_FUNC_IFERROR" +#define HID_FUNC_IFNA "SC_HID_FUNC_IFNA" #define HID_FUNC_ODER "SC_HID_FUNC_ODER" #define HID_FUNC_UND "SC_HID_FUNC_UND" #define HID_FUNC_XOR "SC_HID_FUNC_XOR" diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 55b8b9c..b0dccf7 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -3932,6 +3932,8 @@ "CELL", "CURRENT", "FORMULA", + "IFERROR", + "IFNA", "INFO", "ISBLANK", "ISERR", diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 762b818..267e659 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -368,6 +368,7 @@ const ScQueryParam & rParam ) const; void ScIfJump(); +void ScIfError( bool bNAonly ); void ScChoseJump(); // Be sure to only call this if pStack[sp-nStackLevel] really contains a diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 0b86108..a022015 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -240,6 +240,138 @@ } +void ScInterpreter::ScIfError( bool bNAonly ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIfError" ); + const short* pJump = pCur->GetJump(); + if ( !pJump ) + { + PushIllegalParameter(); + return; + } + short nJumpCount = pJump[ 0 ]; + if ( nJumpCount != 2 ) + { + PushIllegalArgument(); + return; + } + + if ( nGlobalError == 0 || ( bNAonly && nGlobalError != NOTAVAILABLE ) ) + { + MatrixDoubleRefToMatrix(); + switch ( GetStackType() ) + { + case svDoubleRef: + case svSingleRef: + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushIllegalArgument(); + return; + } + ScBaseCell* pCell = GetCell( aAdr ); + sal_uInt16 nErr = GetCellErrCode( pCell ); + if ( nErr == 0 || ( bNAonly && nErr != NOTAVAILABLE ) ) + { + // no error, return 1st argument + if ( pCell && pCell->HasValueData() ) + { + PushDouble( GetCellValue(aAdr, pCell) ); + aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] ); + return; + } + else + { + String aInputString; + GetCellString( aInputString, pCell ); + PushString( aInputString ); + aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] ); + return; + } + } + } + break; + case svMatrix: + { + nFuncFmtType = NUMBERFORMAT_NUMBER; + ScMatrixRef pMat = PopMatrix(); + if ( pMat && ( !nGlobalError || ( bNAonly && nGlobalError != NOTAVAILABLE ) ) ) + { + FormulaTokenRef xNew; + ScTokenMatrixMap::const_iterator aMapIter; + SCSIZE nCols, nRows; + pMat->SetErrorInterpreter( NULL ); + pMat->GetDimensions( nCols, nRows ); + if ( nCols > 0 && nRows > 0 ) + { + if ( pTokenMatrixMap && + ( ( aMapIter = pTokenMatrixMap->find( pCur ) ) != pTokenMatrixMap->end() ) ) + { + xNew = (*aMapIter).second; + } + else + { + ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows ); + for ( SCSIZE nC = 0; nC < nCols; ++nC ) + { + for ( SCSIZE nR = 0; nR < nRows; ++nR ) + { + double fVal; + sal_uInt16 nErr; + bool bIsValue = pMat->IsValue(nC, nR); + if ( bIsValue ) + { + fVal = pMat->GetDouble( nC, nR ); + nErr = !( pMat->GetError( nC, nR ) == 0 || + ( bNAonly && + pMat->GetError( nC, nR )!= NOTAVAILABLE ) ); + } + else + { + fVal = 0.0; + nErr = 1; + } + + if ( nErr == 0 ) + { // no error, return 1st argument + pJumpMat->SetJump( nC, nR, fVal, + pJump[ nJumpCount ], pJump[ nJumpCount ] ); + } + else + { + // error, return 2nd argument + pJumpMat->SetJump( nC, nR, fVal, + pJump[ 1 ], pJump[ nJumpCount ] ); + } + } + } + xNew = new ScJumpMatrixToken( pJumpMat ); + GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur, xNew )); + } + } + PushTempToken( xNew.get() ); + // set endpoint of path for main code line + aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] ); + return; + } + } + break; + default: + { + //other stacktypes, no error, return 1st argument + aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] ); + return; + } + } + } + + // error, return 2nd argument + nGlobalError = 0; + aCode.Jump( pJump[ 1 ], pJump[ nJumpCount ] ); +} + + void ScInterpreter::ScChoseJump() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChoseJump" ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 7155445..2f3b5ac 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -2712,7 +2712,7 @@ } else if ( ( aUnoName = ScGlobal::GetAddInCollection()->FindFunction(aFuncName, false) ).Len() ) { - // bLocalFirst=false in FindFunction, cFunc should be the stored + // bLocalFirst=false in FindFunction, cFunc should be the stored // internal name ScUnoAddInCall aCall( *ScGlobal::GetAddInCollection(), aUnoName, nParamCount ); @@ -3815,7 +3815,8 @@ // RPN code push without error PushWithoutError( (FormulaToken&) *pCur ); } - else if (pTokenMatrixMap && !(eOp == ocIf || eOp == ocChose) && + else if (pTokenMatrixMap && + !(eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChose) && ((aTokenMatrixMapIter = pTokenMatrixMap->find( pCur)) != pTokenMatrixMap->end()) && (*aTokenMatrixMapIter).second->GetType() != svJumpMatrix) @@ -3836,7 +3837,7 @@ nFuncFmtType = NUMBERFORMAT_NUMBER; nFuncFmtIndex = 0; - if ( eOp == ocIf || eOp == ocChose ) + if ( eOp == ocIf || eOp == ocChose || eOp == ocIfError || eOp == ocIfNA ) nStackBase = sp; // don't mess around with the jumps else { @@ -3863,6 +3864,8 @@ case ocDBArea : ScDBArea(); break; case ocColRowNameAuto : ScColRowNameAuto(); break; case ocIf : ScIfJump(); break; + case ocIfError : ScIfError( false ); break; + case ocIfNA : ScIfError( true ); break; case ocChose : ScChoseJump(); break; case ocAdd : ScAdd(); break; case ocSub : ScSub(); break; @@ -4258,7 +4261,9 @@ case ocIsString : \ case ocIsValue : \ case ocN : \ - case ocType : + case ocType : \ + case ocIfError : \ + case ocIfNA : switch ( eOp ) { diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx index ebdbb4a..68144dd 100644 --- a/sc/source/core/tool/parclass.cxx +++ b/sc/source/core/tool/parclass.cxx @@ -55,6 +55,8 @@ // created inside those functions and ConvertMatrixParameters() is not // called for them. { ocIf, {{ Array, Reference, Reference }, 0 }}, + { ocIfError, {{ Array, Reference, Reference }, false }}, + { ocIfNA, {{ Array, Reference }, false }}, { ocChose, {{ Array, Reference }, 1 }}, // Other specials. { ocOpen, {{ Bounds }, 0 }}, @@ -495,6 +497,8 @@ case ocIf: aToken.SetByte(3); break; + case ocIfError: + case ocIfNA: case ocChose: aToken.SetByte(2); break; diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 539cad0..c498eda 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -126,6 +126,8 @@ switch (eOp) { case ocIf: + case ocIfError: + case ocIfNA: eType = svJump; nJump[ 0 ] = 3; // If, Else, Behind break; diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 1b68b2e..6238fba 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -2651,6 +2651,70 @@ Text [ en-US ] = "The result of the function if the logical test returns FALSE." ; }; }; + // -=*# Resource for function IFERROR #*=- + Resource SC_OPCODE_IF_ERROR + { + String 1 // Description + { + Text [ en-US ] = "Returns value if not an error value, else alternative." ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_INFO; + U2S( HID_FUNC_IFERROR ); + 2; 0; 1; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "value" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value to be calculated." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "else value" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The alternative to be returned, should value be an error value." ; + }; + }; + // -=*# Resource for function IFNA #*=- + Resource SC_OPCODE_IF_NA + { + String 1 // Description + { + Text [ en-US ] = "Returns value if not an NA, else alternative." ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_INFO; + U2S( HID_FUNC_IFNA ); + 2; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "value" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value to be calculated." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "else value" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The alternative to be returned, should value be an NA." ; + }; + }; // -=*# Resource for function ODER #*=- Resource SC_OPCODE_OR { diff --git a/sc/util/hidother.src b/sc/util/hidother.src index d339229..718dce2 100644 --- a/sc/util/hidother.src +++ b/sc/util/hidother.src @@ -149,6 +149,8 @@ hidspecial HID_FUNC_NICHT { HelpID = HID_FUNC_NICHT; }; hidspecial HID_FUNC_WAHR { HelpID = HID_FUNC_WAHR; }; hidspecial HID_FUNC_WENN { HelpID = HID_FUNC_WENN; }; +hidspecial HID_FUNC_IFERROR { HelpID = HID_FUNC_IFERROR; }; +hidspecial HID_FUNC_IFNA { HelpID = HID_FUNC_IFNA; }; hidspecial HID_FUNC_ODER { HelpID = HID_FUNC_ODER; }; hidspecial HID_FUNC_UND { HelpID = HID_FUNC_UND; }; hidspecial HID_FUNC_XOR { HelpID = HID_FUNC_XOR; }; -- To view, visit https://gerrit.libreoffice.org/1522 To unsubscribe, visit https://gerrit.libreoffice.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6403b51ac8c710ad3b8d2625e1482971f50e6b1d Gerrit-PatchSet: 1 Gerrit-Project: core Gerrit-Branch: master Gerrit-Owner: Winfried Donkers <o...@dci-electronics.nl> _______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice