sc/inc/global.hxx                                |    2 
 sc/inc/subtotalparam.hxx                         |   77 ++++++---
 sc/source/core/data/sortparam.cxx                |   10 -
 sc/source/core/data/subtotalparam.cxx            |  181 ++++-------------------
 sc/source/core/data/table3.cxx                   |   67 +++-----
 sc/source/core/tool/dbdata.cxx                   |   14 -
 sc/source/filter/xml/XMLExportDatabaseRanges.cxx |   14 -
 sc/source/filter/xml/xmldrani.cxx                |   26 ---
 sc/source/ui/dbgui/tpsubt.cxx                    |   19 +-
 sc/source/ui/docshell/dbdocfun.cxx               |    4 
 sc/source/ui/unoobj/cellsuno.cxx                 |   24 +--
 sc/source/ui/unoobj/datauno.cxx                  |  102 +++---------
 sc/source/ui/view/dbfunc.cxx                     |    2 
 sc/source/ui/view/dbfunc3.cxx                    |    2 
 14 files changed, 195 insertions(+), 349 deletions(-)

New commits:
commit 669c839a61e2742a9128aabba30e2b55be517d21
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Nov 27 21:37:06 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Nov 28 05:36:59 2024 +0100

    Simplify ScSubTotalParam
    
    Change-Id: I4c1840e377711ad065c3042bddacb2028481b88d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177433
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index fd51ff15808b..e37b2dbaef58 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -860,7 +860,7 @@ enum ScQueryConnect
         SC_OR
     };
 
-enum ScSubTotalFunc
+enum ScSubTotalFunc : sal_Int16
     {
         SUBTOTAL_FUNC_NONE  = 0,
         SUBTOTAL_FUNC_AVE   = 1,
diff --git a/sc/inc/subtotalparam.hxx b/sc/inc/subtotalparam.hxx
index 3b379edb167d..df9f5ef390e3 100644
--- a/sc/inc/subtotalparam.hxx
+++ b/sc/inc/subtotalparam.hxx
@@ -11,35 +11,60 @@
 
 #include "global.hxx"
 #include <memory>
+#include <span>
+
+namespace com::sun::star::sheet { struct SubTotalColumn; }
+namespace com::sun::star::uno { template <class E> class Sequence; }
 
 struct SC_DLLPUBLIC ScSubTotalParam
 {
-    SCCOL           nCol1;                      ///< selected area
-    SCROW           nRow1;
-    SCCOL           nCol2;
-    SCROW           nRow2;
-    sal_uInt16      nUserIndex;                 ///< index into list
-    bool            bRemoveOnly:1;
-    bool            bReplace:1;                 ///< replace existing results
-    bool            bPagebreak:1;               ///< page break at change of 
group
-    bool            bCaseSens:1;
-    bool            bDoSort:1;                  ///< presort
-    bool            bSummaryBelow:1;            ///< Summary below or above 
(default: below)
-    bool            bAscending:1;               ///< sort ascending
-    bool            bUserDef:1;                 ///< sort user defined
-    bool            bIncludePattern:1;          ///< sort formats
-    bool            bGroupActive[MAXSUBTOTAL];  ///< active groups
-    SCCOL           nField[MAXSUBTOTAL];        ///< associated field
-    SCCOL           nSubTotals[MAXSUBTOTAL];    ///< number of SubTotals
-    std::unique_ptr<SCCOL[]> pSubTotals[MAXSUBTOTAL];    ///< array of columns 
to be calculated
-    std::unique_ptr<ScSubTotalFunc[]> pFunctions[MAXSUBTOTAL];    ///< array 
of associated functions
-
-    ScSubTotalParam();
-    ScSubTotalParam( const ScSubTotalParam& r );
-
-    ScSubTotalParam& operator= ( const ScSubTotalParam& r );
-    bool operator== ( const ScSubTotalParam& r ) const;
-    void Clear();
+    SCCOL           nCol1 = 0;                  ///< selected area
+    SCROW           nRow1 = 0;
+    SCCOL           nCol2 = 0;
+    SCROW           nRow2 = 0;
+    sal_uInt16      nUserIndex = 0;             ///< index into list
+    bool            bRemoveOnly:1     = false;
+    bool            bReplace:1        = true;   ///< replace existing results
+    bool            bPagebreak:1      = false;  ///< page break at change of 
group
+    bool            bCaseSens:1       = false;
+    bool            bDoSort:1         = true;   ///< presort
+    bool            bSummaryBelow:1   = true;   ///< Summary below or above 
(default: below)
+    bool            bAscending:1      = true;   ///< sort ascending
+    bool            bUserDef:1        = false;  ///< sort user defined
+    bool            bIncludePattern:1 = false;  ///< sort formats
+
+    struct SubtotalGroup
+    {
+        bool  bActive    = false; ///< active groups
+        SCCOL nField     = 0;     ///< associated field
+        SCCOL nSubTotals = 0;     ///< number of SubTotals
+
+        using Pair = std::pair<SCCOL, ScSubTotalFunc>;
+        // array of columns to be calculated, and associated functions
+        std::unique_ptr<Pair[]> pSubTotals;
+
+        SubtotalGroup() = default;
+        SubtotalGroup(const SubtotalGroup& r);
+
+        SubtotalGroup& operator=(const SubtotalGroup& r);
+        bool operator==(const SubtotalGroup& r) const;
+
+        void AllocSubTotals(SCCOL n);
+        void SetSubtotals(const 
css::uno::Sequence<css::sheet::SubTotalColumn>& seq);
+
+        std::span<Pair> subtotals() { return std::span(pSubTotals.get(), 
nSubTotals); }
+        std::span<const Pair> subtotals() const { return 
std::span(pSubTotals.get(), nSubTotals); }
+        SCCOL& col(SCCOL n) { return subtotals()[n].first; }
+        SCCOL col(SCCOL n) const { return subtotals()[n].first; }
+        ScSubTotalFunc func(SCCOL n) const { return subtotals()[n].second; }
+    };
+    SubtotalGroup aGroups[MAXSUBTOTAL];
+
+    ScSubTotalParam() = default;
+    ScSubTotalParam(const ScSubTotalParam&) = default;
+
+    ScSubTotalParam& operator=(const ScSubTotalParam&) = default;
+    inline bool operator==(const ScSubTotalParam&) const = default;
     void SetSubTotals( sal_uInt16 nGroup,
                        const SCCOL* ptrSubTotals,
                        const ScSubTotalFunc* ptrFunctions,
diff --git a/sc/source/core/data/sortparam.cxx 
b/sc/source/core/data/sortparam.cxx
index 37e44794a4df..868cf38a8df8 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -173,23 +173,21 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, 
const ScSortParam& rOld )
     aDataAreaExtras.mbCellFormats = rSub.bIncludePattern;
     aDataAreaExtras.resetArea();
 
-    sal_uInt16 i;
-
     //  first the groups from the partial results
     if (rSub.bDoSort)
-        for (i=0; i<MAXSUBTOTAL; i++)
-            if (rSub.bGroupActive[i])
+        for (const auto& group : rSub.aGroups)
+            if (group.bActive)
             {
                 ScSortKeyState key;
                 key.bDoSort = true;
-                key.nField = rSub.nField[i];
+                key.nField = group.nField;
                 key.bAscending = rSub.bAscending;
                 key.aColorSortMode = ScColorSortMode::None;
                 maKeyState.push_back(key);
             }
 
     //  then the old settings
-    for (i=0; i < rOld.GetSortKeyCount(); i++)
+    for (sal_uInt16 i = 0; i < rOld.GetSortKeyCount(); i++)
         if (rOld.maKeyState[i].bDoSort)
         {
             SCCOLROW nThisField = rOld.maKeyState[i].nField;
diff --git a/sc/source/core/data/subtotalparam.cxx 
b/sc/source/core/data/subtotalparam.cxx
index ae28606d3643..a056871be521 100644
--- a/sc/source/core/data/subtotalparam.cxx
+++ b/sc/source/core/data/subtotalparam.cxx
@@ -7,162 +7,65 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <sal/config.h>
+
+#include <dputil.hxx>
 #include <subtotalparam.hxx>
 
 #include <osl/diagnose.h>
 
-ScSubTotalParam::ScSubTotalParam()
-{
-    for ( sal_uInt16 i=0; i<MAXSUBTOTAL; i++ )
-    {
-        nSubTotals[i] = 0;
-        pSubTotals[i] = nullptr;
-        pFunctions[i] = nullptr;
-    }
+#include <com/sun/star/sheet/SubTotalColumn.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
 
-    Clear();
-}
-
-ScSubTotalParam::ScSubTotalParam( const ScSubTotalParam& r ) :
-        
nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nUserIndex(r.nUserIndex),
-        
bRemoveOnly(r.bRemoveOnly),bReplace(r.bReplace),bPagebreak(r.bPagebreak),bCaseSens(r.bCaseSens),
-        bDoSort(r.bDoSort), bSummaryBelow(r.bSummaryBelow), 
bAscending(r.bAscending), bUserDef(r.bUserDef),
-        bIncludePattern(r.bIncludePattern)
+ScSubTotalParam::SubtotalGroup::SubtotalGroup(const SubtotalGroup& r)
+    : bActive(r.bActive)
+    , nField(r.nField)
 {
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+    if (r.nSubTotals > 0)
     {
-        bGroupActive[i] = r.bGroupActive[i];
-        nField[i]       = r.nField[i];
-
-        if ( (r.nSubTotals[i] > 0) && r.pSubTotals[i] && r.pFunctions[i] )
-        {
-            nSubTotals[i] = r.nSubTotals[i];
-            pSubTotals[i].reset(new SCCOL   [r.nSubTotals[i]]);
-            pFunctions[i].reset(new ScSubTotalFunc  [r.nSubTotals[i]]);
-
-            for (SCCOL j=0; j<r.nSubTotals[i]; j++)
-            {
-                pSubTotals[i][j] = r.pSubTotals[i][j];
-                pFunctions[i][j] = r.pFunctions[i][j];
-            }
-        }
-        else
-        {
-            nSubTotals[i] = 0;
-        }
+        assert(r.pSubTotals);
+        AllocSubTotals(r.nSubTotals);
+        std::copy_n(r.pSubTotals.get(), r.nSubTotals, pSubTotals.get());
     }
 }
 
-void ScSubTotalParam::Clear()
+ScSubTotalParam::SubtotalGroup& 
ScSubTotalParam::SubtotalGroup::operator=(const SubtotalGroup& r)
 {
-    nCol1=nCol2= 0;
-    nRow1=nRow2 = 0;
-    nUserIndex = 0;
-    bPagebreak=bCaseSens=bUserDef=bIncludePattern=bRemoveOnly = false;
-    bAscending=bReplace=bDoSort=bSummaryBelow = true;
+    bActive = r.bActive;
+    nField = r.nField;
 
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+    AllocSubTotals(r.nSubTotals);
+    if (r.nSubTotals > 0)
     {
-        bGroupActive[i] = false;
-        nField[i]       = 0;
-
-        if ( (nSubTotals[i] > 0) && pSubTotals[i] && pFunctions[i] )
-        {
-            for ( SCCOL j=0; j<nSubTotals[i]; j++ ) {
-                pSubTotals[i][j] = 0;
-                pFunctions[i][j] = SUBTOTAL_FUNC_NONE;
-            }
-        }
+        assert(r.pSubTotals);
+        std::copy_n(r.pSubTotals.get(), r.nSubTotals, pSubTotals.get());
     }
+
+    return *this;
 }
 
-ScSubTotalParam& ScSubTotalParam::operator=( const ScSubTotalParam& r )
+bool ScSubTotalParam::SubtotalGroup::operator==(const SubtotalGroup& r) const
 {
-    if(this == &r)
-        return *this;
-
-    nCol1           = r.nCol1;
-    nRow1           = r.nRow1;
-    nCol2           = r.nCol2;
-    nRow2           = r.nRow2;
-    bRemoveOnly     = r.bRemoveOnly;
-    bReplace        = r.bReplace;
-    bPagebreak      = r.bPagebreak;
-    bCaseSens       = r.bCaseSens;
-    bDoSort         = r.bDoSort;
-    bSummaryBelow   = r.bSummaryBelow;
-    bAscending      = r.bAscending;
-    bUserDef        = r.bUserDef;
-    nUserIndex      = r.nUserIndex;
-    bIncludePattern = r.bIncludePattern;
-
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
-    {
-        bGroupActive[i] = r.bGroupActive[i];
-        nField[i]       = r.nField[i];
-        nSubTotals[i]   = r.nSubTotals[i];
-
-        pSubTotals[i].reset();
-        pFunctions[i].reset();
-
-        if ( r.nSubTotals[i] > 0 )
-        {
-            pSubTotals[i].reset(new SCCOL   [r.nSubTotals[i]]);
-            pFunctions[i].reset(new ScSubTotalFunc  [r.nSubTotals[i]]);
-
-            for (SCCOL j=0; j<r.nSubTotals[i]; j++)
-            {
-                pSubTotals[i][j] = r.pSubTotals[i][j];
-                pFunctions[i][j] = r.pFunctions[i][j];
-            }
-        }
-        else
-        {
-            nSubTotals[i] = 0;
-        }
-    }
-
-    return *this;
+    return bActive == r.bActive && nField == r.nField && nSubTotals == 
r.nSubTotals
+           && (!nSubTotals
+               || std::equal(pSubTotals.get(), pSubTotals.get() + nSubTotals, 
r.pSubTotals.get()));
 }
 
-bool ScSubTotalParam::operator==( const ScSubTotalParam& rOther ) const
+void ScSubTotalParam::SubtotalGroup::AllocSubTotals(SCCOL n)
 {
-    bool bEqual =   (nCol1          == rOther.nCol1)
-                 && (nRow1          == rOther.nRow1)
-                 && (nCol2          == rOther.nCol2)
-                 && (nRow2          == rOther.nRow2)
-                 && (nUserIndex     == rOther.nUserIndex)
-                 && (bRemoveOnly    == rOther.bRemoveOnly)
-                 && (bReplace       == rOther.bReplace)
-                 && (bPagebreak     == rOther.bPagebreak)
-                 && (bDoSort        == rOther.bDoSort)
-                 && (bSummaryBelow  == rOther.bSummaryBelow)
-                 && (bCaseSens      == rOther.bCaseSens)
-                 && (bAscending     == rOther.bAscending)
-                 && (bUserDef       == rOther.bUserDef)
-                 && (bIncludePattern== rOther.bIncludePattern);
-
-    if ( bEqual )
+    if (nSubTotals != n)
     {
-        bEqual = true;
-        for ( sal_uInt16 i=0; i<MAXSUBTOTAL && bEqual; i++ )
-        {
-            bEqual =   (bGroupActive[i] == rOther.bGroupActive[i])
-                    && (nField[i]       == rOther.nField[i])
-                    && (nSubTotals[i]   == rOther.nSubTotals[i]);
-
-            if ( bEqual && (nSubTotals[i] > 0) )
-            {
-                for (SCCOL j=0; (j<nSubTotals[i]) && bEqual; j++)
-                {
-                    bEqual = pSubTotals[i][j] == rOther.pSubTotals[i][j]
-                            && pFunctions[i][j] == rOther.pFunctions[i][j];
-                }
-            }
-        }
+        nSubTotals = std::max(n, SCCOL(0));
+        pSubTotals.reset(nSubTotals ? new std::pair<SCCOL, 
ScSubTotalFunc>[nSubTotals] : nullptr);
     }
+}
 
-    return bEqual;
+void ScSubTotalParam::SubtotalGroup::SetSubtotals(const 
css::uno::Sequence<css::sheet::SubTotalColumn>& seq)
+{
+    AllocSubTotals(seq.getLength());
+    for (SCCOL i = 0; i < nSubTotals; ++i)
+        pSubTotals[i] = { seq[i].Column,
+                          
ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(seq[i].Function)) };
 }
 
 void ScSubTotalParam::SetSubTotals( sal_uInt16 nGroup,
@@ -177,7 +80,7 @@ void ScSubTotalParam::SetSubTotals( sal_uInt16 nGroup,
     OSL_ENSURE( ptrFunctions,
                 "ScSubTotalParam::SetSubTotals(): ptrFunctions == NULL!" );
     OSL_ENSURE( (nCount > 0),
-                "ScSubTotalParam::SetSubTotals(): nCount <= 0!" );
+                "ScSubTotalParam::SetSubTotals(): nCount == 0!" );
 
     if ( !(ptrSubTotals && ptrFunctions && (nCount > 0) && (nGroup <= 
MAXSUBTOTAL)) )
         return;
@@ -186,15 +89,9 @@ void ScSubTotalParam::SetSubTotals( sal_uInt16 nGroup,
     if (nGroup != 0)
         nGroup--;
 
-    pSubTotals[nGroup].reset(new SCCOL[nCount]);
-    pFunctions[nGroup].reset(new ScSubTotalFunc[nCount]);
-    nSubTotals[nGroup] = static_cast<SCCOL>(nCount);
-
+    aGroups[nGroup].AllocSubTotals(nCount);
     for ( sal_uInt16 i=0; i<nCount; i++ )
-    {
-        pSubTotals[nGroup][i] = ptrSubTotals[i];
-        pFunctions[nGroup][i] = ptrFunctions[i];
-    }
+        aGroups[nGroup].pSubTotals[i] = { ptrSubTotals[i], ptrFunctions[i] };
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index fed72506c2a3..f5b66a250ea7 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1947,7 +1947,7 @@ struct RowEntry
 
 }
 
-static TranslateId lcl_GetSubTotalStrId(int id)
+static TranslateId lcl_GetSubTotalStrId(ScSubTotalFunc id)
 {
     switch ( id )
     {
@@ -1971,7 +1971,7 @@ static TranslateId lcl_GetSubTotalStrId(int id)
 }
 
 // Gets the string used for "Grand" results
-static TranslateId lcl_GetGrandSubTotalStrId(int id)
+static TranslateId lcl_GetGrandSubTotalStrId(ScSubTotalFunc id)
 {
     switch ( id )
     {
@@ -2011,20 +2011,16 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
     nEndRow -= nEmpty;
 
     sal_uInt16 nLevelCount = 0;             // Number of levels
-    bool bDoThis = true;
-    for (sal_uInt16 i = 0; i < MAXSUBTOTAL && bDoThis; ++i)
+    for (const auto& group : rParam.aGroups)
     {
-        if (rParam.bGroupActive[i])
-            nLevelCount = o3tl::sanitizing_inc(i);
-        else
-            bDoThis = false;
+        if (!group.bActive)
+            break;
+        ++nLevelCount;
     }
 
     if (nLevelCount==0)                 // do nothing
         return true;
 
-    SCCOL*          nGroupCol = rParam.nField;  // columns which will be used 
when grouping
-
     //  With (blank) as a separate category, subtotal rows from
     //  the other columns must always be tested
     //  (previously only when a column occurred more than once)
@@ -2053,17 +2049,16 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
     {
         aRowEntry.nGroupNo = nLevelCount - nLevel - 1;
 
+        const auto& group = rParam.aGroups[aRowEntry.nGroupNo];
         // how many results per level
-        SCCOL nResCount         = rParam.nSubTotals[aRowEntry.nGroupNo];
-        // result functions
-        ScSubTotalFunc* pResFunc = rParam.pFunctions[aRowEntry.nGroupNo].get();
+        SCCOL nResCount = group.nSubTotals;
 
         if (nResCount > 0)                                      // otherwise 
only sort
         {
             SCROW nAboveRows = rParam.bSummaryBelow ? nStartRow : nStartRow + 
nLevel;
             for (sal_uInt16 i = 0; i <= aRowEntry.nGroupNo; ++i)
             {
-                aSubString = GetString( nGroupCol[i], nAboveRows );
+                aSubString = GetString(rParam.aGroups[i].nField, nAboveRows);
                 if ( bIgnoreCase )
                     aCompString[i] = ScGlobal::getCharClass().uppercase( 
aSubString );
                 else
@@ -2083,7 +2078,7 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
                     OUString aString;
                     for (sal_uInt16 i = 0; i <= aRowEntry.nGroupNo && 
!bChanged; ++i)
                     {
-                        aString = GetString( nGroupCol[i], nRow );
+                        aString = GetString(rParam.aGroups[i].nField, nRow);
                         if (bIgnoreCase)
                             aString = 
ScGlobal::getCharClass().uppercase(aString);
                         //  when sorting, blanks are separate group
@@ -2145,17 +2140,17 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
                         aOutString += " ";
                         TranslateId pStrId = STR_TABLE_ERGEBNIS;
                         if ( nResCount == 1 )
-                            pStrId = lcl_GetSubTotalStrId(pResFunc[0]);
+                            pStrId = lcl_GetSubTotalStrId(group.func(0));
                         aOutString += ScResId(pStrId);
-                        SetString( nGroupCol[aRowEntry.nGroupNo], 
aRowEntry.nDestRow, nTab, aOutString );
-                        ApplyStyle( nGroupCol[aRowEntry.nGroupNo], 
aRowEntry.nDestRow, pStyle );
+                        SetString(group.nField, aRowEntry.nDestRow, nTab, 
aOutString);
+                        ApplyStyle(group.nField, aRowEntry.nDestRow, pStyle);
 
                         ++nRow;
                         ++nEndRow;
                         aRowEntry.nSubStartRow = nRow;
                         for (sal_uInt16 i = 0; i <= aRowEntry.nGroupNo; ++i)
                         {
-                            aSubString = GetString( nGroupCol[i], nRow );
+                            aSubString = GetString(rParam.aGroups[i].nField, 
nRow);
                             if ( bIgnoreCase )
                                 aCompString[i] = 
ScGlobal::getCharClass().uppercase( aSubString );
                             else
@@ -2194,21 +2189,21 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
         for (sal_uInt16 nLevel = 0; nLevel<nLevelCount; nLevel++)
         {
             const sal_uInt16 nGroupNo = nLevelCount - nLevel - 1;
-            const ScSubTotalFunc* pResFunc = rParam.pFunctions[nGroupNo].get();
-            if (!pResFunc)
+            const auto& group = rParam.aGroups[nGroupNo];
+            if (!group.nSubTotals)
             {
                 // No subtotal function given for this group => no formula or
                 // label and do not insert a row.
                 continue;
             }
 
+            aRowEntry.nGroupNo = nGroupNo;
             if (rParam.bSummaryBelow)
             {
                 // increment end row
                 nGlobalEndRow++;
 
                 // add row entry for formula
-                aRowEntry.nGroupNo = nGroupNo;
                 aRowEntry.nSubStartRow = nGlobalStartRow;
                 aRowEntry.nFuncStart = nGlobalStartFunc;
                 aRowEntry.nDestRow = nGlobalEndRow;
@@ -2220,7 +2215,6 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
             else
             {
                 // if we have Global summary we need to shift summary rows down
-                aRowEntry.nGroupNo = nGroupNo;
                 aRowEntry.nSubStartRow = nGlobalStartRow - nGroupNo - 1;
                 aRowEntry.nFuncStart = nGlobalStartFunc - nGroupNo - 1;
                 aRowEntry.nDestRow = nGlobalStartRow - nGroupNo - 1;
@@ -2236,9 +2230,9 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
                 DBShowRow(aRowEntry.nDestRow, true);
 
                 // insert label
-                OUString label = 
ScResId(lcl_GetGrandSubTotalStrId(pResFunc[0]));
-                SetString(nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, 
nTab, label);
-                ApplyStyle(nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, 
pStyle);
+                OUString label = 
ScResId(lcl_GetGrandSubTotalStrId(group.func(0)));
+                SetString(group.nField, aRowEntry.nDestRow, nTab, label);
+                ApplyStyle(group.nField, aRowEntry.nDestRow, pStyle);
             }
         }
     }
@@ -2250,35 +2244,34 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
     aRef.Ref2.SetAbsTab(nTab);
     for (const auto& rRowEntry : aRowVector)
     {
-        SCCOL nResCount         = rParam.nSubTotals[rRowEntry.nGroupNo];
-        SCCOL* nResCols         = rParam.pSubTotals[rRowEntry.nGroupNo].get();
-        ScSubTotalFunc* pResFunc = rParam.pFunctions[rRowEntry.nGroupNo].get();
+        const auto& group = rParam.aGroups[rRowEntry.nGroupNo];
+        SCCOL nResCount = group.nSubTotals;
         for ( SCCOL nResult=0; nResult < nResCount; ++nResult )
         {
-            aRef.Ref1.SetAbsCol(nResCols[nResult]);
+            aRef.Ref1.SetAbsCol(group.col(nResult));
             aRef.Ref1.SetAbsRow(rRowEntry.nFuncStart);
-            aRef.Ref2.SetAbsCol(nResCols[nResult]);
+            aRef.Ref2.SetAbsCol(group.col(nResult));
             aRef.Ref2.SetAbsRow(rRowEntry.nFuncEnd);
 
             ScTokenArray aArr(rDocument);
             aArr.AddOpCode( ocSubTotal );
             aArr.AddOpCode( ocOpen );
-            aArr.AddDouble( static_cast<double>(pResFunc[nResult]) );
+            aArr.AddDouble( static_cast<double>(group.func(nResult)) );
             aArr.AddOpCode( ocSep );
             aArr.AddDoubleReference( aRef );
             aArr.AddOpCode( ocClose );
             aArr.AddOpCode( ocStop );
             ScFormulaCell* pCell = new ScFormulaCell(
-                rDocument, ScAddress(nResCols[nResult], rRowEntry.nDestRow, 
nTab), aArr);
+                rDocument, ScAddress(group.col(nResult), rRowEntry.nDestRow, 
nTab), aArr);
             if ( rParam.bIncludePattern )
                 pCell->SetNeedNumberFormat(true);
 
-            SetFormulaCell(nResCols[nResult], rRowEntry.nDestRow, pCell);
-            if ( nResCols[nResult] != nGroupCol[rRowEntry.nGroupNo] )
+            SetFormulaCell(group.col(nResult), rRowEntry.nDestRow, pCell);
+            if (group.col(nResult) != group.nField)
             {
-                ApplyStyle( nResCols[nResult], rRowEntry.nDestRow, pStyle );
+                ApplyStyle(group.col(nResult), rRowEntry.nDestRow, pStyle);
 
-                lcl_RemoveNumberFormat( this, nResCols[nResult], 
rRowEntry.nDestRow );
+                lcl_RemoveNumberFormat(this, group.col(nResult), 
rRowEntry.nDestRow);
             }
         }
 
diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx
index 563ca6058465..b719cb056221 100644
--- a/sc/source/core/tool/dbdata.cxx
+++ b/sc/source/core/tool/dbdata.cxx
@@ -276,7 +276,7 @@ OUString ScDBData::GetOperations() const
         aBuf.append(ScResId(STR_OPERATION_SORT));
     }
 
-    if (mpSubTotal->bGroupActive[0] && !mpSubTotal->bRemoveOnly)
+    if (mpSubTotal->aGroups[0].bActive && !mpSubTotal->bRemoveOnly)
     {
         if (!aBuf.isEmpty())
             aBuf.append(", ");
@@ -377,13 +377,13 @@ void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW 
nRow1, SCCOL nCol2, SCROW n
             rEntry.bDoQuery = false;
         }
     }
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+    for (auto& group : mpSubTotal->aGroups)
     {
-        mpSubTotal->nField[i] = sal::static_int_cast<SCCOL>( 
mpSubTotal->nField[i] + nDifX );
-        if (mpSubTotal->nField[i] > nCol2)
+        group.nField += nDifX;
+        if (group.nField > nCol2)
         {
-            mpSubTotal->nField[i] = 0;
-            mpSubTotal->bGroupActive[i] = false;
+            group.nField = 0;
+            group.bActive = false;
         }
     }
 
@@ -533,7 +533,7 @@ bool ScDBData::HasSortParam() const
 
 bool ScDBData::HasSubTotalParam() const
 {
-    return mpSubTotal && mpSubTotal->bGroupActive[0];
+    return mpSubTotal && mpSubTotal->aGroups[0].bActive;
 }
 
 void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos)
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx 
b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index d1817bc4ddc5..5deb8978da66 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -642,7 +642,7 @@ private:
         size_t nCount = 0;
         for (; nCount < MAXSUBTOTAL; ++nCount)
         {
-            if (!aParam.bGroupActive[nCount])
+            if (!aParam.aGroups[nCount].bActive)
                 break;
         }
 
@@ -676,20 +676,20 @@ private:
             SvXMLElementExport aElemSGs(mrExport, XML_NAMESPACE_TABLE, 
XML_SORT_GROUPS, true, true);
         }
 
-        for (size_t i = 0; i < MAXSUBTOTAL; ++i)
+        for (auto& group : aParam.aGroups)
         {
-            if (!aParam.bGroupActive[i])
+            if (!group.bActive)
                 // We're done!
                 break;
 
-            sal_Int32 nFieldCol = static_cast<sal_Int32>(aParam.nField[i]);
+            sal_Int32 nFieldCol = static_cast<sal_Int32>(group.nField);
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, 
XML_GROUP_BY_FIELD_NUMBER, OUString::number(nFieldCol));
             SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, 
XML_SUBTOTAL_RULE, true, true);
 
-            for (SCCOL j = 0, n = aParam.nSubTotals[i]; j < n; ++j)
+            for (SCCOL j = 0, n = group.nSubTotals; j < n; ++j)
             {
-                sal_Int32 nCol = 
static_cast<sal_Int32>(aParam.pSubTotals[i][j]);
-                ScSubTotalFunc eFunc = aParam.pFunctions[i][j];
+                sal_Int32 nCol = static_cast<sal_Int32>(group.col(j));
+                ScSubTotalFunc eFunc = group.func(j);
 
                 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, 
OUString::number(nCol));
                 OUString aFuncStr = 
ScXMLConverter::GetStringFromFunction(eFunc);
diff --git a/sc/source/filter/xml/xmldrani.cxx 
b/sc/source/filter/xml/xmldrani.cxx
index cce484918d21..8a91e8d44959 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -343,32 +343,14 @@ std::unique_ptr<ScDBData> 
ScXMLDatabaseRangeContext::ConvertToDBData(const OUStr
         {
             if (nPos >= MAXSUBTOTAL)
                 break;
+            auto& group = aParam.aGroups[nPos];
 
             const uno::Sequence<sheet::SubTotalColumn>& rColumns = 
rSubTotalRule.aSubTotalColumns;
-            sal_Int32 nColCount = rColumns.getLength();
             sal_Int16 nGroupColumn = 
rSubTotalRule.nSubTotalRuleGroupFieldNumber;
-            aParam.bGroupActive[nPos] = true;
-            aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
+            group.bActive = true;
+            group.nField = static_cast<SCCOL>(nGroupColumn);
 
-            SCCOL nCount = static_cast<SCCOL>(nColCount);
-            aParam.nSubTotals[nPos] = nCount;
-            if (nCount != 0)
-            {
-                aParam.pSubTotals[nPos].reset(new SCCOL[nCount]);
-                aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]);
-
-                const sheet::SubTotalColumn* pAry = rColumns.getConstArray();
-                for (SCCOL i = 0; i < nCount; ++i)
-                {
-                    aParam.pSubTotals[nPos][i] = 
static_cast<SCCOL>(pAry[i].Column);
-                    aParam.pFunctions[nPos][i] = 
ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function));
-                }
-            }
-            else
-            {
-                aParam.pSubTotals[nPos].reset();
-                aParam.pFunctions[nPos].reset();
-            }
+            group.SetSubtotals(rColumns);
             ++nPos;
         }
 
diff --git a/sc/source/ui/dbgui/tpsubt.cxx b/sc/source/ui/dbgui/tpsubt.cxx
index e0fcf640f756..f911292c08f7 100644
--- a/sc/source/ui/dbgui/tpsubt.cxx
+++ b/sc/source/ui/dbgui/tpsubt.cxx
@@ -130,22 +130,19 @@ bool ScTpSubTotalGroup::DoReset( sal_uInt16             
nGroupNo,
 
     const ScSubTotalParam & theSubTotalData( rArgSet.Get( nWhichSubTotals 
).GetSubTotalData() );
 
-    if ( theSubTotalData.bGroupActive[nGroupIdx] )
+    if (theSubTotalData.aGroups[nGroupIdx].bActive)
     {
-        SCCOL           nField      = theSubTotalData.nField[nGroupIdx];
-        SCCOL           nSubTotals  = theSubTotalData.nSubTotals[nGroupIdx];
-        SCCOL*          pSubTotals  = 
theSubTotalData.pSubTotals[nGroupIdx].get();
-        ScSubTotalFunc* pFunctions  = 
theSubTotalData.pFunctions[nGroupIdx].get();
+        const auto& group = theSubTotalData.aGroups[nGroupIdx];
 
-        mxLbGroup->set_active( GetFieldSelPos( nField )+1 );
+        mxLbGroup->set_active(GetFieldSelPos(group.nField) + 1);
 
         sal_uInt16 nFirstChecked = 0;
-        for ( sal_uInt16 i=0; i<nSubTotals; i++ )
+        for (sal_uInt16 i = 0; i < group.nSubTotals; i++)
         {
-            sal_uInt16  nCheckPos = GetFieldSelPos( pSubTotals[i] );
+            sal_uInt16 nCheckPos = GetFieldSelPos(group.col(i));
 
             mxLbColumns->set_toggle(nCheckPos, TRISTATE_TRUE);
-            mxLbColumns->set_id(nCheckPos, 
OUString::number(FuncToLbPos(pFunctions[i])));
+            mxLbColumns->set_id(nCheckPos, 
OUString::number(FuncToLbPos(group.func(i))));
 
             if (i == 0 || nCheckPos < nFirstChecked)
                 nFirstChecked = nCheckPos;
@@ -206,8 +203,8 @@ bool ScTpSubTotalGroup::DoFillItemSet( sal_uInt16       
nGroupNo,
     theSubTotalData.nRow1                   = rSubTotalData.nRow1;
     theSubTotalData.nCol2                   = rSubTotalData.nCol2;
     theSubTotalData.nRow2                   = rSubTotalData.nRow2;
-    theSubTotalData.bGroupActive[nGroupIdx] = (nGroup != 0);
-    theSubTotalData.nField[nGroupIdx]       = (nGroup != 0)
+    theSubTotalData.aGroups[nGroupIdx].bActive = (nGroup != 0);
+    theSubTotalData.aGroups[nGroupIdx].nField  = (nGroup != 0)
                                                 ? mnFieldArr[nGroup-1]
                                                 : static_cast<SCCOL>(0);
 
diff --git a/sc/source/ui/docshell/dbdocfun.cxx 
b/sc/source/ui/docshell/dbdocfun.cxx
index 357ad17417e6..bf6dd852614d 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -313,7 +313,7 @@ bool ScDBDocFunc::RepeatDB( const OUString& rDBName, bool 
bApi, bool bIsUnnamed,
 
         ScSubTotalParam aSubTotalParam;
         pDBData->GetSubTotalParam( aSubTotalParam );
-        bool bSubTotal = aSubTotalParam.bGroupActive[0] && 
!aSubTotalParam.bRemoveOnly;
+        bool bSubTotal = aSubTotalParam.aGroups[0].bActive && 
!aSubTotalParam.bRemoveOnly;
 
         if ( bQuery || bSort || bSubTotal )
         {
@@ -796,7 +796,7 @@ bool ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& 
rQueryParam,
         ScSubTotalParam aSubTotalParam;
         pDBData->GetSubTotalParam( aSubTotalParam );    // partial results 
exist?
 
-        if ( aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly )
+        if (aSubTotalParam.aGroups[0].bActive && !aSubTotalParam.bRemoveOnly)
             bKeepSub = true;
     }
 
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 384671ea0d99..29f437e77529 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -5470,15 +5470,15 @@ uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL 
ScCellRangeObj::createSubTot
             ScRange aDBRange;
             pData->GetArea(aDBRange);
             SCCOL nFieldStart = aDBRange.aStart.Col();
-            for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+            for (auto& group : aParam.aGroups)
             {
-                if ( aParam.bGroupActive[i] )
+                if (group.bActive)
                 {
-                    if ( aParam.nField[i] >= nFieldStart )
-                        aParam.nField[i] = sal::static_int_cast<SCCOL>( 
aParam.nField[i] - nFieldStart );
-                    for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
-                        if ( aParam.pSubTotals[i][j] >= nFieldStart )
-                            aParam.pSubTotals[i][j] = 
sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] - nFieldStart );
+                    if (group.nField >= nFieldStart)
+                        group.nField -= nFieldStart;
+                    for (SCCOL j = 0; j < group.nSubTotals; j++)
+                        if (group.col(j) >= nFieldStart)
+                            group.col(j) -= nFieldStart;
                 }
             }
             pNew->SetParam(aParam);
@@ -5507,13 +5507,13 @@ void SAL_CALL ScCellRangeObj::applySubTotals(
 
     //  SubTotalDescriptor contains the counted fields inside the area
     SCCOL nFieldStart = aRange.aStart.Col();
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+    for (auto& group : aParam.aGroups)
     {
-        if ( aParam.bGroupActive[i] )
+        if (group.bActive)
         {
-            aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + 
nFieldStart );
-            for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
-                aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( 
aParam.pSubTotals[i][j] + nFieldStart );
+            group.nField += nFieldStart;
+            for (SCCOL j = 0; j < group.nSubTotals; j++)
+                group.col(j) += nFieldStart;
         }
     }
 
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index db8946232706..99cb53d48222 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -459,7 +459,7 @@ sal_Int32 SAL_CALL ScSubTotalFieldObj::getGroupColumn()
     ScSubTotalParam aParam;
     xParent->GetData(aParam);
 
-    return aParam.nField[nPos];
+    return aParam.aGroups[nPos].nField;
 }
 
 void SAL_CALL ScSubTotalFieldObj::setGroupColumn( sal_Int32 nGroupColumn )
@@ -468,7 +468,7 @@ void SAL_CALL ScSubTotalFieldObj::setGroupColumn( sal_Int32 
nGroupColumn )
     ScSubTotalParam aParam;
     xParent->GetData(aParam);
 
-    aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
+    aParam.aGroups[nPos].nField = static_cast<SCCOL>(nGroupColumn);
 
     xParent->PutData(aParam);
 }
@@ -479,14 +479,13 @@ uno::Sequence<sheet::SubTotalColumn> SAL_CALL 
ScSubTotalFieldObj::getSubTotalCol
     ScSubTotalParam aParam;
     xParent->GetData(aParam);
 
-    SCCOL nCount = aParam.nSubTotals[nPos];
+    SCCOL nCount = aParam.aGroups[nPos].nSubTotals;
     uno::Sequence<sheet::SubTotalColumn> aSeq(nCount);
     sheet::SubTotalColumn* pAry = aSeq.getArray();
     for (SCCOL i=0; i<nCount; i++)
     {
-        pAry[i].Column = aParam.pSubTotals[nPos][i];
-        pAry[i].Function = ScDataUnoConversion::SubTotalToGeneral(
-                                        aParam.pFunctions[nPos][i] );
+        pAry[i].Column = aParam.aGroups[nPos].col(i);
+        pAry[i].Function = 
ScDataUnoConversion::SubTotalToGeneral(aParam.aGroups[nPos].func(i));
     }
     return aSeq;
 }
@@ -498,29 +497,8 @@ void SAL_CALL ScSubTotalFieldObj::setSubTotalColumns(
     ScSubTotalParam aParam;
     xParent->GetData(aParam);
 
-    sal_uInt32 nColCount = aSubTotalColumns.getLength();
-    if ( nColCount <= sal::static_int_cast<sal_uInt32>(SCCOL_MAX) )
-    {
-        SCCOL nCount = static_cast<SCCOL>(nColCount);
-        aParam.nSubTotals[nPos] = nCount;
-        if (nCount != 0)
-        {
-            aParam.pSubTotals[nPos].reset(new SCCOL[nCount]);
-            aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]);
-
-            const sheet::SubTotalColumn* pAry = 
aSubTotalColumns.getConstArray();
-            for (SCCOL i=0; i<nCount; i++)
-            {
-                aParam.pSubTotals[nPos][i] = 
static_cast<SCCOL>(pAry[i].Column);
-                aParam.pFunctions[nPos][i] = 
ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function));
-            }
-        }
-        else
-        {
-            aParam.pSubTotals[nPos].reset();
-            aParam.pFunctions[nPos].reset();
-        }
-    }
+    if (aSubTotalColumns.getLength() <= SCCOL_MAX)
+        aParam.aGroups[nPos].SetSubtotals(aSubTotalColumns);
     //! otherwise exception or so? (too many columns)
 
     xParent->PutData(aParam);
@@ -550,8 +528,8 @@ void SAL_CALL ScSubTotalDescriptorBase::clear()
     ScSubTotalParam aParam;
     GetData(aParam);
 
-    for (bool & rn : aParam.bGroupActive)
-        rn = false;
+    for (auto& group : aParam.aGroups)
+        group.bActive = false;
 
     //! notify the field objects???
 
@@ -567,40 +545,17 @@ void SAL_CALL ScSubTotalDescriptorBase::addNew(
     GetData(aParam);
 
     sal_uInt16 nPos = 0;
-    while ( nPos < MAXSUBTOTAL && aParam.bGroupActive[nPos] )
+    while (nPos < MAXSUBTOTAL && aParam.aGroups[nPos].bActive)
         ++nPos;
 
-    sal_uInt32 nColCount = aSubTotalColumns.getLength();
-
-    if ( nPos >= MAXSUBTOTAL || nColCount > 
sal::static_int_cast<sal_uInt32>(SCCOL_MAX) )
+    if (nPos >= MAXSUBTOTAL || aSubTotalColumns.getLength() > SCCOL_MAX)
         // too many fields / columns
         throw uno::RuntimeException();      // no other exceptions specified
+    auto& group = aParam.aGroups[nPos];
 
-    aParam.bGroupActive[nPos] = true;
-    aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn);
-
-    aParam.pSubTotals[nPos].reset();
-    aParam.pFunctions[nPos].reset();
-
-    SCCOL nCount = static_cast<SCCOL>(nColCount);
-    aParam.nSubTotals[nPos] = nCount;
-    if (nCount != 0)
-    {
-        aParam.pSubTotals[nPos].reset(new SCCOL[nCount]);
-        aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]);
-
-        const sheet::SubTotalColumn* pAry = aSubTotalColumns.getConstArray();
-        for (SCCOL i=0; i<nCount; i++)
-        {
-            aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column);
-            aParam.pFunctions[nPos][i] = 
ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function));
-        }
-    }
-    else
-    {
-        aParam.pSubTotals[nPos].reset();
-        aParam.pFunctions[nPos].reset();
-    }
+    group.bActive = true;
+    group.nField = static_cast<SCCOL>(nGroupColumn);
+    group.SetSubtotals(aSubTotalColumns);
 
     PutData(aParam);
 }
@@ -624,7 +579,7 @@ sal_Int32 SAL_CALL ScSubTotalDescriptorBase::getCount()
     GetData(aParam);
 
     sal_uInt16 nCount = 0;
-    while ( nCount < MAXSUBTOTAL && aParam.bGroupActive[nCount] )
+    while ( nCount < MAXSUBTOTAL && aParam.aGroups[nCount].bActive )
         ++nCount;
     return nCount;
 }
@@ -1770,16 +1725,15 @@ void 
ScDatabaseRangeObj::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
     ScRange aDBRange;
     pData->GetArea(aDBRange);
     SCCOL nFieldStart = aDBRange.aStart.Col();
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+    for (auto& group : rSubTotalParam.aGroups)
     {
-        if ( rSubTotalParam.bGroupActive[i] )
+        if (group.bActive)
         {
-            if ( rSubTotalParam.nField[i] >= nFieldStart )
-                rSubTotalParam.nField[i] = sal::static_int_cast<SCCOL>( 
rSubTotalParam.nField[i] - nFieldStart );
-            for (SCCOL j=0; j<rSubTotalParam.nSubTotals[i]; j++)
-                if ( rSubTotalParam.pSubTotals[i][j] >= nFieldStart )
-                    rSubTotalParam.pSubTotals[i][j] =
-                        sal::static_int_cast<SCCOL>( 
rSubTotalParam.pSubTotals[i][j] - nFieldStart );
+            if (group.nField >= nFieldStart)
+                group.nField -= nFieldStart;
+            for (SCCOL j = 0; j < group.nSubTotals; j++)
+                if (group.col(j) >= nFieldStart)
+                    group.col(j) -= nFieldStart;
         }
     }
 }
@@ -1795,13 +1749,13 @@ void ScDatabaseRangeObj::SetSubTotalParam(const 
ScSubTotalParam& rSubTotalParam)
     ScRange aDBRange;
     pData->GetArea(aDBRange);
     SCCOL nFieldStart = aDBRange.aStart.Col();
-    for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
+    for (auto& group : aParam.aGroups)
     {
-        if ( aParam.bGroupActive[i] )
+        if (group.bActive)
         {
-            aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + 
nFieldStart );
-            for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
-                aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( 
aParam.pSubTotals[i][j] + nFieldStart );
+            group.nField += nFieldStart;
+            for (SCCOL j = 0; j < group.nSubTotals; j++)
+                group.col(j) += nFieldStart;
         }
     }
 
diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
index 5f5a0621c9f6..0123cbf648f7 100644
--- a/sc/source/ui/view/dbfunc.cxx
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -198,7 +198,7 @@ void ScDBFunc::UISort( const ScSortParam& rSortParam )
 
     ScSubTotalParam aSubTotalParam;
     pDBData->GetSubTotalParam( aSubTotalParam );
-    if (aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly)
+    if (aSubTotalParam.aGroups[0].bActive && !aSubTotalParam.bRemoveOnly)
     {
         //  repeat subtotals, with new sortorder
 
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 7a2ba764a3e1..515a99add718 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -2123,7 +2123,7 @@ void ScDBFunc::RepeatDB( bool bRecord )
 
     ScSubTotalParam aSubTotalParam;
     pDBData->GetSubTotalParam( aSubTotalParam );
-    bool bSubTotal = aSubTotalParam.bGroupActive[0] && 
!aSubTotalParam.bRemoveOnly;
+    bool bSubTotal = aSubTotalParam.aGroups[0].bActive && 
!aSubTotalParam.bRemoveOnly;
 
     if ( bQuery || bSort || bSubTotal )
     {

Reply via email to