summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2017-12-13 22:27:03 -0500
committerKohei Yoshida <libreoffice@kohei.us>2017-12-18 23:28:02 +0100
commit1c7fa9528f7373e6798b597a42abe38f20a306aa (patch)
tree9777e93c63ae9c7615eb6929ddd3739f80cfd373 /sc
parenta72f3d40def7878ae487c8c34cd84da7d90fc99a (diff)
Defer cell value insertion until later.
Because Calc's formula engine expects all named expressions to be present at the time of re-calculations, we need to delay insertion of cell values until after the named expressions are inserted into the document. Change-Id: I54c7d3dc86b3e2c5c192337b1cebfbdfb901ab1f Reviewed-on: https://gerrit.libreoffice.org/46665 Reviewed-by: Kohei Yoshida <libreoffice@kohei.us> Tested-by: Kohei Yoshida <libreoffice@kohei.us>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/documentimport.hxx10
-rw-r--r--sc/source/core/data/documentimport.cxx42
-rw-r--r--sc/source/filter/inc/orcusinterface.hxx51
-rw-r--r--sc/source/filter/orcus/interface.cxx293
4 files changed, 323 insertions, 73 deletions
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index b4c35e1f99b5..d881da37cf2d 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -96,7 +96,15 @@ public:
void setNumericCell(const ScAddress& rPos, double fVal);
void setStringCell(const ScAddress& rPos, const OUString& rStr);
void setEditCell(const ScAddress& rPos, EditTextObject* pEditText);
- void setFormulaCell(const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar);
+
+ void setFormulaCell(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+ const double* pResult = nullptr );
+
+ void setFormulaCell(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+ const OUString& rResult );
+
void setFormulaCell(const ScAddress& rPos, ScTokenArray* pArray);
void setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell);
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 183f3e1650af..6208789f416e 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -25,9 +25,7 @@
#include <svl/sharedstringpool.hxx>
#include <svl/languageoptions.hxx>
-
-#include <memory>
-#include <vector>
+#include <o3tl/make_unique.hxx>
namespace {
@@ -271,7 +269,35 @@ void ScDocumentImport::setEditCell(const ScAddress& rPos, EditTextObject* pEditT
}
void ScDocumentImport::setFormulaCell(
- const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar)
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+ const double* pResult )
+{
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ std::unique_ptr<ScFormulaCell> pFC =
+ o3tl::make_unique<ScFormulaCell>(&mpImpl->mrDoc, rPos, rFormula, eGrammar);
+
+ if (pResult)
+ {
+ // Set cached result to this formula cell.
+ pFC->SetResultDouble(*pResult);
+ }
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos =
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), pFC.release());
+}
+
+void ScDocumentImport::setFormulaCell(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+ const OUString& rResult )
{
ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
if (!pTab)
@@ -282,9 +308,15 @@ void ScDocumentImport::setFormulaCell(
if (!pBlockPos)
return;
+ std::unique_ptr<ScFormulaCell> pFC =
+ o3tl::make_unique<ScFormulaCell>(&mpImpl->mrDoc, rPos, rFormula, eGrammar);
+
+ // Set cached result to this formula cell.
+ pFC->SetHybridString(mpImpl->mrDoc.GetSharedStringPool().intern(rResult));
+
sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
pBlockPos->miCellPos =
- rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), pFC.release());
}
void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScTokenArray* pArray)
diff --git a/sc/source/filter/inc/orcusinterface.hxx b/sc/source/filter/inc/orcusinterface.hxx
index 851271f9806a..07c35fa78dfe 100644
--- a/sc/source/filter/inc/orcusinterface.hxx
+++ b/sc/source/filter/inc/orcusinterface.hxx
@@ -273,6 +273,8 @@ public:
virtual orcus::spreadsheet::range_size_t get_sheet_size() const override;
SCTAB getIndex() const { return mnTab; }
+
+ const sc::SharedFormulaGroups& getSharedFormulaGroups() const;
};
class ScOrcusStyles : public orcus::spreadsheet::iface::import_styles
@@ -508,28 +510,51 @@ public:
class ScOrcusFactory : public orcus::spreadsheet::iface::import_factory
{
- struct StringCellCache
+ struct CellStoreToken
{
+ enum class Type
+ {
+ Auto,
+ Numeric,
+ String,
+ Formula,
+ FormulaWithResult,
+ SharedFormula,
+ SharedFormulaWithResult,
+ Matrix
+ };
+
ScAddress maPos;
- size_t mnIndex;
+ Type meType;
- StringCellCache(const ScAddress& rPos, size_t nIndex);
+ OUString maStr1;
+ OUString maStr2;
+ double mfValue;
+
+ uint32_t mnIndex1;
+ uint32_t mnIndex2;
+ formula::FormulaGrammar::Grammar meGrammar;
+
+ CellStoreToken( const ScAddress& rPos, Type eType );
+ CellStoreToken( const ScAddress& rPos, double fValue );
+ CellStoreToken( const ScAddress& rPos, uint32_t nIndex );
+ CellStoreToken( const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar );
};
typedef std::unordered_map<OUString, size_t> StringHashType;
- typedef std::vector<StringCellCache> StringCellCaches;
+ typedef std::vector<CellStoreToken> CellStoreTokensType;
ScDocumentImport maDoc;
std::vector<OUString> maStrings;
StringHashType maStringHash;
- StringCellCaches maStringCells;
+ CellStoreTokensType maCellStoreTokens;
ScOrcusGlobalSettings maGlobalSettings;
ScOrcusRefResolver maRefResolver;
ScOrcusSharedStrings maSharedStrings;
ScOrcusNamedExpression maNamedExpressions;
- std::vector< std::unique_ptr<ScOrcusSheet> > maSheets;
+ std::vector<std::unique_ptr<ScOrcusSheet>> maSheets;
ScOrcusStyles maStyles;
int mnProgress;
@@ -552,7 +577,19 @@ public:
size_t appendString(const OUString& rStr);
size_t addString(const OUString& rStr);
- void pushStringCell(const ScAddress& rPos, size_t nStrIndex);
+ void pushCellStoreAutoToken( const ScAddress& rPos, const OUString& rVal );
+ void pushCellStoreToken( const ScAddress& rPos, uint32_t nStrIndex );
+ void pushCellStoreToken( const ScAddress& rPos, double fValue );
+ void pushCellStoreToken(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar );
+
+ void pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex );
+ void pushMatrixFormulaToken(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+ uint32_t nRowRange, uint32_t nColRange );
+
+ void pushFormulaResult( const ScAddress& rPos, double fValue );
+ void pushFormulaResult( const ScAddress& rPos, const OUString& rValue );
void incrementProgress();
diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx
index c2fa116d0617..04581dc70d72 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -177,8 +177,27 @@ void ScOrcusNamedExpression::define_name(const char* p_name, size_t n_name, cons
pNames->insert(pRange, false);
}
-ScOrcusFactory::StringCellCache::StringCellCache(const ScAddress& rPos, size_t nIndex) :
- maPos(rPos), mnIndex(nIndex) {}
+ScOrcusFactory::CellStoreToken::CellStoreToken( const ScAddress& rPos, Type eType ) :
+ maPos(rPos), meType(eType)
+{
+ rtl::math::setNan(&mfValue);
+}
+
+ScOrcusFactory::CellStoreToken::CellStoreToken( const ScAddress& rPos, double fValue ) :
+ maPos(rPos), meType(Type::Numeric), mfValue(fValue) {}
+
+ScOrcusFactory::CellStoreToken::CellStoreToken( const ScAddress& rPos, uint32_t nIndex ) :
+ maPos(rPos), meType(Type::String), mnIndex1(nIndex)
+{
+ rtl::math::setNan(&mfValue);
+}
+
+ScOrcusFactory::CellStoreToken::CellStoreToken(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar ) :
+ maPos(rPos), meType(Type::Formula), maStr1(rFormula), meGrammar(eGrammar)
+{
+ rtl::math::setNan(&mfValue);
+}
ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) :
maDoc(rDoc),
@@ -281,16 +300,112 @@ orcus::spreadsheet::iface::import_styles* ScOrcusFactory::get_styles()
void ScOrcusFactory::finalize()
{
+ auto toFormulaCell = [this]( const CellStoreToken& rToken ) -> std::unique_ptr<ScFormulaCell>
+ {
+ const ScOrcusSheet& rSheet = *maSheets.at(rToken.maPos.Tab());
+ const sc::SharedFormulaGroups& rSFG = rSheet.getSharedFormulaGroups();
+ const ScTokenArray* pArray = rSFG.get(rToken.mnIndex1);
+ if (!pArray)
+ return std::unique_ptr<ScFormulaCell>();
+
+ return o3tl::make_unique<ScFormulaCell>(&maDoc.getDoc(), rToken.maPos, *pArray);
+ };
+
int nCellCount = 0;
- StringCellCaches::const_iterator it = maStringCells.begin(), itEnd = maStringCells.end();
- for (; it != itEnd; ++it)
+
+ for (const CellStoreToken& rToken : maCellStoreTokens)
{
- if (it->mnIndex >= maStrings.size())
- // String index out-of-bound! Something is up.
- continue;
+ switch (rToken.meType)
+ {
+ case CellStoreToken::Type::Auto:
+ {
+ maDoc.setAutoInput(rToken.maPos, rToken.maStr1);
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::String:
+ {
+ if (rToken.mnIndex1 >= maStrings.size())
+ // String index out-of-bound! Something is up.
+ break;
+
+ maDoc.setStringCell(rToken.maPos, maStrings[rToken.mnIndex1]);
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::Numeric:
+ {
+ maDoc.setNumericCell(rToken.maPos, rToken.mfValue);
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::Formula:
+ {
+ maDoc.setFormulaCell(
+ rToken.maPos, rToken.maStr1, rToken.meGrammar);
+
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::FormulaWithResult:
+ {
+ if (rtl::math::isFinite(rToken.mfValue))
+ maDoc.setFormulaCell(rToken.maPos, rToken.maStr1, rToken.meGrammar, &rToken.mfValue);
+ else
+ maDoc.setFormulaCell(rToken.maPos, rToken.maStr1, rToken.meGrammar, rToken.maStr2);
+
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::SharedFormula:
+ {
+ std::unique_ptr<ScFormulaCell> pCell = toFormulaCell(rToken);
+ if (!pCell)
+ break;
+
+ maDoc.setFormulaCell(rToken.maPos, pCell.release());
+
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::SharedFormulaWithResult:
+ {
+ std::unique_ptr<ScFormulaCell> pCell = toFormulaCell(rToken);
+ if (!pCell)
+ break;
+
+ if (rtl::math::isFinite(rToken.mfValue))
+ pCell->SetResultDouble(rToken.mfValue);
+ else
+ pCell->SetHybridString(
+ maDoc.getDoc().GetSharedStringPool().intern(rToken.maStr2));
+
+ maDoc.setFormulaCell(rToken.maPos, pCell.release());
+
+ ++nCellCount;
+ break;
+ }
+ case CellStoreToken::Type::Matrix:
+ {
+ if (!rToken.mnIndex1 || !rToken.mnIndex2)
+ break;
+
+ ScRange aRange(rToken.maPos);
+ aRange.aEnd.IncCol(rToken.mnIndex1-1);
+ aRange.aEnd.IncRow(rToken.mnIndex2-1);
+
+ ScCompiler aComp(&maDoc.getDoc(), aRange.aStart, rToken.meGrammar);
+ std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(rToken.maStr1));
+ if (!pArray)
+ break;
+
+ maDoc.setMatrixCells(aRange, *pArray, rToken.meGrammar);
+ break;
+ }
+ default:
+ ;
+ }
- maDoc.setStringCell(it->maPos, maStrings[it->mnIndex]);
- ++nCellCount;
if (nCellCount == 100000)
{
incrementProgress();
@@ -323,9 +438,96 @@ size_t ScOrcusFactory::addString(const OUString& rStr)
return appendString(rStr);
}
-void ScOrcusFactory::pushStringCell(const ScAddress& rPos, size_t nStrIndex)
+void ScOrcusFactory::pushCellStoreAutoToken( const ScAddress& rPos, const OUString& rVal )
+{
+ maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::Auto);
+ maCellStoreTokens.back().maStr1 = rVal;
+}
+
+void ScOrcusFactory::pushCellStoreToken( const ScAddress& rPos, uint32_t nStrIndex )
+{
+ maCellStoreTokens.emplace_back(rPos, nStrIndex);
+}
+
+void ScOrcusFactory::pushCellStoreToken( const ScAddress& rPos, double fValue )
+{
+ maCellStoreTokens.emplace_back(rPos, fValue);
+}
+
+void ScOrcusFactory::pushCellStoreToken(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar )
{
- maStringCells.emplace_back(rPos, nStrIndex);
+ maCellStoreTokens.emplace_back(rPos, rFormula, eGrammar);
+}
+
+void ScOrcusFactory::pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex )
+{
+ maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::SharedFormula);
+ maCellStoreTokens.back().mnIndex1 = nIndex;
+}
+
+void ScOrcusFactory::pushMatrixFormulaToken(
+ const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+ uint32_t nRowRange, uint32_t nColRange )
+{
+ maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::Matrix);
+ CellStoreToken& rT = maCellStoreTokens.back();
+ rT.maStr1 = rFormula;
+ rT.meGrammar = eGrammar;
+ rT.mnIndex1 = nColRange;
+ rT.mnIndex2 = nRowRange;
+}
+
+void ScOrcusFactory::pushFormulaResult( const ScAddress& rPos, double fValue )
+{
+ // Formula result is expected to be pushed immediately following the
+ // formula token it belongs.
+ if (maCellStoreTokens.empty())
+ return;
+
+ CellStoreToken& rToken = maCellStoreTokens.back();
+ if (rToken.maPos != rPos)
+ return;
+
+ switch (rToken.meType)
+ {
+ case CellStoreToken::Type::Formula:
+ rToken.meType = CellStoreToken::Type::FormulaWithResult;
+ break;
+ case CellStoreToken::Type::SharedFormula:
+ rToken.meType = CellStoreToken::Type::SharedFormulaWithResult;
+ break;
+ default:
+ return;
+ }
+
+ rToken.mfValue = fValue;
+}
+
+void ScOrcusFactory::pushFormulaResult( const ScAddress& rPos, const OUString& rValue )
+{
+ // Formula result is expected to be pushed immediately following the
+ // formula token it belongs.
+ if (maCellStoreTokens.empty())
+ return;
+
+ CellStoreToken& rToken = maCellStoreTokens.back();
+ if (rToken.maPos != rPos)
+ return;
+
+ switch (rToken.meType)
+ {
+ case CellStoreToken::Type::Formula:
+ rToken.meType = CellStoreToken::Type::FormulaWithResult;
+ break;
+ case CellStoreToken::Type::SharedFormula:
+ rToken.meType = CellStoreToken::Type::SharedFormulaWithResult;
+ break;
+ default:
+ return;
+ }
+
+ rToken.maStr2 = rValue;
}
void ScOrcusFactory::incrementProgress()
@@ -620,30 +822,25 @@ os::iface::import_conditional_format* ScOrcusSheet::get_conditional_format()
void ScOrcusSheet::set_auto(os::row_t row, os::col_t col, const char* p, size_t n)
{
OUString aVal(p, n, RTL_TEXTENCODING_UTF8);
- mrDoc.setAutoInput(ScAddress(col, row, mnTab), aVal);
+ mrFactory.pushCellStoreAutoToken(ScAddress(col, row, mnTab), aVal);
cellInserted();
}
void ScOrcusSheet::set_string(os::row_t row, os::col_t col, size_t sindex)
{
- // We need to defer string cells since the shared string pool is not yet
- // populated at the time this method is called. Orcus imports string
- // table after the cells get imported. We won't need to do this once we
- // implement true shared strings in Calc core.
-
- mrFactory.pushStringCell(ScAddress(col, row, mnTab), sindex);
+ mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), uint32_t(sindex));
cellInserted();
}
void ScOrcusSheet::set_value(os::row_t row, os::col_t col, double value)
{
- mrDoc.setNumericCell(ScAddress(col, row, mnTab), value);
+ mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), value);
cellInserted();
}
void ScOrcusSheet::set_bool(os::row_t row, os::col_t col, bool value)
{
- mrDoc.setNumericCell(ScAddress(col, row, mnTab), value ? 1.0 : 0.0);
+ mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), value ? 1.0 : 0.0);
cellInserted();
}
@@ -666,7 +863,7 @@ void ScOrcusSheet::set_date_time(
fTime /= DATE_TIME_FACTOR;
- mrDoc.setNumericCell(ScAddress(col, row, mnTab), nDateDiff + fTime);
+ mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), nDateDiff + fTime);
cellInserted();
}
@@ -692,35 +889,20 @@ void ScOrcusSheet::set_formula(
os::row_t row, os::col_t col, os::formula_grammar_t grammar, const char* p, size_t n)
{
OUString aFormula(p, n, RTL_TEXTENCODING_UTF8);
- formula::FormulaGrammar::Grammar eGrammar = getCalcGrammarFromOrcus( grammar );
- mrDoc.setFormulaCell(ScAddress(col,row,mnTab), aFormula, eGrammar);
+ mrFactory.pushCellStoreToken(
+ ScAddress(col, row, mnTab), aFormula, getCalcGrammarFromOrcus(grammar));
cellInserted();
}
void ScOrcusSheet::set_formula_result(os::row_t row, os::col_t col, const char* p, size_t n)
{
- ScFormulaCell* pCell = mrDoc.getDoc().GetFormulaCell(ScAddress(col, row, mnTab));
- if (!pCell)
- {
- SAL_WARN("sc.orcus", "trying to set formula result for non formula "
- "cell! Col: " << col << ";Row: " << row << ";Tab: " << mnTab);
- return;
- }
OUString aResult( p, n, RTL_TEXTENCODING_UTF8);
- pCell->SetHybridString(mrDoc.getDoc().GetSharedStringPool().intern(aResult));
+ mrFactory.pushFormulaResult(ScAddress(col, row, mnTab), aResult);
}
-void ScOrcusSheet::set_formula_result(os::row_t row, os::col_t col, double /*val*/)
+void ScOrcusSheet::set_formula_result(os::row_t row, os::col_t col, double val)
{
- ScFormulaCell* pCell = mrDoc.getDoc().GetFormulaCell(ScAddress(col, row, mnTab));
- if (!pCell)
- {
- SAL_WARN("sc.orcus", "trying to set formula result for non formula "
- "cell! Col: " << col << ";Row: " << row << ";Tab: " << mnTab);
- return;
- }
-
- // TODO: FIXME
+ mrFactory.pushFormulaResult(ScAddress(col, row, mnTab), val);
}
void ScOrcusSheet::set_shared_formula(
@@ -740,12 +922,8 @@ void ScOrcusSheet::set_shared_formula(
maFormulaGroups.set(sindex, pArray);
- ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, *pArray);
- mrDoc.setFormulaCell(aPos, pCell);
+ mrFactory.pushSharedFormulaToken(aPos, sindex);
cellInserted();
-
- // For now, orcus doesn't support setting cached result. Mark it for re-calculation.
- pCell->SetDirty();
}
void ScOrcusSheet::set_shared_formula(
@@ -763,29 +941,19 @@ void ScOrcusSheet::set_shared_formula(os::row_t row, os::col_t col, size_t sinde
if (!pArray)
return;
- ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, *pArray);
- mrDoc.setFormulaCell(aPos, pCell);
+ mrFactory.pushSharedFormulaToken(aPos, sindex);
cellInserted();
-
- // For now, orcus doesn't support setting cached result. Mark it for re-calculation.
- pCell->SetDirty();
}
void ScOrcusSheet::set_array_formula(
os::row_t row, os::col_t col, os::formula_grammar_t grammar,
const char* p, size_t n, os::row_t array_rows, os::col_t array_cols)
{
- formula::FormulaGrammar::Grammar eGrammar = getCalcGrammarFromOrcus( grammar );
OUString aFormula(p, n, RTL_TEXTENCODING_UTF8);
+ formula::FormulaGrammar::Grammar eGrammar = getCalcGrammarFromOrcus(grammar);
- ScRange aRange(col, row, mnTab, col+array_cols, row + array_rows, mnTab);
-
- ScCompiler aComp(&mrDoc.getDoc(), aRange.aStart, eGrammar);
- std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(aFormula));
- if (!pArray)
- return;
-
- mrDoc.setMatrixCells(aRange, *pArray, eGrammar);
+ ScAddress aPos(col, row, mnTab);
+ mrFactory.pushMatrixFormulaToken(aPos, aFormula, eGrammar, array_rows, array_cols);
}
void ScOrcusSheet::set_array_formula(
@@ -803,6 +971,11 @@ orcus::spreadsheet::range_size_t ScOrcusSheet::get_sheet_size() const
return ret;
}
+const sc::SharedFormulaGroups& ScOrcusSheet::getSharedFormulaGroups() const
+{
+ return maFormulaGroups;
+}
+
ScOrcusSharedStrings::ScOrcusSharedStrings(ScOrcusFactory& rFactory) :
mrFactory(rFactory) {}