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

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Fri Apr 5 11:44:23 UTC 2019


 sc/inc/address.hxx                    |    1 
 sc/inc/colcontainer.hxx               |    6 +-
 sc/inc/dociter.hxx                    |    8 +--
 sc/inc/document.hxx                   |    2 
 sc/inc/table.hxx                      |   17 ++++---
 sc/source/core/data/columnspanset.cxx |   16 +++---
 sc/source/core/data/dociter.cxx       |   19 ++++++--
 sc/source/core/data/documen3.cxx      |    5 ++
 sc/source/core/data/documen8.cxx      |    3 +
 sc/source/core/data/document.cxx      |    9 +++
 sc/source/core/data/fillinfo.cxx      |    2 
 sc/source/core/data/table1.cxx        |   44 +++++++++---------
 sc/source/core/data/table2.cxx        |   79 ++++++++++++++++++++--------------
 sc/source/core/data/table3.cxx        |    7 +--
 sc/source/core/data/table4.cxx        |    2 
 sc/source/core/data/table5.cxx        |    5 +-
 sc/source/core/data/table7.cxx        |   10 +---
 sc/source/ui/dbgui/tpsort.cxx         |    2 
 18 files changed, 146 insertions(+), 91 deletions(-)

New commits:
commit 7282014e362a1529a36c88eb308df8ed359c2cfa
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Fri Feb 1 15:15:16 2019 +0100
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri Apr 5 13:43:52 2019 +0200

    tdf#50916 Makes numbers of columns dynamic.
    
    With this commit we are making numbers of columns
    dynamic, but the number of maximum supported
    columns will be the same (1024).
    Such approach will allow us to check issues
    (eg. performance, LO format etc.), and improve it.
    
    Increasing number of maximum columns, will be done
    in separate commit.
    
    Change-Id: Ibac4101e9ffc05e3548eca1c198f6319ac7ff9aa
    Reviewed-on: https://gerrit.libreoffice.org/44802
    Tested-by: Jenkins
    Reviewed-by: Bartosz Kosiorek <gang65 at poczta.onet.pl>

diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 766135d614f9..e04e0d50f5d9 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -67,6 +67,7 @@ const SCSIZE   SCSIZE_MAX   = ::std::numeric_limits<SCSIZE>::max();
 // Count values
 const SCROW       MAXROWCOUNT    = MAXROWCOUNT_DEFINE;
 const SCCOL       MAXCOLCOUNT    = MAXCOLCOUNT_DEFINE;
+const SCCOL       INITIALCOLCOUNT = 64;
 /// limiting to 10000 for now, problem with 32 bit builds for now
 const SCTAB       MAXTABCOUNT    = 10000;
 const SCCOLROW    MAXCOLROWCOUNT = MAXROWCOUNT;
diff --git a/sc/inc/colcontainer.hxx b/sc/inc/colcontainer.hxx
index e6dbf0e22731..c7b72e082a96 100644
--- a/sc/inc/colcontainer.hxx
+++ b/sc/inc/colcontainer.hxx
@@ -28,10 +28,9 @@
 
 class ScColContainer
 {
+public:
     typedef std::vector<std::unique_ptr<ScColumn>> ScColumnVector;
-    ScColumnVector    aCols;
 
-public:
     ScColContainer( const size_t nSize );
     ~ScColContainer() COVERITY_NOEXCEPT_FALSE;
 
@@ -73,6 +72,9 @@ public:
 
     ScColumnVector::const_iterator begin() const { return aCols.begin(); }
     ScColumnVector::const_iterator end() const { return aCols.end(); }
+
+private:
+    ScColumnVector    aCols;
 };
 
 
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index 5bb957059b03..8604abcdd453 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -370,7 +370,7 @@ class ScDocAttrIterator             // all attribute areas
 private:
     ScDocument*     pDoc;
     SCTAB           nTab;
-    SCCOL const     nEndCol;
+    SCCOL           nEndCol;
     SCROW const     nStartRow;
     SCROW const     nEndRow;
     SCCOL           nCol;
@@ -391,7 +391,7 @@ class ScAttrRectIterator            // all attribute areas, including areas stre
 private:
     ScDocument*     pDoc;
     SCTAB           nTab;
-    SCCOL const     nEndCol;
+    SCCOL           nEndCol;
     SCROW const     nStartRow;
     SCROW const     nEndRow;
     SCCOL           nIterStartCol;
@@ -423,7 +423,7 @@ class ScHorizontalCellIterator      // walk through all non empty cells in an ar
     ScDocument*     pDoc;
     SCTAB           mnTab;
     SCCOL const           nStartCol;
-    SCCOL const           nEndCol;
+    SCCOL                 nEndCol;
     SCROW const           nStartRow;
     SCROW const           nEndRow;
     SCCOL           mnCol;
@@ -482,7 +482,7 @@ private:
     SCTAB                   nTab;
     SCCOL const             nStartCol;
     SCROW const             nStartRow;
-    SCCOL const             nEndCol;
+    SCCOL                   nEndCol;
     SCROW const             nEndRow;
 
     std::unique_ptr<SCROW[]>  pNextEnd;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index c587229c6ce6..7d050666f19f 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -786,6 +786,8 @@ public:
     ScRangePairListRef& GetColNameRangesRef() { return xColNameRanges; }
     ScRangePairListRef& GetRowNameRangesRef() { return xRowNameRanges; }
 
+    SC_DLLPUBLIC SCCOL ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const;
+
     SC_DLLPUBLIC ScDBCollection* GetDBCollection() const { return pDBCollection.get();}
     void                         SetDBCollection( std::unique_ptr<ScDBCollection> pNewDBCollection,
                                                   bool bRemoveAutoFilter = false );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index a4dd113a0cd9..e9b1e3f54c65 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -20,6 +20,7 @@
 #ifndef INCLUDED_SC_INC_TABLE_HXX
 #define INCLUDED_SC_INC_TABLE_HXX
 
+#include <algorithm>
 #include <vector>
 #include <tools/gen.hxx>
 #include <tools/color.hxx>
@@ -151,7 +152,7 @@ class ScTable
 private:
     typedef ::std::vector< ScRange > ScRangeVec;
 
-    ScColContainer  aCol;
+    mutable ScColContainer aCol;
 
     OUString aName;
     OUString aCodeName;
@@ -273,14 +274,14 @@ public:
 
     ScOutlineTable* GetOutlineTable()               { return pOutlineTable.get(); }
 
-    ScColumn& CreateColumnIfNotExists( const SCCOL nScCol )
+    ScColumn& CreateColumnIfNotExists( const SCCOL nScCol ) const
     {
         if ( nScCol >= aCol.size() )
             CreateColumnIfNotExistsImpl(nScCol);
         return aCol[nScCol];
     }
     // out-of-line the cold part of the function
-    void CreateColumnIfNotExistsImpl( const SCCOL nScCol );
+    void CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const;
     sal_uLong       GetCellCount() const;
     sal_uLong       GetWeightedCount() const;
     sal_uLong       GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const;
@@ -443,9 +444,11 @@ public:
 
     CellType    GetCellType( const ScAddress& rPos ) const
                     {
-                        return ValidColRow(rPos.Col(),rPos.Row()) ?
-                            aCol[rPos.Col()].GetCellType( rPos.Row() ) :
-                            CELLTYPE_NONE;
+                        if (!ValidColRow(rPos.Col(),rPos.Row()))
+                            return CELLTYPE_NONE;
+                        if (rPos.Col() >= aCol.size())
+                            return CELLTYPE_NONE;
+                        return aCol[rPos.Col()].GetCellType( rPos.Row() );
                     }
     CellType    GetCellType( SCCOL nCol, SCROW nRow ) const;
     ScRefCellValue GetCellValue( SCCOL nCol, SCROW nRow ) const;
@@ -1072,6 +1075,8 @@ public:
     static void UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow );
 
     ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const;
+    SCCOL ClampToAllocatedColumns(SCCOL nCol) const { return std::min(nCol, static_cast<SCCOL>(aCol.size() - 1)); }
+    SCCOL GetAllocatedColumnsCount() const { return aCol.size(); }
 
 private:
 
diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx
index 1098ce30447e..89805a7824df 100644
--- a/sc/source/core/data/columnspanset.cxx
+++ b/sc/source/core/data/columnspanset.cxx
@@ -131,6 +131,7 @@ void ColumnSpanSet::scan(
     if (!pTab)
         return;
 
+    nCol2 = pTab->ClampToAllocatedColumns(nCol2);
     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
     {
         ColumnType& rCol = getColumn(nTab, nCol);
@@ -181,7 +182,7 @@ void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) cons
             continue;
 
         const TableType& rTab = *maTables[nTab];
-        for (size_t nCol = 0; nCol < rTab.size(); ++nCol)
+        for (SCCOL nCol = 0; nCol < static_cast<SCCOL>(rTab.size()); ++nCol)
         {
             if (!rTab[nCol])
                 continue;
@@ -190,7 +191,7 @@ void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) cons
             if (!pTab)
                 continue;
 
-            if (!ValidCol(nCol))
+            if (!ValidCol(nCol) || nCol >= pTab->GetAllocatedColumnsCount())
             {
                 // End the loop.
                 nCol = rTab.size();
@@ -357,12 +358,13 @@ void RangeColumnSpanSet::executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet
 {
     for (SCTAB nTab = range.aStart.Tab(); nTab <= range.aEnd.Tab(); ++nTab)
     {
-        for (SCCOL nCol = range.aStart.Col(); nCol <= range.aEnd.Col(); ++nCol)
-        {
-            ScTable* pTab = rDoc.FetchTable(nTab);
-            if (!pTab)
-                continue;
+        ScTable* pTab = rDoc.FetchTable(nTab);
+        if (!pTab)
+            continue;
 
+        SCCOL nEndCol = pTab->ClampToAllocatedColumns(range.aEnd.Col());
+        for (SCCOL nCol = range.aStart.Col(); nCol <= nEndCol; ++nCol)
+        {
             if (!ValidCol(nCol))
                 break;
 
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 6cd02b5c4a6e..174ff54c43e8 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -166,7 +166,7 @@ bool ScValueIterator::GetThis(double& rValue, FormulaError& rErr)
             do
             {
                 ++mnCol;
-                if (mnCol > maEndPos.Col())
+                if (mnCol > maEndPos.Col() || mnCol >= pDoc->maTabs[mnTab]->GetAllocatedColumnsCount())
                 {
                     mnCol = maStartPos.Col();
                     ++mnTab;
@@ -829,6 +829,7 @@ ScCellIterator::ScCellIterator( ScDocument* pDoc, const ScRange& rRange, Subtota
     maEndPos(rRange.aEnd),
     mnSubTotalFlags(nSubTotalFlags)
 {
+    maEndPos.SetCol( pDoc->ClampToAllocatedColumns(maStartPos.Tab(), maEndPos.Col()) );
     init();
 }
 
@@ -1922,7 +1923,9 @@ ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB
     if (mnTab >= pDoc->GetTableCount())
         OSL_FAIL("try to access index out of bounds, FIX IT");
 
-    maColPositions.reserve( nCol2-nCol1+1 );
+    nEndCol = pDoc->maTabs[mnTab]->ClampToAllocatedColumns(nEndCol);
+
+    maColPositions.reserve( nEndCol-nStartCol+1 );
 
     SetTab( mnTab );
 }
@@ -2233,6 +2236,8 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB
         OSL_FAIL("try to access index out of bounds, FIX IT");
     OSL_ENSURE( pDoc->maTabs[nTab], "Table does not exist" );
 
+    nEndCol = pDoc->maTabs[nTab]->ClampToAllocatedColumns(nEndCol);
+
     nRow = nStartRow;
     nCol = nStartCol;
     bRowEmpty = false;
@@ -2482,8 +2487,12 @@ ScDocAttrIterator::ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
     nEndRow( nRow2 ),
     nCol( nCol1 )
 {
-    if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] )
+    if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab]
+        && nCol < pDoc->maTabs[nTab]->GetAllocatedColumnsCount())
+    {
+        nEndCol = pDoc->maTabs[nTab]->ClampToAllocatedColumns(nEndCol);
         pColIter = pDoc->maTabs[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
+    }
 }
 
 ScDocAttrIterator::~ScDocAttrIterator()
@@ -2610,8 +2619,10 @@ ScAttrRectIterator::ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
     nIterStartCol( nCol1 ),
     nIterEndCol( nCol1 )
 {
-    if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab] )
+    if ( ValidTab(nTab) && nTab < pDoc->GetTableCount() && pDoc->maTabs[nTab]
+        && nCol1 < pDoc->maTabs[nTab]->GetAllocatedColumnsCount())
     {
+        nEndCol = pDoc->maTabs[nTab]->ClampToAllocatedColumns(nEndCol);
         pColIter = pDoc->maTabs[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
         while ( nIterEndCol < nEndCol &&
                 pDoc->maTabs[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index a0c0bcd0f040..75f1cdab071a 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -2098,4 +2098,9 @@ void ScDocument::SetSortParam( const ScSortParam& rParam, SCTAB nTab )
     mSheetSortParams[ nTab ] = rParam;
 }
 
+SCCOL ScDocument::ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const
+{
+    return maTabs[nTab]->ClampToAllocatedColumns(nCol);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index c90353bc207b..af0100f6dde4 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -578,6 +578,7 @@ bool ScDocument::IdleCalcTextWidth()            // true = try next again
     sal_uInt16 nZoom = getScaleValue(*pStyle, ATTR_PAGE_SCALE);
     Fraction aZoomFract(nZoom, 100);
 
+    aScope.setCol(pTab->ClampToAllocatedColumns(aScope.Col()));
     // Start at specified cell position (nCol, nRow, nTab).
     ScColumn* pCol  = &pTab->aCol[aScope.Col()];
     std::unique_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
@@ -646,6 +647,8 @@ bool ScDocument::IdleCalcTextWidth()            // true = try next again
                 bNewTab = true;
             }
 
+            aScope.setCol(pTab->ClampToAllocatedColumns(aScope.Col()));
+
             if ( nRestart < 2 )
             {
                 if ( bNewTab )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 7538690cf625..a3df4639e94b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -4720,7 +4720,8 @@ void ScDocument::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, S
 
 const SfxPoolItem* ScDocument::GetAttr( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich ) const
 {
-    if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
+    if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] &&
+         nCol < maTabs[nTab]->GetAllocatedColumnsCount())
     {
         const SfxPoolItem* pTemp = maTabs[nTab]->GetAttr( nCol, nRow, nWhich );
         if (pTemp)
@@ -6511,7 +6512,8 @@ ScPostIt* ScDocument::GetNote(const ScAddress& rPos)
 
 ScPostIt* ScDocument::GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab)
 {
-    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
+    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) &&
+        nCol < maTabs[nTab]->GetAllocatedColumnsCount())
         return maTabs[nTab]->aCol[nCol].GetCellNote(nRow);
     else
         return nullptr;
@@ -6542,6 +6544,9 @@ bool ScDocument::HasNote(SCCOL nCol, SCROW nRow, SCTAB nTab) const
     if (!pTab)
         return false;
 
+    if (nCol >= pTab->GetAllocatedColumnsCount())
+        return false;
+
     const ScPostIt* pNote = pTab->aCol[nCol].GetCellNote(nRow);
     return pNote != nullptr;
 }
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index ecdcfd6deb64..6c170200e8be 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -442,7 +442,7 @@ void ScDocument::FillInfo(
     {
         SCCOL nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;                    // negative -> invalid
 
-        if ( ValidCol(nX) )
+        if ( ValidCol(nX) && nX < maTabs[nTab]->GetAllocatedColumnsCount() )
         {
             // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
             // will disturb the output
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 6fb453807604..d964642bd498 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -237,7 +237,7 @@ bool SetOptimalHeightsToRows(
 
 ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
                     bool bColInfo, bool bRowInfo ) :
-    aCol( MAXCOLCOUNT ),
+    aCol( INITIALCOLCOUNT ),
     aName( rNewName ),
     aCodeName( rNewName ),
     nLinkRefreshDelay( 0 ),
@@ -1705,7 +1705,7 @@ void ScTable::UpdateReference(
         mpRangeName->UpdateReference(rCxt, nTab);
 
     for ( ; i<=iMax; i++)
-        bUpdated |= aCol[i].UpdateReference(rCxt, pUndoDoc);
+        bUpdated |= CreateColumnIfNotExists(i).UpdateReference(rCxt, pUndoDoc);
 
     if ( bIncludeDraw )
         UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos );
@@ -2434,11 +2434,12 @@ void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
 {
     size_t nMatCol = 0;
     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
-        aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool);
+        CreateColumnIfNotExists(nCol).FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool);
 }
 
 void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
 {
+    nCol2 = ClampToAllocatedColumns(nCol2);
     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
         aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
 }
@@ -2509,32 +2510,33 @@ const ScConditionalFormatList* ScTable::GetCondFormList() const
 
 ScColumnsRange ScTable::GetColumnsRange(SCCOL nColBegin, SCCOL nColEnd) const
 {
-    // Because the range is inclusive, some code will pass nColEnd<nColBegin to
-    // indicate an empty range. Ensure that we create only valid iterators for
-    // the range, limit columns to bounds.
-    SCCOL nEffBegin, nEffEnd;
-    if (nColBegin <= nColEnd)
+    ScColContainer::ScColumnVector::const_iterator beginIter;
+    ScColContainer::ScColumnVector::const_iterator endIter;
+
+    // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range
+    if (nColEnd < nColBegin)
     {
-        if (nColBegin < 0)
-            nEffBegin = 0;
-        else
-            nEffBegin = std::min<SCCOL>( nColBegin, aCol.size());
-        if (nColEnd < 0)
-            nEffEnd = 0;
-        else
-            nEffEnd = std::min<SCCOL>( nColEnd + 1, aCol.size());
+        beginIter = aCol.end();
+        endIter = aCol.end();
+    }
+    else if (nColBegin >= aCol.size())
+    {
+        beginIter = aCol.end();
+        endIter = aCol.end();
     }
     else
     {
-        // Any empty will do.
-        nEffBegin = nEffEnd = 0;
+        // clamp end of range to available columns
+        if (nColEnd >= aCol.size())
+            nColEnd = aCol.size() - 1;
+        beginIter = aCol.begin() + nColBegin;
+        endIter = aCol.begin() + nColEnd + 1;
     }
-    return ScColumnsRange( ScColumnsRange::Iterator( aCol.begin() + nEffBegin),
-                           ScColumnsRange::Iterator( aCol.begin() + nEffEnd));
+    return ScColumnsRange(ScColumnsRange::Iterator(beginIter), ScColumnsRange::Iterator(endIter));
 }
 
 // out-of-line the cold part of the CreateColumnIfNotExists function
-void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol )
+void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const
 {
     const SCCOL aOldColSize = aCol.size();
     aCol.resize( static_cast< size_t >( nScCol + 1 ) );
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index bc2293f3bd9c..a74fc3a9a289 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -136,7 +136,7 @@ bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SC
         bTest = pOutlineTable->TestInsertRow(nSize);
 
     for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
-        bTest = aCol[i].TestInsertRow(nStartRow, nSize);
+        bTest = CreateColumnIfNotExists(i).TestInsertRow(nStartRow, nSize);
 
     return bTest;
 }
@@ -487,10 +487,10 @@ void ScTable::CopyToClip(
     if (!pTable->mpRangeName && mpRangeName)
         pTable->mpRangeName.reset( new ScRangeName(*mpRangeName) );
 
-    SCCOL i;
+    nCol2 = ClampToAllocatedColumns(nCol2);
 
-    for ( i = nCol1; i <= nCol2; i++)
-        aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->aCol[i]);  // notes are handled at column level
+    for ( SCCOL i = nCol1; i <= nCol2; i++)
+        aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->CreateColumnIfNotExists(i));  // notes are handled at column level
 
     //  copy widths/heights, and only "hidden", "filtered" and "manual" flags
     //  also for all preceding columns/rows, to have valid positions for drawing objects
@@ -515,7 +515,7 @@ void ScTable::CopyToClip(
     // If necessary replace formulas with values
 
     if ( IsProtected() )
-        for (i = nCol1; i <= nCol2; i++)
+        for (SCCOL i = nCol1; i <= nCol2; i++)
             pTable->aCol[i].RemoveProtected(nRow1, nRow2);
 
     pTable->mpCondFormatList.reset(new ScConditionalFormatList(pTable->pDocument, *mpCondFormatList));
@@ -665,7 +665,7 @@ bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL
     if (!ValidCol(nCol))
         return false;
 
-    aCol[nCol].InitBlockPosition(rBlockPos);
+    CreateColumnIfNotExists(nCol).InitBlockPosition(rBlockPos);
     return true;
 }
 
@@ -681,7 +681,10 @@ void ScTable::CopyFromClip(
     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
     {
         for ( SCCOL i = nCol1; i <= nCol2; i++)
+        {
+            pTable->CreateColumnIfNotExists(i - nDx);
             aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); // notes are handles at column level
+        }
 
         if (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB)
         {
@@ -1043,7 +1046,7 @@ ScColumn* ScTable::FetchColumn( SCCOL nCol )
     if (!ValidCol(nCol))
         return nullptr;
 
-    return &aCol[nCol];
+    return &CreateColumnIfNotExists(nCol);
 }
 
 const ScColumn* ScTable::FetchColumn( SCCOL nCol ) const
@@ -1124,9 +1127,9 @@ void ScTable::CopyToTable(
     {
         InsertDeleteFlags nTempFlags( nFlags &
                 ~InsertDeleteFlags( InsertDeleteFlags::NOTE | InsertDeleteFlags::ADDNOTES));
-        for (SCCOL i = nCol1; i <= nCol2; i++)
+        for (SCCOL i = nCol1; i <= ClampToAllocatedColumns(nCol2); i++)
             aCol[i].CopyToColumn(rCxt, nRow1, nRow2, bIsUndoDoc ? nFlags : nTempFlags, bMarked,
-                                pDestTab->aCol[i], pMarkData, bAsLink, bGlobalNamesToLocal);
+                                 pDestTab->CreateColumnIfNotExists(i), pMarkData, bAsLink, bGlobalNamesToLocal);
     }
 
     if (!bColRowFlags)      // Column widths/Row heights/Flags
@@ -1253,9 +1256,10 @@ void ScTable::CopyCaptionsToTable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW
     if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
         return;
 
+    nCol2 = ClampToAllocatedColumns(nCol2);
     for (SCCOL i = nCol1; i <= nCol2; i++)
     {
-        aCol[i].CopyCellNotesToDocument(nRow1, nRow2, pDestTab->aCol[i], bCloneCaption);
+        aCol[i].CopyCellNotesToDocument(nRow1, nRow2, pDestTab->CreateColumnIfNotExists(i), bCloneCaption);
         pDestTab->aCol[i].UpdateNoteCaptions(nRow1, nRow2);
     }
 }
@@ -1298,6 +1302,8 @@ void ScTable::UndoToTable(
 
 void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
 {
+    pPosTab->CreateColumnIfNotExists(aCol.size()-1);
+    pDestTab->CreateColumnIfNotExists(aCol.size()-1);
     for (SCCOL i=0; i < aCol.size(); i++)
         aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
 }
@@ -1317,14 +1323,16 @@ void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
     OSL_ENSURE( bScenario, "bScenario == FALSE" );
 
     for (SCCOL i=0; i < aCol.size(); i++)
-        aCol[i].CopyScenarioTo( pDestTab->aCol[i] );
+        aCol[i].CopyScenarioTo( pDestTab->CreateColumnIfNotExists(i) );
 }
 
 void ScTable::CopyScenarioFrom( const ScTable* pSrcTab )
 {
     OSL_ENSURE( bScenario, "bScenario == FALSE" );
 
-    for (SCCOL i=0; i < aCol.size(); i++)
+    SCCOL nEndCol = pSrcTab->aCol.size();
+    CreateColumnIfNotExists(nEndCol);
+    for (SCCOL i=0; i < nEndCol; i++)
         aCol[i].CopyScenarioFrom( pSrcTab->aCol[i] );
 }
 
@@ -1411,7 +1419,7 @@ bool ScTable::SetEditText( SCCOL nCol, SCROW nRow, std::unique_ptr<EditTextObjec
         return false;
     }
 
-    aCol[nCol].SetEditText(nRow, std::move(pEditText));
+    CreateColumnIfNotExists(nCol).SetEditText(nRow, std::move(pEditText));
     return true;
 }
 
@@ -1472,7 +1480,7 @@ void ScTable::SetFormula(
     if (!ValidColRow(nCol, nRow))
         return;
 
-    aCol[nCol].SetFormula(nRow, rFormula, eGram);
+    CreateColumnIfNotExists(nCol).SetFormula(nRow, rFormula, eGram);
 }
 
 ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell )
@@ -1516,7 +1524,7 @@ void ScTable::SetRawString( SCCOL nCol, SCROW nRow, const svl::SharedString& rSt
 
 void ScTable::GetString( SCCOL nCol, SCROW nRow, OUString& rString, const ScInterpreterContext* pContext ) const
 {
-    if (ValidColRow(nCol,nRow))
+    if (ValidColRow(nCol,nRow) && nCol < GetAllocatedColumnsCount())
         aCol[nCol].GetString( nRow, rString, pContext );
     else
         rString.clear();
@@ -1581,8 +1589,7 @@ ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow )
 {
     if (!ValidColRow(nCol, nRow))
         return nullptr;
-
-    return aCol[nCol].GetFormulaCell(nRow);
+    return CreateColumnIfNotExists(nCol).GetFormulaCell(nRow);
 }
 
 std::unique_ptr<ScPostIt> ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
@@ -1793,6 +1800,7 @@ void ScTable::SetDirty( const ScRange& rRange, ScColumn::BroadcastMode eMode )
     bool bOldAutoCalc = pDocument->GetAutoCalc();
     pDocument->SetAutoCalc( false );    // avoid multiple recalculations
     SCCOL nCol2 = rRange.aEnd.Col();
+    nCol2 = ClampToAllocatedColumns(nCol2);
     for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
         aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row(), eMode);
     pDocument->SetAutoCalc( bOldAutoCalc );
@@ -1913,7 +1921,7 @@ void ScTable::ResetChanged( const ScRange& rRange )
 {
     SCCOL nStartCol = rRange.aStart.Col();
     SCROW nStartRow = rRange.aStart.Row();
-    SCCOL nEndCol = rRange.aEnd.Col();
+    SCCOL nEndCol = ClampToAllocatedColumns(rRange.aEnd.Col());
     SCROW nEndRow = rRange.aEnd.Row();
 
     for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
@@ -1964,7 +1972,7 @@ void ScTable::SetNumberFormat( SCCOL nCol, SCROW nRow, sal_uInt32 nNumberFormat
 const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
 {
     if (ValidColRow(nCol,nRow))
-        return aCol[nCol].GetPattern( nRow );
+        return CreateColumnIfNotExists(nCol).GetPattern( nRow );
     else
     {
         OSL_FAIL("wrong column or row");
@@ -1974,7 +1982,8 @@ const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
 
 const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const
 {
-    if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow) )
+    if ( ValidColRow( nCol, nStartRow ) && ValidRow( nEndRow ) && (nStartRow <= nEndRow)
+        && nCol < GetAllocatedColumnsCount())
         return aCol[nCol].GetMostUsedPattern( nStartRow, nEndRow );
     else
         return nullptr;
@@ -2052,6 +2061,7 @@ bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
         return false;
     }
+    nCol2 = ClampToAllocatedColumns(nCol2);
     bool bEmpty = true;
     for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++)
     {
@@ -2300,7 +2310,8 @@ bool ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
 
     for (sc::ColRowSpan & aSpan : aSpans)
     {
-        for ( SCCOLROW j=aSpan.mnStart; j<=aSpan.mnEnd; j++ )
+        SCCOL nEndCol = ClampToAllocatedColumns(aSpan.mnEnd);
+        for ( SCCOLROW j=aSpan.mnStart; j<=nEndCol; j++ )
         {
             if ( aCol[j].HasSelectionMatrixFragment(rMark) )
                 return true;
@@ -2319,6 +2330,8 @@ bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
             *pOnlyNotBecauseOfMatrix = false;
         return false;
     }
+    nCol1 = ClampToAllocatedColumns(nCol1);
+    nCol2 = ClampToAllocatedColumns(nCol2);
 
     bool bIsEditable = true;
     if ( nLockCount )
@@ -2495,7 +2508,8 @@ void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkDa
 
     for (const sc::ColRowSpan & rSpan : aSpans)
     {
-        for (SCCOLROW i = rSpan.mnStart; i <= rSpan.mnEnd; ++i)
+        SCCOL nEnd = ClampToAllocatedColumns(rSpan.mnEnd);
+        for (SCCOLROW i = rSpan.mnStart; i <= nEnd; ++i)
         {
             aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
         }
@@ -2505,6 +2519,7 @@ void ScTable::MergeSelectionPattern( ScMergePatternState& rState, const ScMarkDa
 void ScTable::MergePatternArea( ScMergePatternState& rState, SCCOL nCol1, SCROW nRow1,
                                                     SCCOL nCol2, SCROW nRow2, bool bDeep ) const
 {
+    nCol2 = ClampToAllocatedColumns(nCol2);
     for (SCCOL i=nCol1; i<=nCol2; i++)
         aCol[i].MergePatternArea( rState, nRow1, nRow2, bDeep );
 }
@@ -2550,7 +2565,7 @@ void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol,
         PutInOrder(nStartCol, nEndCol);
         PutInOrder(nStartRow, nEndRow);
         for (SCCOL i = nStartCol; i <= nEndCol; i++)
-            aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged);
+            CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged);
     }
 }
 
@@ -2576,7 +2591,7 @@ void ScTable::AddCondFormatData( const ScRangeList& rRangeList, sal_uInt32 nInde
         SCROW nRowEnd = rRange.aEnd.Row();
         for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
         {
-            aCol[nCol].AddCondFormat(nRowStart, nRowEnd, nIndex);
+            CreateColumnIfNotExists(nCol).AddCondFormat(nRowStart, nRowEnd, nIndex);
         }
     }
 }
@@ -2588,7 +2603,7 @@ void ScTable::RemoveCondFormatData( const ScRangeList& rRangeList, sal_uInt32 nI
     {
         const ScRange & rRange = rRangeList[i];
         SCCOL nColStart = rRange.aStart.Col();
-        SCCOL nColEnd = rRange.aEnd.Col();
+        SCCOL nColEnd = ClampToAllocatedColumns(rRange.aEnd.Col());
         SCROW nRowStart = rRange.aStart.Row();
         SCROW nRowEnd = rRange.aEnd.Row();
         for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
@@ -2698,7 +2713,7 @@ const ScStyleSheet* ScTable::GetAreaStyle( bool& rFound, SCCOL nCol1, SCROW nRow
 
     const ScStyleSheet* pStyle = nullptr;
     const ScStyleSheet* pNewStyle;
-
+    nCol2 = ClampToAllocatedColumns(nCol2);
     for (SCCOL i=nCol1; i<=nCol2 && bEqual; i++)
     {
         pNewStyle = aCol[i].GetAreaStyle(bColFound, nRow1, nRow2);
@@ -2761,17 +2776,19 @@ bool ScTable::ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW
     bool bChanged = false;
     if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
         for (SCCOL i = nStartCol; i <= nEndCol; i++)
-            bChanged |= aCol[i].ApplyFlags(nStartRow, nEndRow, nFlags);
+            bChanged |= CreateColumnIfNotExists(i).ApplyFlags(nStartRow, nEndRow, nFlags);
     return bChanged;
 }
 
 bool ScTable::RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
                            ScMF nFlags )
 {
+    if (!ValidColRow(nStartCol, nStartRow) || !ValidColRow(nEndCol, nEndRow))
+        return false;
     bool bChanged = false;
-    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
-        for (SCCOL i = nStartCol; i <= nEndCol; i++)
-            bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
+    nEndCol = ClampToAllocatedColumns(nEndCol);
+    for (SCCOL i = nStartCol; i <= nEndCol; i++)
+        bChanged |= aCol[i].RemoveFlags(nStartRow, nEndRow, nFlags);
     return bChanged;
 }
 
@@ -2784,7 +2801,7 @@ void ScTable::SetPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )
 void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
 {
     if (ValidColRow(nCol,nRow))
-        aCol[nCol].ApplyAttr( nRow, rAttr );
+        CreateColumnIfNotExists(nCol).ApplyAttr( nRow, rAttr );
 }
 
 void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 4e9f074470ae..819bfa6f87db 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -17,7 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <rtl/math.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/random.hxx>
 #include <unotools/textsearch.hxx>
@@ -1825,7 +1824,7 @@ bool ScTable::TestRemoveSubTotals( const ScSubTotalParam& rParam )
 {
     SCCOL nStartCol = rParam.nCol1;
     SCROW nStartRow = rParam.nRow1 + 1;     // Header
-    SCCOL nEndCol   = rParam.nCol2;
+    SCCOL nEndCol   = ClampToAllocatedColumns(rParam.nCol2);
     SCROW nEndRow    = rParam.nRow2;
 
     for (SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
@@ -1859,7 +1858,7 @@ void ScTable::RemoveSubTotals( ScSubTotalParam& rParam )
 {
     SCCOL nStartCol = rParam.nCol1;
     SCROW nStartRow = rParam.nRow1 + 1;     // Header
-    SCCOL nEndCol   = rParam.nCol2;
+    SCCOL nEndCol   = ClampToAllocatedColumns(rParam.nCol2);
     SCROW nEndRow    = rParam.nRow2;        // will change
 
     RemoveSubTotalsHandler aFunc;
@@ -3541,7 +3540,7 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData, const ScMarkData&
         aMarkArea.aEnd.SetCol(MAXCOL);
     }
     const SCCOL nStartCol = aMarkArea.aStart.Col();
-    const SCCOL nEndCol = aMarkArea.aEnd.Col();
+    const SCCOL nEndCol = ClampToAllocatedColumns(aMarkArea.aEnd.Col());
     for (SCCOL nCol = nStartCol; nCol <= nEndCol && !rData.getError(); ++nCol)
     {
         if (mpColFlags && ColHidden(nCol))
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 91201f0efbe7..41754592410c 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -1638,6 +1638,8 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     {
         rInner = nISource;
 
+        CreateColumnIfNotExists(nCol);
+
         // Source cell value. We need to clone the value since it may be inserted repeatedly.
         ScCellValue aSrcCell = aCol[nCol].GetCellValue(static_cast<SCROW>(nRow));
 
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 4d3c99f86899..5a50a7cfcdcc 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -1082,7 +1082,7 @@ void ScTable::StartListening( const ScAddress& rAddress, SvtListener* pListener
     if (!ValidCol(rAddress.Col()))
         return;
 
-    aCol[rAddress.Col()].StartListening( *pListener, rAddress.Row() );
+    CreateColumnIfNotExists(rAddress.Col()).StartListening( *pListener, rAddress.Row() );
 }
 
 void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener )
@@ -1090,7 +1090,8 @@ void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener )
     if (!ValidCol(rAddress.Col()))
         return;
 
-    aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() );
+    if (rAddress.Col() < aCol.size())
+        aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() );
 }
 
 void ScTable::StartListening( sc::StartListeningContext& rCxt, const ScAddress& rAddress, SvtListener& rListener )
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 30f869a58733..e0ed0c96bce6 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -21,7 +21,7 @@
 
 bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const
 {
-    if (!ValidCol(nCol))
+    if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount() )
         return false;
 
     return aCol[nCol].IsMerged(nRow);
@@ -128,7 +128,7 @@ void ScTable::CopyOneCellFromClip(
         SCCOL nColOffset = nCol - nCol1;
         nColOffset = nColOffset % nSrcColSize;
         assert(nColOffset >= 0);
-        aCol[nCol].CopyOneCellFromClip(rCxt, nRow1, nRow2, nColOffset);
+        CreateColumnIfNotExists(nCol).CopyOneCellFromClip(rCxt, nRow1, nRow2, nColOffset);
 
         if (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB)
         {
@@ -318,9 +318,7 @@ void ScTable::EndListeningIntersectedGroups(
     if (nCol2 < nCol1 || !IsColValid(nCol1) || !ValidCol(nCol2))
         return;
 
-    const SCCOL nMaxCol2 = std::min<SCCOL>( nCol2, aCol.size() - 1 );
-
-    for (SCCOL nCol = nCol1; nCol <= nMaxCol2; ++nCol)
+    for (SCCOL nCol : GetColumnsRange(nCol1, nCol2))
         aCol[nCol].EndListeningIntersectedGroups(rCxt, nRow1, nRow2, pGroupPos);
 }
 
@@ -345,7 +343,7 @@ bool ScTable::IsEditActionAllowed(
 {
     if (!IsProtected())
     {
-        SCCOL nCol1 = 0, nCol2 = MAXCOL;
+        SCCOL nCol1 = 0, nCol2 = aCol.size() - 1;
         SCROW nRow1 = 0, nRow2 = MAXROW;
 
         switch (eAction)
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index 9b6c72ecdb22..04bb7d63e319 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -340,7 +340,7 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
             if ( bSortByRows )
             {
                 OUString  aFieldName;
-                SCCOL   nMaxCol = aSortData.nCol2;
+                SCCOL   nMaxCol = pDoc->ClampToAllocatedColumns(nTab, aSortData.nCol2);
                 SCCOL   col;
 
                 for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )


More information about the Libreoffice-commits mailing list