[Libreoffice-commits] core.git: sc/inc sc/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Wed Sep 9 19:11:15 UTC 2020


 sc/inc/chgtrack.hxx                    |   13 ---
 sc/inc/colcontainer.hxx                |    4 
 sc/inc/column.hxx                      |    2 
 sc/inc/columnspanset.hxx               |    4 
 sc/source/core/data/attarray.cxx       |   10 +-
 sc/source/core/data/bcaslot.cxx        |  134 +++++++++++++++------------------
 sc/source/core/data/colcontainer.cxx   |    8 -
 sc/source/core/data/column.cxx         |   30 ++++---
 sc/source/core/data/column2.cxx        |   12 +-
 sc/source/core/data/column3.cxx        |   26 +++---
 sc/source/core/data/column4.cxx        |   10 +-
 sc/source/core/data/columnspanset.cxx  |    6 -
 sc/source/core/data/documen3.cxx       |    2 
 sc/source/core/data/document.cxx       |    4 
 sc/source/core/data/documentimport.cxx |    6 -
 sc/source/core/data/dpcache.cxx        |    8 -
 sc/source/core/data/table1.cxx         |    4 
 sc/source/core/data/table3.cxx         |   18 ++--
 sc/source/core/data/table6.cxx         |    2 
 sc/source/core/inc/bcaslot.hxx         |   16 +++
 sc/source/core/tool/address.cxx        |   13 +--
 sc/source/core/tool/chgtrack.cxx       |   28 ++++--
 sc/source/core/tool/interpr3.cxx       |    7 +
 sc/source/filter/excel/colrowst.cxx    |    8 -
 sc/source/filter/lotus/lotattr.cxx     |    2 
 sc/source/filter/xml/xmlrowi.cxx       |    2 
 sc/source/ui/navipi/navipi.cxx         |    9 +-
 sc/source/ui/pagedlg/areasdlg.cxx      |    8 -
 sc/source/ui/unoobj/chart2uno.cxx      |    6 -
 sc/source/ui/unoobj/funcuno.cxx        |    4 
 sc/source/ui/view/viewdata.cxx         |    2 
 31 files changed, 217 insertions(+), 191 deletions(-)

New commits:
commit 94512c499d678e9eeca05e84361d846bbd3b6950
Author:     Noel Grandin <noelgrandin at gmail.com>
AuthorDate: Tue May 26 21:03:25 2020 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Wed Sep 9 21:10:32 2020 +0200

    sc: rowcol: convert more use of MAXROWCOUNT
    
    this is part of the very large(jumbo) sheet work
    
    Change-Id: Ia5c1246e908d3c81d7ec7eff39a3580d5362969c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94889
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx
index 146521538943..94062c846836 100644
--- a/sc/inc/chgtrack.hxx
+++ b/sc/inc/chgtrack.hxx
@@ -826,8 +826,8 @@ class SAL_DLLPUBLIC_RTTI ScChangeTrack : public utl::ConfigurationListener
     friend void ScChangeActionMove::DeleteCellEntries();
     friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
 
-    static  const SCROW         nContentRowsPerSlot;
-    static  const SCSIZE        nContentSlots;
+    SCROW               mnContentRowsPerSlot;
+    SCSIZE              mnContentSlots;
 
     css::uno::Sequence< sal_Int8 >   aProtectPass;
     ScChangeActionMap   aMap;
@@ -869,7 +869,7 @@ class SAL_DLLPUBLIC_RTTI ScChangeTrack : public utl::ConfigurationListener
     ScChangeTrack( const ScChangeTrack& ) = delete;
     ScChangeTrack& operator=( const ScChangeTrack& ) = delete;
 
-    static  SCROW               InitContentRowsPerSlot();
+    SCROW               InitContentRowsPerSlot();
 
     // true if one is ScMatrixMode::Formula and the other is
     // not, or if both are and range differs
@@ -948,12 +948,7 @@ class SAL_DLLPUBLIC_RTTI ScChangeTrack : public utl::ConfigurationListener
 
 public:
 
-    static  SCSIZE              ComputeContentSlot( sal_Int32 nRow )
-                                    {
-                                        if ( nRow < 0 || nRow > MAXROW )
-                                            return nContentSlots - 1;
-                                        return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
-                                    }
+    SCSIZE              ComputeContentSlot( sal_Int32 nRow ) const;
 
     SC_DLLPUBLIC ScChangeTrack( ScDocument* );
     ScChangeTrack(ScDocument* pDocP, const std::set<OUString>& aTempUserCollection); // only to use in the XML import
diff --git a/sc/inc/colcontainer.hxx b/sc/inc/colcontainer.hxx
index a3a871a8787d..e3f36e5172b6 100644
--- a/sc/inc/colcontainer.hxx
+++ b/sc/inc/colcontainer.hxx
@@ -31,7 +31,7 @@ class ScColContainer
 public:
     typedef std::vector<std::unique_ptr<ScColumn, o3tl::default_delete<ScColumn>>> ScColumnVector;
 
-    ScColContainer( const size_t nSize );
+    ScColContainer( ScSheetLimits const &, const size_t nSize );
     ~ScColContainer() COVERITY_NOEXCEPT_FALSE;
 
     const ScColumn& operator[] ( const size_t nIndex ) const
@@ -54,7 +54,7 @@ public:
         return aCols.empty();
     }
 
-    void resize( const size_t aNewSize );
+    void resize( ScSheetLimits const &, const size_t aNewSize );
 
     void Clear();
 
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index f5417eec3623..25f8e1430906 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -174,7 +174,7 @@ public:
         BROADCAST_BROADCASTERS      ///< broadcast only existing cell broadcasters => no AreaBroadcast of range!
     };
 
-    ScColumn();
+    ScColumn(ScSheetLimits const &);
     ~ScColumn() COVERITY_NOEXCEPT_FALSE;
 
     void        Init(SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc, bool bEmptyAttrArray);
diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx
index a2f7c7bf6cf9..9e7e4f16fe24 100644
--- a/sc/inc/columnspanset.hxx
+++ b/sc/inc/columnspanset.hxx
@@ -19,6 +19,7 @@ class ScDocument;
 class ScColumn;
 class ScMarkData;
 class ScRangeList;
+struct ScSheetLimits;
 
 namespace sc {
 
@@ -114,7 +115,7 @@ public:
 
     typedef std::vector<RowSpan> SpansType;
 
-    SingleColumnSpanSet();
+    SingleColumnSpanSet(ScSheetLimits const &);
 
     /**
      * Scan an entire column and tag all non-empty cell positions.
@@ -149,6 +150,7 @@ public:
     bool empty() const;
 
 private:
+    ScSheetLimits const & mrSheetLimits;
     ColumnSpansType maSpans;
 };
 
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 201c7698d9a6..06f8638038e9 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -519,7 +519,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
             bool bSplit = false;
             if ( nStartRow > 0 )
             {
-                nInsert = MAXROWCOUNT;
+                nInsert = pDocument->MaxRow() + 1;
                 if ( mvData[ni].pPattern != pPattern )
                 {
                     if ( ni == 0 || (mvData[ni-1].nEndRow < nStartRow - 1) )
@@ -536,7 +536,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
                 if ( ni > 0 && mvData[ni-1].pPattern == pPattern )
                 {   // combine
                     mvData[ni-1].nEndRow = nEndRow;
-                    nInsert = MAXROWCOUNT;
+                    nInsert = pDocument->MaxRow() + 1;
                     bCombined = true;
                 }
             }
@@ -560,7 +560,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
                         else if ( ni == nInsert )
                             mvData[ni-1].nEndRow = nStartRow - 1;   // shrink
                     }
-                    nInsert = MAXROWCOUNT;
+                    nInsert = pDocument->MaxRow() + 1;
                     bCombined = true;
                 }
                 else if ( ni > 0 && ni == nInsert )
@@ -582,7 +582,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
                     mvData[ni].nEndRow = nEndRow;
                     mvData[ni].pPattern = pPattern;
                     ni++;
-                    nInsert = MAXROWCOUNT;
+                    nInsert = pDocument->MaxRow() + 1;
                 }
                 if ( ni < nj )
                 {   // remove entries
@@ -590,7 +590,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
                 }
             }
 
-            if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+            if ( nInsert < sal::static_int_cast<SCSIZE>(pDocument->MaxRow() + 1) )
             {   // insert or append new entry
                 if ( nInsert <= mvData.size() )
                 {
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index fb80a7bdb17c..bbca9dda93ae 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -38,63 +38,25 @@
 // Number of slots per dimension
 // must be integer divisors of MAXCOLCOUNT respectively MAXROWCOUNT
 constexpr SCCOL BCA_SLOTS_COL  = MAXCOLCOUNT / 16;
-constexpr SCROW BCA_SLICE = 128;
-constexpr SCROW BCA_SLOTS_ROW  = MAXROWCOUNT / BCA_SLICE;
 constexpr SCCOL BCA_SLOT_COLS  = MAXCOLCOUNT / BCA_SLOTS_COL;
-constexpr SCROW BCA_SLOT_ROWS  = MAXROWCOUNT / BCA_SLOTS_ROW;
+#if !defined NDEBUG
+constexpr SCROW BCA_SLICE = 128;
+static SCROW BCA_SLOTS_ROW(const ScSheetLimits& rLimits)  { return rLimits.GetMaxRowCount() / BCA_SLICE; }
+static SCROW BCA_SLOT_ROWS(const ScSheetLimits& rLimits)
+{
+    auto nMaxRowCount = rLimits.GetMaxRowCount();
+    auto nSlotsRow = BCA_SLOTS_ROW(rLimits);
+    assert((nMaxRowCount / nSlotsRow * nSlotsRow) == nMaxRowCount && "bad BCA_SLOTS_ROW value");
+    return nMaxRowCount / nSlotsRow;
+}
+#endif
 // multiple?
 static_assert((BCA_SLOT_COLS * BCA_SLOTS_COL) == MAXCOLCOUNT, "bad BCA_SLOTS_COL value");
-static_assert((BCA_SLOT_ROWS * BCA_SLOTS_ROW) == MAXROWCOUNT, "bad BCA_SLOTS_ROW value");
 
 // size of slot array if linear
-constexpr int BCA_SLOTS  = BCA_SLOTS_COL * BCA_SLOTS_ROW;
-// Arbitrary 2**31/8, assuming size_t can hold at least 2^31 values and
-// sizeof_ptr is at most 8 bytes. You'd probably doom your machine's memory
-// anyway, once you reached these values...
-static_assert(BCA_SLOTS <= 268435456, "DOOMed");
-
-namespace {
-
-struct ScSlotData
-{
-    SCROW  nStartRow;   // first row of this segment
-    SCROW  nStopRow;    // first row of next segment
-    SCSIZE nSlice;      // slice size in this segment
-    SCSIZE nCumulated;  // cumulated slots of previous segments
-
-    ScSlotData( SCROW r1, SCROW r2, SCSIZE s, SCSIZE c ) : nStartRow(r1), nStopRow(r2), nSlice(s), nCumulated(c) {}
-};
-
-}
-
-typedef ::std::vector< ScSlotData > ScSlotDistribution;
-// Logarithmic or any other distribution.
-// Upper sheet part usually is more populated and referenced and gets fine
-// grained resolution, larger data in larger hunks.
-// Could be further enhanced by also applying a different distribution of
-// column slots.
-static SCSIZE initSlotDistribution( ScSlotDistribution & rSD, SCSIZE & rBSR )
-{
-    SCSIZE nSlots = 0;
-    SCROW nRow1 = 0;
-    SCROW nRow2 = 32*1024;
-    SCSIZE nSlice = 128;
-    // Must be sorted by row1,row2!
-    while (nRow2 <= MAXROWCOUNT)
-    {
-        rSD.emplace_back( nRow1, nRow2, nSlice, nSlots);
-        nSlots += (nRow2 - nRow1) / nSlice;
-        nRow1 = nRow2;
-        nRow2 *= 2;
-        nSlice *= 2;
-    }
-    rBSR = nSlots;
-    return nSlots;
-}
-static ScSlotDistribution aSlotDistribution;
-static SCSIZE nBcaSlotsRow;
-static SCSIZE nBcaSlots = initSlotDistribution( aSlotDistribution, nBcaSlotsRow) * BCA_SLOTS_COL;
-// Ensure that all static variables are initialized with this one call.
+#if !defined NDEBUG
+static int BCA_SLOTS(const ScSheetLimits& rLimits)  { return BCA_SLOTS_COL * BCA_SLOTS_ROW(rLimits); }
+#endif
 
 ScBroadcastArea::ScBroadcastArea( const ScRange& rRange ) :
     pUpdateChainNext(nullptr),
@@ -610,7 +572,8 @@ void ScBroadcastAreaSlot::FinallyEraseAreas()
 
 // --- ScBroadcastAreaSlotMachine -------------------------------------
 
-ScBroadcastAreaSlotMachine::TableSlots::TableSlots()
+ScBroadcastAreaSlotMachine::TableSlots::TableSlots(SCSIZE nBcaSlots)
+    : mnBcaSlots(nBcaSlots)
 {
     ppSlots.reset( new ScBroadcastAreaSlot* [ nBcaSlots ] );
     memset( ppSlots.get(), 0 , sizeof( ScBroadcastAreaSlot* ) * nBcaSlots );
@@ -618,7 +581,7 @@ ScBroadcastAreaSlotMachine::TableSlots::TableSlots()
 
 ScBroadcastAreaSlotMachine::TableSlots::~TableSlots()
 {
-    for ( ScBroadcastAreaSlot** pp = ppSlots.get() + nBcaSlots; --pp >= ppSlots.get(); /* nothing */ )
+    for ( ScBroadcastAreaSlot** pp = ppSlots.get() + mnBcaSlots; --pp >= ppSlots.get(); /* nothing */ )
         delete *pp;
 }
 
@@ -629,6 +592,35 @@ ScBroadcastAreaSlotMachine::ScBroadcastAreaSlotMachine(
     pEOUpdateChain( nullptr ),
     nInBulkBroadcast( 0 )
 {
+    const ScSheetLimits& rSheetLimits = pDoc->GetSheetLimits();
+
+    assert((BCA_SLOT_ROWS(rSheetLimits) * BCA_SLOTS_ROW(rSheetLimits)) == pDoc->GetSheetLimits().GetMaxRowCount() && "bad BCA_SLOTS_ROW value");
+    // Arbitrary 2**31/8, assuming size_t can hold at least 2^31 values and
+    // sizeof_ptr is at most 8 bytes. You'd probably doom your machine's memory
+    // anyway, once you reached these values...
+    assert(BCA_SLOTS(rSheetLimits) <= 268435456 && "DOOMed");
+
+    // initSlotDistribution ---------
+    // Logarithmic or any other distribution.
+    // Upper sheet part usually is more populated and referenced and gets fine
+    // grained resolution, larger data in larger hunks.
+    // Could be further enhanced by also applying a different distribution of
+    // column slots.
+    SCSIZE nSlots = 0;
+    SCROW nRow1 = 0;
+    SCROW nRow2 = 32*1024;
+    SCSIZE nSlice = 128;
+    // Must be sorted by row1,row2!
+    while (nRow2 <= rSheetLimits.GetMaxRowCount())
+    {
+        maSlotDistribution.emplace_back( nRow1, nRow2, nSlice, nSlots);
+        nSlots += (nRow2 - nRow1) / nSlice;
+        nRow1 = nRow2;
+        nRow2 *= 2;
+        nSlice *= 2;
+    }
+    mnBcaSlotsRow = nSlots;
+    mnBcaSlots = mnBcaSlotsRow * BCA_SLOTS_COL;
 }
 
 ScBroadcastAreaSlotMachine::~ScBroadcastAreaSlotMachine()
@@ -650,18 +642,18 @@ inline SCSIZE ScBroadcastAreaSlotMachine::ComputeSlotOffset(
         OSL_FAIL( "Row/Col invalid, using first slot!" );
         return 0;
     }
-    for (const ScSlotData & i : aSlotDistribution)
+    for (const ScSlotData & i : maSlotDistribution)
     {
         if (nRow < i.nStopRow)
         {
             const ScSlotData& rSD = i;
             return rSD.nCumulated +
                 static_cast<SCSIZE>(nRow - rSD.nStartRow) / rSD.nSlice +
-                static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * nBcaSlotsRow;
+                static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * mnBcaSlotsRow;
         }
     }
     OSL_FAIL( "No slot found, using last!" );
-    return nBcaSlots - 1;
+    return mnBcaSlots - 1;
 }
 
 void ScBroadcastAreaSlotMachine::ComputeAreaPoints( const ScRange& rRange,
@@ -675,7 +667,7 @@ void ScBroadcastAreaSlotMachine::ComputeAreaPoints( const ScRange& rRange,
 }
 
 static void ComputeNextSlot( SCSIZE & nOff, SCSIZE & nBreak, ScBroadcastAreaSlot** & pp,
-        SCSIZE & nStart, ScBroadcastAreaSlot** const & ppSlots, SCSIZE nRowBreak )
+        SCSIZE & nStart, ScBroadcastAreaSlot** const & ppSlots, SCSIZE nRowBreak, SCSIZE nBcaSlotsRow )
 {
     if ( nOff < nBreak )
     {
@@ -713,7 +705,7 @@ void ScBroadcastAreaSlotMachine::StartListeningArea(
         {
             TableSlotsMap::iterator iTab( aTableSlotsMap.find( nTab));
             if (iTab == aTableSlotsMap.end())
-                iTab = aTableSlotsMap.emplace(nTab, std::make_unique<TableSlots>()).first;
+                iTab = aTableSlotsMap.emplace(nTab, std::make_unique<TableSlots>(mnBcaSlots)).first;
             ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
             SCSIZE nStart, nEnd, nRowBreak;
             ComputeAreaPoints( rRange, nStart, nEnd, nRowBreak );
@@ -735,7 +727,7 @@ void ScBroadcastAreaSlotMachine::StartListeningArea(
                 }
                 else
                     (*pp)->InsertListeningArea( pArea);
-                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
             }
         }
     }
@@ -768,7 +760,7 @@ void ScBroadcastAreaSlotMachine::EndListeningArea(
             SCSIZE nBreak = nOff + nRowBreak;
             ScBroadcastAreaSlot** pp = ppSlots + nOff;
             ScBroadcastArea* pArea = nullptr;
-            if (nOff == 0 && nEnd == nBcaSlots-1)
+            if (nOff == 0 && nEnd == mnBcaSlots-1)
             {
                 // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
                 // happen for insertion and deletion of sheets.
@@ -785,7 +777,7 @@ void ScBroadcastAreaSlotMachine::EndListeningArea(
                 {
                     if ( *pp )
                         (*pp)->EndListeningArea( rRange, bGroupListening, pListener, pArea);
-                    ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+                    ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
                 }
             }
         }
@@ -809,7 +801,7 @@ bool ScBroadcastAreaSlotMachine::AreaBroadcast( const ScRange& rRange, SfxHintId
         {
             if ( *pp )
                 bBroadcasted |= (*pp)->AreaBroadcast( rRange, nHint );
-            ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+            ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
         }
     }
     return bBroadcasted;
@@ -855,7 +847,7 @@ void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange(
         SCSIZE nOff = nStart;
         SCSIZE nBreak = nOff + nRowBreak;
         ScBroadcastAreaSlot** pp = ppSlots + nOff;
-        if (nOff == 0 && nEnd == nBcaSlots-1)
+        if (nOff == 0 && nEnd == mnBcaSlots-1)
         {
             // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
             // happen for insertion and deletion of sheets.
@@ -872,7 +864,7 @@ void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange(
             {
                 if ( *pp )
                     (*pp)->DelBroadcastAreasInRange( rRange );
-                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
             }
         }
     }
@@ -894,7 +886,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
         SCSIZE nOff = nStart;
         SCSIZE nBreak = nOff + nRowBreak;
         ScBroadcastAreaSlot** pp = ppSlots + nOff;
-        if (nOff == 0 && nEnd == nBcaSlots-1)
+        if (nOff == 0 && nEnd == mnBcaSlots-1)
         {
             // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
             // happen for insertion and deletion of sheets.
@@ -911,7 +903,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
             {
                 if ( *pp )
                     (*pp)->UpdateRemove( eUpdateRefMode, rRange, nDx, nDy, nDz );
-                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
             }
         }
     }
@@ -943,7 +935,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
             {
                 if (*pp)
                     (*pp)->UpdateRemoveArea( pArea);
-                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
             }
         }
 
@@ -1024,7 +1016,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
         {
             TableSlotsMap::iterator iTab( aTableSlotsMap.find( nTab));
             if (iTab == aTableSlotsMap.end())
-                iTab = aTableSlotsMap.emplace(nTab, std::make_unique<TableSlots>()).first;
+                iTab = aTableSlotsMap.emplace(nTab, std::make_unique<TableSlots>(mnBcaSlots)).first;
             ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots();
             SCSIZE nStart, nEnd, nRowBreak;
             ComputeAreaPoints( aRange, nStart, nEnd, nRowBreak );
@@ -1036,7 +1028,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
                 if (!*pp)
                     *pp = new ScBroadcastAreaSlot( pDoc, this );
                 (*pp)->UpdateInsert( pArea );
-                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+                ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
             }
         }
 
@@ -1183,7 +1175,7 @@ std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners(
             ScBroadcastAreaSlot* p = *pp;
             if (p)
                 p->GetAllListeners(rRange, aRet, eType, eGroup);
-            ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
+            ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak, mnBcaSlotsRow);
         }
     }
 
diff --git a/sc/source/core/data/colcontainer.cxx b/sc/source/core/data/colcontainer.cxx
index 4a99bc16f336..a0a9d845772f 100644
--- a/sc/source/core/data/colcontainer.cxx
+++ b/sc/source/core/data/colcontainer.cxx
@@ -21,11 +21,11 @@
 #include <colcontainer.hxx>
 #include <column.hxx>
 
-ScColContainer::ScColContainer( const size_t nSize )
+ScColContainer::ScColContainer( ScSheetLimits const & rSheetLimits, const size_t nSize )
 {
     aCols.resize( nSize );
     for ( size_t nCol = 0; nCol < nSize; ++nCol )
-        aCols[nCol].reset( new ScColumn() );
+        aCols[nCol].reset( new ScColumn(rSheetLimits) );
 }
 
 ScColContainer::~ScColContainer() COVERITY_NOEXCEPT_FALSE
@@ -44,12 +44,12 @@ void ScColContainer::Clear()
     aCols.clear();
 }
 
-void ScColContainer::resize( const size_t aNewColSize )
+void ScColContainer::resize( ScSheetLimits const & rSheetLimits, const size_t aNewColSize )
 {
     size_t aOldColSize = aCols.size();
     aCols.resize( aNewColSize );
     for ( size_t nCol = aOldColSize; nCol < aNewColSize; ++nCol )
-        aCols[nCol].reset(new ScColumn());
+        aCols[nCol].reset(new ScColumn(rSheetLimits));
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 34be6086f10e..e7123988262b 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -77,17 +77,17 @@ ScNeededSizeOptions::ScNeededSizeOptions() :
 {
 }
 
-ScColumn::ScColumn() :
-    maCellTextAttrs(MAXROWCOUNT),
-    maCellNotes(MAXROWCOUNT),
-    maBroadcasters(MAXROWCOUNT),
+ScColumn::ScColumn(ScSheetLimits const & rSheetLimits) :
+    maCellTextAttrs(rSheetLimits.GetMaxRowCount()),
+    maCellNotes(rSheetLimits.GetMaxRowCount()),
+    maBroadcasters(rSheetLimits.GetMaxRowCount()),
     maCellsEvent(this),
     maCells(maCellsEvent),
     mnBlkCountFormula(0),
     nCol( 0 ),
     nTab( 0 )
 {
-    maCells.resize(MAXROWCOUNT);
+    maCells.resize(rSheetLimits.GetMaxRowCount());
 }
 
 ScColumn::~ScColumn() COVERITY_NOEXCEPT_FALSE
@@ -868,16 +868,16 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     pAttrArray->InsertRow( nStartRow, nSize );
 
     maCellNotes.insert_empty(nStartRow, nSize);
-    maCellNotes.resize(MAXROWCOUNT);
+    maCellNotes.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     maBroadcasters.insert_empty(nStartRow, nSize);
-    maBroadcasters.resize(MAXROWCOUNT);
+    maBroadcasters.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     maCellTextAttrs.insert_empty(nStartRow, nSize);
-    maCellTextAttrs.resize(MAXROWCOUNT);
+    maCellTextAttrs.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     maCells.insert_empty(nStartRow, nSize);
-    maCells.resize(MAXROWCOUNT);
+    maCells.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     CellStorageModified();
 
@@ -1775,7 +1775,7 @@ void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
     // rows that are present in the position column (rPosCol).
 
     // First, mark all the non-empty cell ranges from the position column.
-    sc::SingleColumnSpanSet aRangeSet;
+    sc::SingleColumnSpanSet aRangeSet(GetDoc()->GetSheetLimits());
     aRangeSet.scan(rPosCol);
 
     // Now, copy cells from this column to the destination column for those
@@ -1993,7 +1993,7 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
     pAttrArray->MoveTo(nStartRow, nEndRow, *rCol.pAttrArray);
 
     // Mark the non-empty cells within the specified range, for later broadcasting.
-    sc::SingleColumnSpanSet aNonEmpties;
+    sc::SingleColumnSpanSet aNonEmpties(GetDoc()->GetSheetLimits());
     aNonEmpties.scan(*this, nStartRow, nEndRow);
     sc::SingleColumnSpanSet::SpansType aRanges;
     aNonEmpties.getSpans(aRanges);
@@ -2822,7 +2822,9 @@ class SetDirtyOnRangeHandler
     sc::SingleColumnSpanSet maValueRanges;
     ScColumn& mrColumn;
 public:
-    explicit SetDirtyOnRangeHandler(ScColumn& rColumn) : mrColumn(rColumn) {}
+    explicit SetDirtyOnRangeHandler(ScColumn& rColumn)
+        : maValueRanges(rColumn.GetDoc()->GetSheetLimits()),
+          mrColumn(rColumn) {}
 
     void operator() (size_t /*nRow*/, ScFormulaCell* p)
     {
@@ -2865,7 +2867,9 @@ class SetTableOpDirtyOnRangeHandler
     sc::SingleColumnSpanSet maValueRanges;
     ScColumn& mrColumn;
 public:
-    explicit SetTableOpDirtyOnRangeHandler(ScColumn& rColumn) : mrColumn(rColumn) {}
+    explicit SetTableOpDirtyOnRangeHandler(ScColumn& rColumn)
+        : maValueRanges(rColumn.GetDoc()->GetSheetLimits()),
+          mrColumn(rColumn) {}
 
     void operator() (size_t /*nRow*/, ScFormulaCell* p)
     {
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index c96d34679f68..32080e851d8c 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -669,7 +669,7 @@ sal_uInt16 ScColumn::GetOptimalColWidth(
         // All cells are empty.
         return nOldWidth;
 
-    sc::SingleColumnSpanSet aSpanSet;
+    sc::SingleColumnSpanSet aSpanSet(GetDoc()->GetSheetLimits());
     sc::SingleColumnSpanSet::SpansType aMarkedSpans;
     if (pMarkData && (pMarkData->IsMarked() || pMarkData->IsMultiMarked()))
     {
@@ -889,7 +889,7 @@ void ScColumn::GetOptimalHeight(
                 }
             }
 
-            sc::SingleColumnSpanSet aSpanSet;
+            sc::SingleColumnSpanSet aSpanSet(GetDoc()->GetSheetLimits());
             aSpanSet.scan(*this, nStart, nEnd);
             sc::SingleColumnSpanSet::SpansType aSpans;
             aSpanSet.getSpans(aSpans);
@@ -1603,21 +1603,21 @@ void ScColumn::CellStorageModified()
     // TODO: Update column's "last updated" timestamp here.
 
 #if DEBUG_COLUMN_STORAGE
-    if (maCells.size() != MAXROWCOUNT)
+    if (maCells.size() != MAXROWCOUNT1)
     {
         cout << "ScColumn::CellStorageModified: Size of the cell array is incorrect." << endl;
         cout.flush();
         abort();
     }
 
-    if (maCellTextAttrs.size() != MAXROWCOUNT)
+    if (maCellTextAttrs.size() != MAXROWCOUNT1)
     {
         cout << "ScColumn::CellStorageModified: Size of the cell text attribute array is incorrect." << endl;
         cout.flush();
         abort();
     }
 
-    if (maBroadcasters.size() != MAXROWCOUNT)
+    if (maBroadcasters.size() != MAXROWCOUNT1)
     {
         cout << "ScColumn::CellStorageModified: Size of the broadcaster array is incorrect." << endl;
         cout.flush();
@@ -3445,7 +3445,7 @@ public:
 void ScColumn::UpdateSelectionFunction(
     const ScRangeList& rRanges, ScFunctionData& rData, const ScFlatBoolRowSegments& rHiddenRows )
 {
-    sc::SingleColumnSpanSet aSpanSet;
+    sc::SingleColumnSpanSet aSpanSet(GetDoc()->GetSheetLimits());
     aSpanSet.scan(rRanges, nTab, nCol); // mark all selected rows.
 
     if (aSpanSet.empty())
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b5d7f4bd3162..43dc0c6b5338 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -86,7 +86,7 @@ void ScColumn::BroadcastCells( const std::vector<SCROW>& rRows, SfxHintId nHint
 
 void ScColumn::BroadcastRows( SCROW nStartRow, SCROW nEndRow, SfxHintId nHint )
 {
-    sc::SingleColumnSpanSet aSpanSet;
+    sc::SingleColumnSpanSet aSpanSet(GetDoc()->GetSheetLimits());
     aSpanSet.scan(*this, nStartRow, nEndRow);
     std::vector<SCROW> aRows;
     aSpanSet.getRows(aRows);
@@ -149,20 +149,21 @@ void ScColumn::Delete( SCROW nRow )
 
 void ScColumn::FreeAll()
 {
+    auto maxRowCount = GetDoc()->GetSheetLimits().GetMaxRowCount();
     // Keep a logical empty range of 0-rDoc.MaxRow() at all times.
     maCells.clear();
-    maCells.resize(MAXROWCOUNT);
+    maCells.resize(maxRowCount);
     maCellTextAttrs.clear();
-    maCellTextAttrs.resize(MAXROWCOUNT);
+    maCellTextAttrs.resize(maxRowCount);
     maCellNotes.clear();
-    maCellNotes.resize(MAXROWCOUNT);
+    maCellNotes.resize(maxRowCount);
     CellStorageModified();
 }
 
 void ScColumn::FreeNotes()
 {
     maCellNotes.clear();
-    maCellNotes.resize(MAXROWCOUNT);
+    maCellNotes.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 }
 
 namespace {
@@ -186,11 +187,11 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize, std::vector<ScAddress>*
     SCROW nEndRow = nStartRow + nSize - 1;
 
     maBroadcasters.erase(nStartRow, nEndRow);
-    maBroadcasters.resize(MAXROWCOUNT);
+    maBroadcasters.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     CellNotesDeleting(nStartRow, nEndRow, false);
     maCellNotes.erase(nStartRow, nEndRow);
-    maCellNotes.resize(MAXROWCOUNT);
+    maCellNotes.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     // See if we have any cells that would get deleted or shifted by deletion.
     sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
@@ -227,7 +228,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize, std::vector<ScAddress>*
             bShiftCells = true;
     }
 
-    sc::SingleColumnSpanSet aNonEmptySpans;
+    sc::SingleColumnSpanSet aNonEmptySpans(GetDoc()->GetSheetLimits());
     if (bShiftCells)
     {
         // Mark all non-empty cell positions below the end row.
@@ -240,7 +241,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize, std::vector<ScAddress>*
 
     // Remove the cells.
     maCells.erase(nStartRow, nEndRow);
-    maCells.resize(MAXROWCOUNT);
+    maCells.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     // Get the position again after the container change.
     aPos = maCells.position(nStartRow);
@@ -255,7 +256,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize, std::vector<ScAddress>*
 
     // Shift the text attribute array too (before the broadcast).
     maCellTextAttrs.erase(nStartRow, nEndRow);
-    maCellTextAttrs.resize(MAXROWCOUNT);
+    maCellTextAttrs.resize(GetDoc()->GetSheetLimits().GetMaxRowCount());
 
     CellStorageModified();
 }
@@ -814,6 +815,7 @@ class DeleteAreaHandler
 public:
     DeleteAreaHandler(ScDocument& rDoc, InsertDeleteFlags nDelFlag, ScColumn& rCol) :
         mrDoc(rDoc),
+        maDeleteRanges(rDoc.GetSheetLimits()),
         mbNumeric(nDelFlag & InsertDeleteFlags::VALUE),
         mbString(nDelFlag & InsertDeleteFlags::STRING),
         mbFormula(nDelFlag & InsertDeleteFlags::FORMULA),
@@ -993,7 +995,7 @@ void ScColumn::DeleteArea(
         nContMask |= InsertDeleteFlags::NOCAPTIONS;
     InsertDeleteFlags nContFlag = nDelFlag & nContMask;
 
-    sc::SingleColumnSpanSet aDeletedRows;
+    sc::SingleColumnSpanSet aDeletedRows(GetDoc()->GetSheetLimits());
 
     sc::ColumnBlockPosition aBlockPos;
     InitBlockPosition(aBlockPos);
@@ -1393,7 +1395,7 @@ void ScColumn::CopyFromClip(
         if (rCxt.isSkipAttrForEmptyCells())
         {
             //  copy only attributes for non-empty cells between nRow1-nDy and nRow2-nDy.
-            sc::SingleColumnSpanSet aSpanSet;
+            sc::SingleColumnSpanSet aSpanSet(GetDoc()->GetSheetLimits());
             aSpanSet.scan(rColumn, nRow1-nDy, nRow2-nDy);
             sc::SingleColumnSpanSet::SpansType aSpans;
             aSpanSet.getSpans(aSpans);
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 1b1b18acc3e0..ae3cd16fffa7 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -106,7 +106,7 @@ void ScColumn::DeleteBeforeCopyFromClip(
     SCROW nClipRowLen = nClipRow2 - nClipRow1 + 1;
 
     // Check for non-empty cell ranges in the clip column.
-    sc::SingleColumnSpanSet aSpanSet;
+    sc::SingleColumnSpanSet aSpanSet(GetDoc()->GetSheetLimits());
     aSpanSet.scan(rClipCol, nClipRow1, nClipRow2);
     sc::SingleColumnSpanSet::SpansType aSpans;
     aSpanSet.getSpans(aSpans);
@@ -160,7 +160,7 @@ void ScColumn::DeleteBeforeCopyFromClip(
 
         if (nDelFlag & InsertDeleteFlags::CONTENTS)
         {
-            sc::SingleColumnSpanSet aDeletedRows;
+            sc::SingleColumnSpanSet aDeletedRows(GetDoc()->GetSheetLimits());
             DeleteCells(aBlockPos, nRow1, nRow2, nDelFlag, aDeletedRows);
             rBroadcastSpans.set(*GetDoc(), nTab, nCol, aDeletedRows, true);
         }
@@ -396,10 +396,10 @@ class ConvertFormulaToValueHandler
     bool mbModified;
 
 public:
-    ConvertFormulaToValueHandler() :
+    ConvertFormulaToValueHandler(ScSheetLimits const & rSheetLimits) :
         mbModified(false)
     {
-        maResValues.reset(MAXROWCOUNT);
+        maResValues.reset(rSheetLimits.GetMaxRowCount());
     }
 
     void operator() ( size_t nRow, const ScFormulaCell* pCell )
@@ -444,7 +444,7 @@ void ScColumn::ConvertFormulaToValue(
     sc::SharedFormulaUtil::splitFormulaCellGroups(GetDoc(), maCells, aBounds);
 
     // Parse all formulas within the range and store their results into temporary storage.
-    ConvertFormulaToValueHandler aFunc;
+    ConvertFormulaToValueHandler aFunc(GetDoc()->GetSheetLimits());
     sc::ParseFormula(maCells.begin(), maCells, nRow1, nRow2, aFunc);
     if (!aFunc.isModified())
         // No formula cells encountered.
diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx
index e8c4baf31887..fe9b55193d6f 100644
--- a/sc/source/core/data/columnspanset.cxx
+++ b/sc/source/core/data/columnspanset.cxx
@@ -240,7 +240,9 @@ public:
 
 }
 
-SingleColumnSpanSet::SingleColumnSpanSet() : maSpans(0, MAXROWCOUNT, false) {}
+SingleColumnSpanSet::SingleColumnSpanSet(ScSheetLimits const & rSheetLimits)
+    : mrSheetLimits(rSheetLimits),
+      maSpans(0, rSheetLimits.GetMaxRowCount(), false) {}
 
 void SingleColumnSpanSet::scan(const ScColumn& rColumn)
 {
@@ -332,7 +334,7 @@ bool SingleColumnSpanSet::empty() const
 {
     // Empty if there's only the 0..rDoc.MaxRow() span with false.
     ColumnSpansType::const_iterator it = maSpans.begin();
-    return (it->first == 0) && !(it->second) && (++it != maSpans.end()) && (it->first == MAXROWCOUNT);
+    return (it->first == 0) && !(it->second) && (++it != maSpans.end()) && (it->first == mrSheetLimits.GetMaxRowCount());
 }
 
 
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index ae51c8d22b5c..0cb33bc3905f 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -990,7 +990,7 @@ void ScDocument::UpdateReference(
                 ((rCxt.mnColDelta < 0 &&    // convention from ScDocument::DeleteCol()
                   rCxt.maRange.aStart.Col() == MAXCOLCOUNT && rCxt.maRange.aEnd.Col() == MAXCOLCOUNT) ||
                  (rCxt.mnRowDelta < 0 &&    // convention from ScDocument::DeleteRow()
-                  rCxt.maRange.aStart.Row() == MAXROWCOUNT && rCxt.maRange.aEnd.Row() == MAXROWCOUNT))))
+                  rCxt.maRange.aStart.Row() == GetSheetLimits().GetMaxRowCount() && rCxt.maRange.aEnd.Row() == GetSheetLimits().GetMaxRowCount()))))
         return;
 
     std::unique_ptr<sc::ExpandRefsSwitch> pExpandRefsSwitch;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 1b998a0da97b..f77f14ce9317 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1405,7 +1405,7 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
     while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
 
     sc::RefUpdateContext aCxt(*this);
-    const bool bLastRowIncluded = (nStartRow + nSize == MAXROWCOUNT && ValidRow(nStartRow));
+    const bool bLastRowIncluded = (static_cast<SCROW>(nStartRow + nSize) == GetSheetLimits().GetMaxRowCount() && ValidRow(nStartRow));
     if ( ValidRow(nStartRow+nSize) || bLastRowIncluded )
     {
         lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
@@ -1414,7 +1414,7 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
         if (bLastRowIncluded)
         {
             // Last row is included, shift a virtually non-existent row in.
-            aCxt.maRange = ScRange( nStartCol, MAXROWCOUNT, nTabRangeStart, nEndCol, MAXROWCOUNT, nTabRangeEnd);
+            aCxt.maRange = ScRange( nStartCol, GetSheetLimits().GetMaxRowCount(), nTabRangeStart, nEndCol, GetSheetLimits().GetMaxRowCount(), nTabRangeEnd);
         }
         else
         {
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 75571930fffb..ec528a502bfb 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -634,8 +634,8 @@ class CellStoreInitializer
         sc::CellTextAttrStoreType::iterator miPos;
         SvtScriptType mnScriptNumeric;
 
-        explicit Impl(const SvtScriptType nScriptNumeric)
-            : maAttrs(MAXROWCOUNT), miPos(maAttrs.begin()), mnScriptNumeric(nScriptNumeric)
+        explicit Impl(const ScSheetLimits& rSheetLimits, const SvtScriptType nScriptNumeric)
+            : maAttrs(rSheetLimits.GetMaxRowCount()), miPos(maAttrs.begin()), mnScriptNumeric(nScriptNumeric)
         {}
     };
 
@@ -648,7 +648,7 @@ public:
         mrDocImpl(rDocImpl),
         mnTab(nTab),
         mnCol(nCol),
-        mpImpl(std::make_shared<Impl>(mrDocImpl.mnDefaultScriptNumeric))
+        mpImpl(std::make_shared<Impl>(rDocImpl.mrDoc.GetSheetLimits(), mrDocImpl.mnDefaultScriptNumeric))
     {}
 
     std::shared_ptr<Impl> mpImpl;
diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx
index 9bbeafa1bbb4..0fbaa52bd57d 100644
--- a/sc/source/core/data/dpcache.cxx
+++ b/sc/source/core/data/dpcache.cxx
@@ -71,7 +71,7 @@ ScDPCache::Field::Field() : mnNumFormat(0) {}
 ScDPCache::ScDPCache(ScDocument* pDoc) :
     mpDoc( pDoc ),
     mnColumnCount ( 0 ),
-    maEmptyRows(0, MAXROWCOUNT, true),
+    maEmptyRows(0, pDoc->GetSheetLimits().GetMaxRowCount(), true),
     mnDataSize(-1),
     mnRowCount(0),
     mbDisposing(false)
@@ -303,8 +303,8 @@ struct InitColumnData
 
     SCCOL mnCol;
 
-    InitColumnData() :
-        maEmptyRows(0, MAXROWCOUNT, true),
+    InitColumnData(ScSheetLimits const & rSheetLimits) :
+        maEmptyRows(0, rSheetLimits.GetMaxRowCount(), true),
         mpStrPool(nullptr),
         mpField(nullptr),
         mnCol(-1) {}
@@ -553,7 +553,7 @@ void ScDPCache::InitFromDoc(ScDocument* pDoc, const ScRange& rRange)
     }
 
     maStringPools.resize(mnColumnCount);
-    std::vector<InitColumnData> aColData(mnColumnCount);
+    std::vector<InitColumnData> aColData(mnColumnCount, InitColumnData(pDoc->GetSheetLimits()));
     maFields.reserve(mnColumnCount);
     for (SCCOL i = 0; i < mnColumnCount; ++i)
         maFields.push_back(std::make_unique<Field>());
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 91b766f553c4..9d70e081b1ae 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -231,7 +231,7 @@ bool SetOptimalHeightsToRows(
 
 ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
                     bool bColInfo, bool bRowInfo ) :
-    aCol( INITIALCOLCOUNT ),
+    aCol( pDoc->GetSheetLimits(), INITIALCOLCOUNT ),
     aName( rNewName ),
     aCodeName( rNewName ),
     nLinkRefreshDelay( 0 ),
@@ -2617,7 +2617,7 @@ void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const
     // which is bad since that code is not thread-safe.
     SolarMutexGuard aGuard;
     const SCCOL aOldColSize = aCol.size();
-    aCol.resize( static_cast< size_t >( nScCol + 1 ) );
+    aCol.resize( pDocument->GetSheetLimits(), static_cast< size_t >( nScCol + 1 ) );
     for (SCCOL i = aOldColSize; i <= nScCol; i++)
         aCol[i].Init( i, nTab, pDocument, false );
 }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 0308ee3db818..d30499f305e1 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -544,13 +544,13 @@ struct SortedColumn
     SortedColumn(const SortedColumn&) = delete;
     const SortedColumn operator=(const SortedColumn&) = delete;
 
-    explicit SortedColumn( size_t nTopEmptyRows ) :
+    explicit SortedColumn( size_t nTopEmptyRows, const ScSheetLimits& rSheetLimits ) :
         maCells(nTopEmptyRows),
         maCellTextAttrs(nTopEmptyRows),
         maBroadcasters(nTopEmptyRows),
         maCellNotes(nTopEmptyRows),
         maCellDrawObjects(),
-        maPatterns(0, MAXROWCOUNT, nullptr),
+        maPatterns(0, rSheetLimits.GetMaxRowCount(), nullptr),
         miPatternPos(maPatterns.begin()) {}
 
     void setPattern( SCROW nRow, const ScPatternAttr* pPat )
@@ -568,9 +568,9 @@ struct SortedRowFlags
     FlagsType::const_iterator miPosHidden;
     FlagsType::const_iterator miPosFiltered;
 
-    SortedRowFlags() :
-        maRowsHidden(0, MAXROWCOUNT, false),
-        maRowsFiltered(0, MAXROWCOUNT, false),
+    SortedRowFlags(const ScSheetLimits& rSheetLimits) :
+        maRowsHidden(0, rSheetLimits.GetMaxRowCount(), false),
+        maRowsFiltered(0, rSheetLimits.GetMaxRowCount(), false),
         miPosHidden(maRowsHidden.begin()),
         miPosFiltered(maRowsFiltered.begin()) {}
 
@@ -681,14 +681,14 @@ void fillSortedColumnArray(
 
     size_t nColCount = nCol2 - nCol1 + 1;
     std::vector<std::unique_ptr<SortedColumn>> aSortedCols; // storage for copied cells.
-    SortedRowFlags aRowFlags;
+    SortedRowFlags aRowFlags(pTable->GetDoc().GetSheetLimits());
     aSortedCols.reserve(nColCount);
     for (size_t i = 0; i < nColCount; ++i)
     {
         // In the sorted column container, element positions and row
         // positions must match, else formula cells may mis-behave during
         // grouping.
-        aSortedCols.push_back(std::make_unique<SortedColumn>(nRow1));
+        aSortedCols.push_back(std::make_unique<SortedColumn>(nRow1, pTable->GetDoc().GetSheetLimits()));
     }
 
     for (size_t i = 0; i < pRows->size(); ++i)
@@ -1065,7 +1065,7 @@ void ScTable::SortReorderByRow(
     // Cells in the data rows only reference values in the document. Make
     // a copy before updating the document.
     std::vector<std::unique_ptr<SortedColumn>> aSortedCols; // storage for copied cells.
-    SortedRowFlags aRowFlags;
+    SortedRowFlags aRowFlags(GetDoc().GetSheetLimits());
     fillSortedColumnArray(aSortedCols, aRowFlags, aCellListeners, pArray, nTab, nCol1, nCol2, pProgress, this);
 
     for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
@@ -1250,7 +1250,7 @@ void ScTable::SortReorderByRowRefUpdate(
     // Cells in the data rows only reference values in the document. Make
     // a copy before updating the document.
     std::vector<std::unique_ptr<SortedColumn>> aSortedCols; // storage for copied cells.
-    SortedRowFlags aRowFlags;
+    SortedRowFlags aRowFlags(GetDoc().GetSheetLimits());
     std::vector<SvtListener*> aListenersDummy;
     fillSortedColumnArray(aSortedCols, aRowFlags, aListenersDummy, pArray, nTab, nCol1, nCol2, pProgress, this);
 
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index 0605fa5683a4..00b856b4f14b 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -800,7 +800,7 @@ bool ScTable::SearchAndReplace(
     if ( ValidColRow(rCol, rRow) ||
          ((nCommand == SvxSearchCmd::FIND || nCommand == SvxSearchCmd::REPLACE) &&
            (((rCol == MAXCOLCOUNT || rCol == -1) && ValidRow(rRow)) ||
-            ((rRow == MAXROWCOUNT || rRow == -1) && ValidCol(rCol))
+            ((rRow == GetDoc().GetSheetLimits().GetMaxRowCount() || rRow == -1) && ValidCol(rCol))
            )
          )
        )
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
index bf972af37ef6..adc371c813c6 100644
--- a/sc/source/core/inc/bcaslot.hxx
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -263,7 +263,7 @@ private:
     class TableSlots
     {
     public:
-                                        TableSlots();
+                                        TableSlots(SCSIZE nBcaSlots);
                                         ~TableSlots();
         ScBroadcastAreaSlot**    getSlots() { return ppSlots.get(); }
 
@@ -275,6 +275,7 @@ private:
         ScBroadcastAreaSlot*     getAreaSlot( SCSIZE nOff ) { return ppSlots[nOff]; }
 
     private:
+        SCSIZE                                    mnBcaSlots;
         std::unique_ptr<ScBroadcastAreaSlot*[]>   ppSlots;
 
         TableSlots( const TableSlots& ) = delete;
@@ -286,6 +287,19 @@ private:
     typedef ::std::vector< ::std::pair< ScBroadcastAreaSlot*, ScBroadcastAreas::iterator > > AreasToBeErased;
 
 private:
+    struct ScSlotData
+    {
+        SCROW  nStartRow;   // first row of this segment
+        SCROW  nStopRow;    // first row of next segment
+        SCSIZE nSlice;      // slice size in this segment
+        SCSIZE nCumulated;  // cumulated slots of previous segments
+
+        ScSlotData( SCROW r1, SCROW r2, SCSIZE s, SCSIZE c ) : nStartRow(r1), nStopRow(r2), nSlice(s), nCumulated(c) {}
+    };
+    typedef ::std::vector< ScSlotData > ScSlotDistribution;
+    ScSlotDistribution maSlotDistribution;
+    SCSIZE mnBcaSlotsRow;
+    SCSIZE mnBcaSlots;
     ScBroadcastAreasBulk  aBulkBroadcastAreas;
     BulkGroupAreasType m_BulkGroupAreas;
     TableSlotsMap         aTableSlotsMap;
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index be7beec97d83..39bae2ea485c 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -702,6 +702,7 @@ static const sal_Unicode* lcl_r1c1_get_col( const sal_Unicode* p,
 }
 
 static const sal_Unicode* lcl_r1c1_get_row(
+                                    const ScSheetLimits& rSheetLimits,
                                     const sal_Unicode* p,
                                     const ScAddress::Details& rDetails,
                                     ScAddress* pAddr, ScRefFlags* nFlags )
@@ -740,7 +741,7 @@ static const sal_Unicode* lcl_r1c1_get_row(
         n--;
     }
 
-    if( n < 0 || n >= MAXROWCOUNT )
+    if( n < 0 || n >= rSheetLimits.GetMaxRowCount() )
         return nullptr;
     pAddr->SetRow( static_cast<SCROW>( n ) );
     *nFlags |= ScRefFlags::ROW_VALID;
@@ -784,13 +785,13 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
 
     if( *p == 'R' || *p == 'r' )
     {
-        if( nullptr == (p = lcl_r1c1_get_row( p, rDetails, &r.aStart, &nFlags )) )
+        if( nullptr == (p = lcl_r1c1_get_row( pDoc->GetSheetLimits(), p, rDetails, &r.aStart, &nFlags )) )
             return nBailOutFlags;
 
         if( *p != 'C' && *p != 'c' )    // full row R#
         {
             if( p[0] != ':' || (p[1] != 'R' && p[1] != 'r' ) ||
-                nullptr == (pTmp = lcl_r1c1_get_row( p+1, rDetails, &r.aEnd, &nFlags2 )))
+                nullptr == (pTmp = lcl_r1c1_get_row( pDoc->GetSheetLimits(), p+1, rDetails, &r.aEnd, &nFlags2 )))
             {
                 // Only the initial row number is given, or the second row
                 // number is invalid. Fallback to just the initial R
@@ -827,7 +828,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
 
         if( p[0] != ':' ||
             (p[1] != 'R' && p[1] != 'r') ||
-            nullptr == (pTmp = lcl_r1c1_get_row( p+1, rDetails, &r.aEnd, &nFlags2 )) ||
+            nullptr == (pTmp = lcl_r1c1_get_row( pDoc->GetSheetLimits(), p+1, rDetails, &r.aEnd, &nFlags2 )) ||
             (*pTmp != 'C' && *pTmp != 'c') ||
             nullptr == (pTmp = lcl_r1c1_get_col( pTmp, rDetails, &r.aEnd, &nFlags2 )))
         {
@@ -1874,13 +1875,13 @@ void ScRange::ParseRows( const ScDocument* pDoc,
 
     case formula::FormulaGrammar::CONV_XL_R1C1:
         if ((p[0] == 'R' || p[0] == 'r') &&
-            nullptr != (p = lcl_r1c1_get_row( p, rDetails, &aStart, &ignored )))
+            nullptr != (p = lcl_r1c1_get_row( pDoc->GetSheetLimits(), p, rDetails, &aStart, &ignored )))
         {
             if( p[0] == ':')
             {
                 if( p[1] == 'R' || p[1] == 'r' )
                 {
-                    lcl_r1c1_get_row( p+1, rDetails, &aEnd, &ignored );
+                    lcl_r1c1_get_row( pDoc->GetSheetLimits(), p+1, rDetails, &aEnd, &ignored );
                 }
             }
             else
diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx
index ca79af8606d6..fcd282c243eb 100644
--- a/sc/source/core/tool/chgtrack.cxx
+++ b/sc/source/core/tool/chgtrack.cxx
@@ -1888,9 +1888,9 @@ void ScChangeActionContent::UpdateReference( const ScChangeTrack* pTrack,
         UpdateRefMode eMode, const ScBigRange& rRange,
         sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz )
 {
-    SCSIZE nOldSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() );
+    SCSIZE nOldSlot = pTrack->ComputeContentSlot( aBigRange.aStart.Row() );
     ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aBigRange );
-    SCSIZE nNewSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() );
+    SCSIZE nNewSlot = pTrack->ComputeContentSlot( aBigRange.aStart.Row() );
     if ( nNewSlot != nOldSlot )
     {
         RemoveFromSlot();
@@ -2036,15 +2036,18 @@ bool ScChangeActionReject::Reject(ScDocument* /*pDoc*/)
     return false;
 }
 
-const SCROW ScChangeTrack::nContentRowsPerSlot = InitContentRowsPerSlot();
-const SCSIZE ScChangeTrack::nContentSlots =
-    MAXROWCOUNT / InitContentRowsPerSlot() + 2;
+SCSIZE ScChangeTrack::ComputeContentSlot( sal_Int32 nRow ) const
+{
+    if ( nRow < 0 || nRow > pDoc->GetSheetLimits().mnMaxRow )
+        return mnContentSlots - 1;
+    return static_cast< SCSIZE >( nRow / mnContentRowsPerSlot );
+}
 
 SCROW ScChangeTrack::InitContentRowsPerSlot()
 {
     const SCSIZE nMaxSlots = 0xffe0 / sizeof( ScChangeActionContent* ) - 2;
-    SCROW nRowsPerSlot = MAXROWCOUNT / nMaxSlots;
-    if ( nRowsPerSlot * nMaxSlots < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
+    SCROW nRowsPerSlot = pDoc->GetSheetLimits().GetMaxRowCount() / nMaxSlots;
+    if ( nRowsPerSlot * nMaxSlots < sal::static_int_cast<SCSIZE>(pDoc->GetSheetLimits().GetMaxRowCount()) )
         ++nRowsPerSlot;
     return nRowsPerSlot;
 }
@@ -2056,8 +2059,8 @@ ScChangeTrack::ScChangeTrack( ScDocument* pDocP ) :
     Init();
     SC_MOD()->GetUserOptions().AddListener(this);
 
-    ppContentSlots.reset( new ScChangeActionContent* [ nContentSlots ] );
-    memset( ppContentSlots.get(), 0, nContentSlots * sizeof( ScChangeActionContent* ) );
+    ppContentSlots.reset( new ScChangeActionContent* [ mnContentSlots ] );
+    memset( ppContentSlots.get(), 0, mnContentSlots * sizeof( ScChangeActionContent* ) );
 }
 
 ScChangeTrack::ScChangeTrack( ScDocument* pDocP, const std::set<OUString>& aTempUserCollection) :
@@ -2067,8 +2070,8 @@ ScChangeTrack::ScChangeTrack( ScDocument* pDocP, const std::set<OUString>& aTemp
 {
     Init();
     SC_MOD()->GetUserOptions().AddListener(this);
-    ppContentSlots.reset( new ScChangeActionContent* [ nContentSlots ] );
-    memset( ppContentSlots.get(), 0, nContentSlots * sizeof( ScChangeActionContent* ) );
+    ppContentSlots.reset( new ScChangeActionContent* [ mnContentSlots ] );
+    memset( ppContentSlots.get(), 0, mnContentSlots * sizeof( ScChangeActionContent* ) );
 }
 
 ScChangeTrack::~ScChangeTrack()
@@ -2079,6 +2082,9 @@ ScChangeTrack::~ScChangeTrack()
 
 void ScChangeTrack::Init()
 {
+    mnContentRowsPerSlot = InitContentRowsPerSlot();
+    mnContentSlots = pDoc->GetSheetLimits().GetMaxRowCount() / InitContentRowsPerSlot() + 2;
+
     pFirst = nullptr;
     pLast = nullptr;
     pFirstGeneratedDelContent = nullptr;
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index c558f97fbe80..0c4bbe9f2ed7 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -46,7 +46,10 @@ using namespace formula;
 
 /// Two columns of data should be sortable with GetSortArray() and QuickSort()
 // This is an arbitrary limit.
-#define MAX_COUNT_DOUBLE_FOR_SORT (MAXROWCOUNT * 2)
+static size_t MAX_COUNT_DOUBLE_FOR_SORT(const ScSheetLimits& rSheetLimits)
+{
+    return rSheetLimits.GetMaxRowCount() * 2;
+}
 
 const double ScInterpreter::fMaxGammaArgument = 171.624376956302;  // found experimental
 const double fMachEps = ::std::numeric_limits<double>::epsilon();
@@ -4125,7 +4128,7 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double
 void ScInterpreter::GetSortArray( sal_uInt8 nParamCount, vector<double>& rSortArray, vector<long>* pIndexOrder, bool bConvertTextInArray, bool bAllowEmptyArray )
 {
     GetNumberSequenceArray( nParamCount, rSortArray, bConvertTextInArray );
-    if (rSortArray.size() > MAX_COUNT_DOUBLE_FOR_SORT)
+    if (rSortArray.size() > MAX_COUNT_DOUBLE_FOR_SORT(pDok->GetSheetLimits()))
         SetError( FormulaError::MatrixSize);
     else if ( rSortArray.empty() )
     {
diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx
index e325c73e61e9..755e1d355b2f 100644
--- a/sc/source/filter/excel/colrowst.cxx
+++ b/sc/source/filter/excel/colrowst.cxx
@@ -30,9 +30,9 @@ XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) :
     XclImpRoot( rRoot ),
     maColWidths(0, MAXCOLCOUNT, 0),
     maColFlags(0, MAXCOLCOUNT, ExcColRowFlags::NONE),
-    maRowHeights(0, MAXROWCOUNT, 0),
-    maRowFlags(0, MAXROWCOUNT, ExcColRowFlags::NONE),
-    maHiddenRows(0, MAXROWCOUNT, false),
+    maRowHeights(0, rRoot.GetDoc().GetSheetLimits().GetMaxRowCount(), 0),
+    maRowFlags(0, rRoot.GetDoc().GetSheetLimits().GetMaxRowCount(), ExcColRowFlags::NONE),
+    maHiddenRows(0, rRoot.GetDoc().GetSheetLimits().GetMaxRowCount(), false),
     mnLastScRow( -1 ),
     mnDefWidth( STD_COL_WIDTH ),
     mnDefHeight( ScGlobal::nStdRowHeight ),
@@ -301,7 +301,7 @@ void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
         if (!maHiddenRows.search(nLastXLRow, bHidden).second)
             return;
 
-        maHiddenRows.insert_back(nLastXLRow, MAXROWCOUNT, bHidden);
+        maHiddenRows.insert_back(nLastXLRow, GetDoc().GetSheetLimits().GetMaxRowCount(), bHidden);
     }
 
     SCROW nPrevRow = -1;
diff --git a/sc/source/filter/lotus/lotattr.cxx b/sc/source/filter/lotus/lotattr.cxx
index 8082d4cbcca1..7e1af1fcfff6 100644
--- a/sc/source/filter/lotus/lotattr.cxx
+++ b/sc/source/filter/lotus/lotattr.cxx
@@ -182,7 +182,7 @@ const Color& LotAttrCache::GetColor( const sal_uInt8 nLotIndex ) const
 
 void LotAttrCol::SetAttr( const ScDocument* pDoc, const SCROW nRow, const ScPatternAttr& rAttr )
 {
-    // Actually with the current implementation of MAXROWCOUNT>=64k and nRow
+    // Actually with the current implementation of MAXROWCOUNT1>=64k and nRow
     // being read as sal_uInt16 there's no chance that nRow would be invalid...
     SAL_WARN_IF( !pDoc->ValidRow(nRow), "sc.filter", "*LotAttrCol::SetAttr(): ... and failed?!" );
 
diff --git a/sc/source/filter/xml/xmlrowi.cxx b/sc/source/filter/xml/xmlrowi.cxx
index d02ff5507fb9..7b37b066e5d5 100644
--- a/sc/source/filter/xml/xmlrowi.cxx
+++ b/sc/source/filter/xml/xmlrowi.cxx
@@ -70,7 +70,7 @@ ScXMLTableRowContext::ScXMLTableRowContext( ScXMLImport& rImport,
                 case XML_ELEMENT( TABLE, XML_NUMBER_ROWS_REPEATED ):
                 {
                     nRepeatedRows = std::max( it.toInt32(), sal_Int32(1) );
-                    nRepeatedRows = std::min( nRepeatedRows, MAXROWCOUNT );
+                    nRepeatedRows = std::min( nRepeatedRows, rImport.GetDocument()->GetSheetLimits().GetMaxRowCount() );
                 }
                 break;
                 case XML_ELEMENT( TABLE, XML_DEFAULT_CELL_STYLE_NAME ):
diff --git a/sc/source/ui/navipi/navipi.cxx b/sc/source/ui/navipi/navipi.cxx
index c7edef768b2e..1074fa8eff08 100644
--- a/sc/source/ui/navipi/navipi.cxx
+++ b/sc/source/ui/navipi/navipi.cxx
@@ -53,7 +53,10 @@ using namespace com::sun::star;
 // precomputed constant because it is used in every change of spin button field
 const sal_Int32 SCNAV_COLLETTERS = ::ScColToAlpha(SCNAV_MAXCOL).getLength();    // A...IV...ZZZ
 
-#define SCNAV_MAXROW        (MAXROWCOUNT)
+static SCROW SCNAV_MAXROW(const ScSheetLimits& rSheetLimits)
+{
+    return rSheetLimits.GetMaxRowCount();
+}
 
 void ScNavigatorDlg::ReleaseFocus()
 {
@@ -339,7 +342,9 @@ ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, vcl::Window* pParent)
 {
     set_id("NavigatorPanelParent"); // for uitests
 
-    m_xEdRow->set_range(1, SCNAV_MAXROW);
+    GetViewData();
+    ScDocument* pDoc = pViewData->GetDocument();
+    m_xEdRow->set_range(1, SCNAV_MAXROW(pDoc->GetSheetLimits()));
     m_xEdRow->set_width_chars(5);
     //max rows is 1,000,000, which is too long for typical use
     m_xEdRow->connect_activate(LINK(this, ScNavigatorDlg, ExecuteRowHdl));
diff --git a/sc/source/ui/pagedlg/areasdlg.cxx b/sc/source/ui/pagedlg/areasdlg.cxx
index 9726b70c4316..ef0a300b20aa 100644
--- a/sc/source/ui/pagedlg/areasdlg.cxx
+++ b/sc/source/ui/pagedlg/areasdlg.cxx
@@ -607,7 +607,7 @@ static bool lcl_CheckOne_OOO( const ScDocument& rDoc, const OUString& rStr, bool
             {
                 sal_Int32 n = aStr.toInt32();
 
-                bStrOk = (n > 0) && ( n <= MAXROWCOUNT );
+                bStrOk = (n > 0) && ( n <= rDoc.GetSheetLimits().GetMaxRowCount() );
                 if ( bStrOk )
                     nNum = static_cast<SCCOLROW>(n - 1);
             }
@@ -632,7 +632,7 @@ static bool lcl_CheckOne_XL_A1( const ScDocument& rDoc, const OUString& rStr, bo
     return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal);
 }
 
-static bool lcl_CheckOne_XL_R1C1( const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
+static bool lcl_CheckOne_XL_R1C1( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal )
 {
     sal_Int32 nLen = rStr.getLength();
     if (nLen <= 1)
@@ -653,7 +653,7 @@ static bool lcl_CheckOne_XL_R1C1( const OUString& rStr, bool bIsRow, SCCOLROW& r
     if (nNum <= 0)
         return false;
 
-    if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT))
+    if ((bIsRow && nNum > rDoc.GetSheetLimits().GetMaxRowCount()) || (!bIsRow && nNum > MAXCOLCOUNT))
         return false;
 
     rVal = static_cast<SCCOLROW>(nNum-1);
@@ -669,7 +669,7 @@ static bool lcl_CheckRepeatOne( const ScDocument& rDoc, const OUString& rStr, fo
         case formula::FormulaGrammar::CONV_XL_A1:
             return lcl_CheckOne_XL_A1(rDoc, rStr, bIsRow, rVal);
         case formula::FormulaGrammar::CONV_XL_R1C1:
-            return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal);
+            return lcl_CheckOne_XL_R1C1(rDoc, rStr, bIsRow, rVal);
         default:
         {
             // added to avoid warnings
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index ad8a7f0ea6c4..0d271511c7d7 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -1061,7 +1061,7 @@ bool lcl_addUpperLeftCornerIfMissing(const ScDocument* pDoc, vector<ScTokenRef>&
         return false;
 
     SCCOL nMinCol = MAXCOLCOUNT;
-    SCROW nMinRow = MAXROWCOUNT;
+    SCROW nMinRow = pDoc->GetSheetLimits().GetMaxRowCount();
     SCCOL nMaxCol = 0;
     SCROW nMaxRow = 0;
     SCTAB nTab    = 0;
@@ -1207,8 +1207,8 @@ bool lcl_addUpperLeftCornerIfMissing(const ScDocument* pDoc, vector<ScTokenRef>&
     }
 
     if (nMinRow >= nMaxRow || nMinCol >= nMaxCol ||
-        nMinRow >= MAXROWCOUNT || nMinCol >= MAXCOLCOUNT ||
-        nMaxRow >= MAXROWCOUNT || nMaxCol >= MAXCOLCOUNT)
+        nMinRow >= pDoc->GetSheetLimits().GetMaxRowCount() || nMinCol >= MAXCOLCOUNT ||
+        nMaxRow >= pDoc->GetSheetLimits().GetMaxRowCount() || nMaxCol >= MAXCOLCOUNT)
     {
         // Invalid range.  Bail out.
         return false;
diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx
index 7725567f42e6..2a72d61bd1cf 100644
--- a/sc/source/ui/unoobj/funcuno.cxx
+++ b/sc/source/ui/unoobj/funcuno.cxx
@@ -561,7 +561,7 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const OUString& aName,
                     long nColCount = rSrcRange.aEnd.Col() - rSrcRange.aStart.Col() + 1;
                     long nRowCount = rSrcRange.aEnd.Row() - rSrcRange.aStart.Row() + 1;
 
-                    if ( nStartRow + nRowCount > MAXROWCOUNT )
+                    if ( nStartRow + nRowCount > pDoc->GetSheetLimits().GetMaxRowCount() )
                         bOverflow = true;
                     else
                     {
@@ -589,7 +589,7 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const OUString& aName,
     //  execute formula
 
     uno::Any aRet;
-    if ( !bArgErr && !bOverflow && nDocRow <= MAXROWCOUNT )
+    if ( !bArgErr && !bOverflow && nDocRow <= pDoc->GetSheetLimits().GetMaxRowCount() )
     {
         ScAddress aFormulaPos( 0, 0, nTempSheet );
         // GRAM_API doesn't really matter for the token array but fits with
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 930a9927457c..69fadf2f61f7 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -1276,7 +1276,7 @@ bool ScViewData::SelectionFillDOOM( const ScRange& rRange )
     // arbitrarily increased.
     // We could refine this and take some actual cell size into account,
     // evaluate available memory and what not, but...
-    const sal_Int32 kMax = 23 * 1024 * 1024;    // current MAXROWCOUNT is 1024*1024=1048576
+    const sal_Int32 kMax = 23 * 1024 * 1024;    // current MAXROWCOUNT1 is 1024*1024=1048576
     return (rRange.aEnd.Row() - rRange.aStart.Row() + 1) > (kMax / (rRange.aEnd.Col() - rRange.aStart.Col() + 1));
 }
 


More information about the Libreoffice-commits mailing list