[PATCH] fdo#56124 add functions IFERROR and IFNA to calc as in ODFF1...
Winfried Donkers (via Code Review)
gerrit at gerrit.libreoffice.org
Mon Dec 31 06:43:21 PST 2012
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 <osc at dci-electronics.nl>
More information about the LibreOffice
mailing list