Kaydet (Commit) e8d370e8 authored tarafından Jean-Sebastien Bevilacqua's avatar Jean-Sebastien Bevilacqua Kaydeden (comit) Eike Rathke

tdf#107267: Fix grand total calculation

To fix the grand total calculation, we add another step.
This step loop through all row to find the min and max of each value.
These min and max are then used by the grand total.

Patch by Linagora

Change-Id: If3200840764d0ad9cb63231ac9f67b5d5ed197f1
Reviewed-on: https://gerrit.libreoffice.org/42042Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
üst 65ea925d
...@@ -137,7 +137,7 @@ ...@@ -137,7 +137,7 @@
#define STR_MSSG_SOLVE_2 NC_("STR_MSSG_SOLVE_2", "Goal Seek failed.\n\n") #define STR_MSSG_SOLVE_2 NC_("STR_MSSG_SOLVE_2", "Goal Seek failed.\n\n")
#define STR_MSSG_SOLVE_3 NC_("STR_MSSG_SOLVE_3", "Insert the closest value (") #define STR_MSSG_SOLVE_3 NC_("STR_MSSG_SOLVE_3", "Insert the closest value (")
#define STR_MSSG_SOLVE_4 NC_("STR_MSSG_SOLVE_4", ") into the variable cell anyway?") #define STR_MSSG_SOLVE_4 NC_("STR_MSSG_SOLVE_4", ") into the variable cell anyway?")
#define STR_TABLE_GESAMTERGEBNIS NC_("STR_TABLE_GESAMTERGEBNIS", "Grand Total") #define STR_TABLE_GRAND NC_("STR_TABLE_GRAND", "Grand")
#define STR_TABLE_ERGEBNIS NC_("STR_TABLE_ERGEBNIS", "Result") #define STR_TABLE_ERGEBNIS NC_("STR_TABLE_ERGEBNIS", "Result")
#define STR_UNDO_SPELLING NC_("STR_UNDO_SPELLING", "Spellcheck") #define STR_UNDO_SPELLING NC_("STR_UNDO_SPELLING", "Spellcheck")
#define STR_TABLE_UND NC_("STR_TABLE_UND", "AND") #define STR_TABLE_UND NC_("STR_TABLE_UND", "AND")
......
...@@ -1964,6 +1964,30 @@ typedef struct lcl_ScTable_DoSubTotals_RowEntry ...@@ -1964,6 +1964,30 @@ typedef struct lcl_ScTable_DoSubTotals_RowEntry
SCROW nFuncEnd; SCROW nFuncEnd;
} RowEntry; } RowEntry;
static const char* lcl_GetSubTotalStrId(int id)
{
switch ( id )
{
case SUBTOTAL_FUNC_AVE: return STR_FUN_TEXT_AVG;
case SUBTOTAL_FUNC_CNT:
case SUBTOTAL_FUNC_CNT2: return STR_FUN_TEXT_COUNT;
case SUBTOTAL_FUNC_MAX: return STR_FUN_TEXT_MAX;
case SUBTOTAL_FUNC_MIN: return STR_FUN_TEXT_MIN;
case SUBTOTAL_FUNC_PROD: return STR_FUN_TEXT_PRODUCT;
case SUBTOTAL_FUNC_STD:
case SUBTOTAL_FUNC_STDP: return STR_FUN_TEXT_STDDEV;
case SUBTOTAL_FUNC_SUM: return STR_FUN_TEXT_SUM;
case SUBTOTAL_FUNC_VAR:
case SUBTOTAL_FUNC_VARP: return STR_FUN_TEXT_VAR;
default:
{
return STR_EMPTYDATA;
// added to avoid warnings
}
}
}
// new intermediate results // new intermediate results
// rParam.nRow2 is changed! // rParam.nRow2 is changed!
...@@ -2019,10 +2043,9 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) ...@@ -2019,10 +2043,9 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
RowEntry aRowEntry; RowEntry aRowEntry;
::std::vector< RowEntry > aRowVector; ::std::vector< RowEntry > aRowVector;
for (sal_uInt16 nLevel=0; nLevel<=nLevelCount && bSpaceLeft; nLevel++) // including grand total for (sal_uInt16 nLevel=0; nLevel<nLevelCount && bSpaceLeft; nLevel++)
{ {
bool bTotal = ( nLevel == nLevelCount ); aRowEntry.nGroupNo = nLevelCount - nLevel - 1;
aRowEntry.nGroupNo = bTotal ? 0 : (nLevelCount-nLevel-1);
// how many results per level // how many results per level
SCCOL nResCount = rParam.nSubTotals[aRowEntry.nGroupNo]; SCCOL nResCount = rParam.nSubTotals[aRowEntry.nGroupNo];
...@@ -2050,31 +2073,28 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) ...@@ -2050,31 +2073,28 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
else else
{ {
bChanged = false; bChanged = false;
if (!bTotal) OUString aString;
for (i=0; i<=aRowEntry.nGroupNo && !bChanged; i++)
{ {
OUString aString; GetString( nGroupCol[i], nRow, aString );
for (i=0; i<=aRowEntry.nGroupNo && !bChanged; i++) if (bIgnoreCase)
{ aString = ScGlobal::pCharClass->uppercase(aString);
GetString( nGroupCol[i], nRow, aString ); // when sorting, blanks are separate group
if (bIgnoreCase) // otherwise blank cells are allowed below
aString = ScGlobal::pCharClass->uppercase(aString); bChanged = ( ( !aString.isEmpty() || rParam.bDoSort ) &&
// when sorting, blanks are separate group aString != aCompString[i] );
// otherwise blank cells are allowed below }
bChanged = ( ( !aString.isEmpty() || rParam.bDoSort ) && if ( bChanged && bTestPrevSub )
aString != aCompString[i] ); {
} // No group change on rows that will contain subtotal formulas
if ( bChanged && bTestPrevSub ) for ( ::std::vector< RowEntry >::const_iterator
iEntry( aRowVector.begin());
iEntry != aRowVector.end(); ++iEntry)
{ {
// No group change on rows that will contain subtotal formulas if ( iEntry->nDestRow == nRow )
for ( ::std::vector< RowEntry >::const_iterator
iEntry( aRowVector.begin());
iEntry != aRowVector.end(); ++iEntry)
{ {
if ( iEntry->nDestRow == nRow ) bChanged = false;
{ break;
bChanged = false;
break;
}
} }
} }
} }
...@@ -2110,36 +2130,14 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) ...@@ -2110,36 +2130,14 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
// collect formula positions // collect formula positions
aRowVector.push_back( aRowEntry ); aRowVector.push_back( aRowEntry );
if (bTotal) // "Grand total" aOutString = aSubString;
aOutString = ScGlobal::GetRscString( STR_TABLE_GESAMTERGEBNIS ); if (aOutString.isEmpty())
else aOutString = ScGlobal::GetRscString( STR_EMPTYDATA );
{ // "Result" aOutString += " ";
aOutString = aSubString; const char* pStrId = STR_TABLE_ERGEBNIS;
if (aOutString.isEmpty()) if ( nResCount == 1 )
aOutString = ScGlobal::GetRscString( STR_EMPTYDATA ); pStrId = lcl_GetSubTotalStrId(eResFunc[0]);
aOutString += " "; aOutString += ScGlobal::GetRscString(pStrId);
const char* pStrId = STR_TABLE_ERGEBNIS;
if ( nResCount == 1 )
switch ( eResFunc[0] )
{
case SUBTOTAL_FUNC_AVE: pStrId = STR_FUN_TEXT_AVG; break;
case SUBTOTAL_FUNC_CNT:
case SUBTOTAL_FUNC_CNT2: pStrId = STR_FUN_TEXT_COUNT; break;
case SUBTOTAL_FUNC_MAX: pStrId = STR_FUN_TEXT_MAX; break;
case SUBTOTAL_FUNC_MIN: pStrId = STR_FUN_TEXT_MIN; break;
case SUBTOTAL_FUNC_PROD: pStrId = STR_FUN_TEXT_PRODUCT; break;
case SUBTOTAL_FUNC_STD:
case SUBTOTAL_FUNC_STDP: pStrId = STR_FUN_TEXT_STDDEV; break;
case SUBTOTAL_FUNC_SUM: pStrId = STR_FUN_TEXT_SUM; break;
case SUBTOTAL_FUNC_VAR:
case SUBTOTAL_FUNC_VARP: pStrId = STR_FUN_TEXT_VAR; break;
default:
{
// added to avoid warnings
}
}
aOutString += ScGlobal::GetRscString(pStrId);
}
SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString ); SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString );
ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, pStyle ); ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, pStyle );
...@@ -2161,6 +2159,51 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) ...@@ -2161,6 +2159,51 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
} }
} }
// generate global total
SCROW nGlobalStartRow = aRowVector[0].nSubStartRow;
SCROW nGlobalStartFunc = aRowVector[0].nFuncStart;
SCROW nGlobalEndRow = 0;
SCROW nGlobalEndFunc = 0;
for ( ::std::vector< RowEntry >::const_iterator iEntry( aRowVector.begin());
iEntry != aRowVector.end(); ++iEntry)
{
nGlobalEndRow = (nGlobalEndRow < iEntry->nDestRow) ? iEntry->nDestRow : nGlobalEndRow;
nGlobalEndFunc = (nGlobalEndFunc < iEntry->nFuncEnd) ? iEntry->nFuncEnd : nGlobalEndRow;
}
for (sal_uInt16 nLevel=0; nLevel<nLevelCount; nLevel++)
{
// increment end row
nGlobalEndRow++;
// add row entry for formula
aRowEntry.nGroupNo = nLevelCount-nLevel-1;
aRowEntry.nSubStartRow = nGlobalStartRow;
aRowEntry.nFuncStart = nGlobalStartFunc;
aRowEntry.nDestRow = nGlobalEndRow;
aRowEntry.nFuncEnd = nGlobalEndFunc;
// increment row
nGlobalEndFunc++;
bSpaceLeft = pDocument->InsertRow( 0, nTab, MAXCOL, nTab, aRowEntry.nDestRow, 1 );
if (bSpaceLeft)
{
aRowVector.push_back( aRowEntry );
nEndRow++;
DBShowRow(aRowEntry.nDestRow, true);
// insert label
ScSubTotalFunc* eResFunc = rParam.pFunctions[aRowEntry.nGroupNo];
OUString label = ScGlobal::GetRscString( STR_TABLE_GRAND );
label += " ";
label += ScGlobal::GetRscString(lcl_GetSubTotalStrId(eResFunc[0]));
SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, label );
ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, pStyle );
}
}
// now insert the formulas // now insert the formulas
ScComplexRefData aRef; ScComplexRefData aRef;
aRef.InitFlags(); aRef.InitFlags();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment