LibreOffice Module sc (master) 1
formulabuffer.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <formulabuffer.hxx>
12#include <formulacell.hxx>
13#include <document.hxx>
14#include <documentimport.hxx>
15
16#include <autonamecache.hxx>
17#include <tokenarray.hxx>
19#include <externalrefmgr.hxx>
21#include <o3tl/safeint.hxx>
22#include <oox/token/tokens.hxx>
25#include <svl/numformat.hxx>
26#include <sal/log.hxx>
27
28using namespace ::com::sun::star::uno;
29using namespace ::com::sun::star::sheet;
30
31#include <memory>
32#include <utility>
33
34namespace oox::xls {
35
36namespace {
37
42class CachedTokenArray
43{
44public:
45 CachedTokenArray(const CachedTokenArray&) = delete;
46 const CachedTokenArray& operator=(const CachedTokenArray&) = delete;
47
48 struct Item
49 {
52
53 Item(const Item&) = delete;
54 const Item& operator=(const Item&) = delete;
55
56 Item() : mnRow(-1), mpCell(nullptr) {}
57 };
58
59 explicit CachedTokenArray( const ScDocument& rDoc ) :
60 maCxt(rDoc, formula::FormulaGrammar::GRAM_OOXML) {}
61
62 Item* get( const ScAddress& rPos, std::u16string_view rFormula )
63 {
64 // Check if a token array is cached for this column.
65 ColCacheType::iterator it = maCache.find(rPos.Col());
66 if (it == maCache.end())
67 return nullptr;
68
69 Item& rCached = *it->second;
70 const ScTokenArray& rCode = *rCached.mpCell->GetCode();
71 OUString aPredicted = rCode.CreateString(maCxt, rPos);
72 if (rFormula == aPredicted)
73 return &rCached;
74
75 return nullptr;
76 }
77
78 void store( const ScAddress& rPos, ScFormulaCell* pCell )
79 {
80 ColCacheType::iterator it = maCache.find(rPos.Col());
81 if (it == maCache.end())
82 {
83 // Create an entry for this column.
84 std::pair<ColCacheType::iterator,bool> r =
85 maCache.emplace(rPos.Col(), std::make_unique<Item>());
86 if (!r.second)
87 // Insertion failed.
88 return;
89
90 it = r.first;
91 }
92
93 Item& rItem = *it->second;
94 rItem.mnRow = rPos.Row();
95 rItem.mpCell = pCell;
96 }
97
98private:
99 typedef std::unordered_map<SCCOL, std::unique_ptr<Item>> ColCacheType;
100 ColCacheType maCache;
102};
103
104void applySharedFormulas(
105 ScDocumentImport& rDoc,
106 SvNumberFormatter& rFormatter,
107 std::vector<FormulaBuffer::SharedFormulaEntry>& rSharedFormulas,
108 std::vector<FormulaBuffer::SharedFormulaDesc>& rCells,
109 WorkbookHelper& rWorkbookHelper)
110{
112 {
113 // Process shared formulas first.
114 for (const FormulaBuffer::SharedFormulaEntry& rEntry : rSharedFormulas)
115 {
116 const ScAddress& aPos = rEntry.maAddress;
117 sal_Int32 nId = rEntry.mnSharedId;
118 const OUString& rTokenStr = rEntry.maTokenStr;
119
120 ScCompiler aComp(rDoc.getDoc(), aPos, formula::FormulaGrammar::GRAM_OOXML, true, false);
121 aComp.SetNumberFormatter(&rFormatter);
122 std::unique_ptr<ScTokenArray> pArray = aComp.CompileString(rTokenStr);
123 if (pArray)
124 {
125 aComp.CompileTokenArray(); // Generate RPN tokens.
126 aGroups.set(nId, std::move(pArray), aPos);
127 }
128 }
129 }
130
131 {
133 const bool bGeneratorKnownGood = rWorkbookHelper.isGeneratorKnownGood();
134 bool bHasCalculatedFormulaCells = rWorkbookHelper.hasCalculatedFormulaCells();
135 // Process formulas that use shared formulas.
136 for (const FormulaBuffer::SharedFormulaDesc& rDesc : rCells)
137 {
138 const ScAddress& aPos = rDesc.maAddress;
139 const sc::SharedFormulaGroupEntry* pEntry = aGroups.getEntry(rDesc.mnSharedId);
140 if (!pEntry)
141 continue;
142
143 const ScTokenArray* pArray = pEntry->getTokenArray();
144 assert(pArray);
145 const ScAddress& rOrigin = pEntry->getOrigin();
146 assert(rOrigin.IsValid());
147
148 ScFormulaCell* pCell;
149 // In case of shared-formula along a row, do not let
150 // these cells share the same token objects.
151 // If we do, any reference-updates on these cells
152 // (while editing) will mess things up. Pass the cloned array as a
153 // pointer and not as reference to avoid any further allocation.
154 if (rOrigin.Col() != aPos.Col())
155 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, pArray->Clone());
156 else
157 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, *pArray);
158
159 rDoc.setFormulaCell(aPos, pCell);
160 const bool bNeedNumberFormat = ((rDoc.getDoc().GetNumberFormat(
161 aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET) == 0);
162 if (bNeedNumberFormat)
163 pCell->SetNeedNumberFormat(true);
164
165 if (rDesc.maCellValue.isEmpty())
166 {
167 // No cached cell value. Mark it for re-calculation.
168 pCell->SetDirty();
169 // Recalc even if AutoCalc is disabled. Must be after
170 // SetDirty() as it also calls SetDirtyVar().
171 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
172 continue;
173 }
174
175 // Set cached formula results. For now, we only use boolean,
176 // numeric and string-formula results. Find out how to utilize
177 // cached results of other types.
178 switch (rDesc.mnValueType)
179 {
180 case XML_b:
181 // boolean value.
182 if (bNeedNumberFormat)
183 {
184 rDoc.getDoc().SetNumberFormat( aPos,
185 rDoc.getDoc().GetFormatTable()->GetStandardFormat( SvNumFormatType::LOGICAL));
186 }
187 if (rDesc.maCellValue == "1" || rDesc.maCellValue == "0")
188 pCell->SetResultDouble(rDesc.maCellValue == "1" ? 1.0 : 0.0);
189 else
190 {
191 // Recalc even if AutoCalc is disabled.
192 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
193 }
194 break;
195 case XML_n:
196 // numeric value.
197 {
198 const double fVal = rDesc.maCellValue.toDouble();
199 if (!bHasCalculatedFormulaCells && fVal != 0.0)
200 {
201 rWorkbookHelper.setCalculatedFormulaCells();
202 bHasCalculatedFormulaCells = true;
203 }
204 pCell->SetResultDouble(fVal);
205 /* TODO: is it on purpose that we never reset dirty here
206 * and thus recalculate anyway if cell was dirty? Or is it
207 * never dirty and therefore set dirty below otherwise? This
208 * is different from the non-shared case in
209 * applyCellFormulaValues(). */
210 }
211 break;
212 case XML_str:
213 if (bGeneratorKnownGood)
214 {
215 // See applyCellFormulaValues
216 svl::SharedString aSS = rStrPool.intern(rDesc.maCellValue);
217 pCell->SetResultToken(new formula::FormulaStringToken(std::move(aSS)));
218 // If we don't reset dirty, then e.g. disabling macros makes all cells
219 // that use macro functions to show #VALUE!
220 pCell->ResetDirty();
221 pCell->SetChanged(false);
222 break;
223 }
224 [[fallthrough]];
225 default:
226 // Mark it for re-calculation.
227 pCell->SetDirty();
228 // Recalc even if AutoCalc is disabled. Must be after
229 // SetDirty() as it also calls SetDirtyVar().
230 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
231 }
232 }
233 }
234}
235
236void applyCellFormulas(
237 ScDocumentImport& rDoc, CachedTokenArray& rCache, SvNumberFormatter& rFormatter,
238 const Sequence<ExternalLinkInfo>& rExternalLinks,
239 const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
240{
241 for (const FormulaBuffer::TokenAddressItem& rItem : rCells)
242 {
243 const ScAddress& aPos = rItem.maAddress;
244 CachedTokenArray::Item* p = rCache.get(aPos, rItem.maTokenStr);
245 if (p)
246 {
247 // Use the cached version to avoid re-compilation.
248
249 ScFormulaCell* pCell = nullptr;
250 if (p->mnRow + 1 == aPos.Row())
251 {
252 // Put them in the same formula group.
253 ScFormulaCell& rPrev = *p->mpCell;
254 ScFormulaCellGroupRef xGroup = rPrev.GetCellGroup();
255 if (!xGroup)
256 {
257 // Last cell is not grouped yet. Start a new group.
258 assert(rPrev.aPos.Row() == p->mnRow);
259 xGroup = rPrev.CreateCellGroup(1, false);
260 }
261 ++xGroup->mnLength;
262
263 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, xGroup);
264 }
265 else
266 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, p->mpCell->GetCode()->Clone());
267
268 rDoc.setFormulaCell(aPos, pCell);
269 if (rDoc.getDoc().GetNumberFormat(aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET == 0)
270 pCell->SetNeedNumberFormat(true);
271
272 // Update the cache.
273 p->mnRow = aPos.Row();
274 p->mpCell = pCell;
275 continue;
276 }
277
278 ScCompiler aCompiler(rDoc.getDoc(), aPos, formula::FormulaGrammar::GRAM_OOXML, true, false);
279 aCompiler.SetNumberFormatter(&rFormatter);
280 aCompiler.SetExternalLinks(rExternalLinks);
281 std::unique_ptr<ScTokenArray> pCode = aCompiler.CompileString(rItem.maTokenStr);
282 if (!pCode)
283 continue;
284
285 aCompiler.CompileTokenArray(); // Generate RPN tokens.
286
287 ScFormulaCell* pCell = new ScFormulaCell(rDoc.getDoc(), aPos, std::move(pCode));
288 rDoc.setFormulaCell(aPos, pCell);
289 if (rDoc.getDoc().GetNumberFormat(aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET == 0)
290 pCell->SetNeedNumberFormat(true);
291 rCache.store(aPos, pCell);
292 }
293}
294
295void applyArrayFormulas(
296 ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
297 const Sequence<ExternalLinkInfo>& rExternalLinks,
298 const std::vector<FormulaBuffer::TokenRangeAddressItem>& rArrays )
299{
300 for (const FormulaBuffer::TokenRangeAddressItem& rAddressItem : rArrays)
301 {
302 const ScAddress& aPos = rAddressItem.maTokenAndAddress.maAddress;
303
305 aComp.SetNumberFormatter(&rFormatter);
306 aComp.SetExternalLinks(rExternalLinks);
307 std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(rAddressItem.maTokenAndAddress.maTokenStr));
308 if (pArray)
309 rDoc.setMatrixCells(rAddressItem.maRange, *pArray, formula::FormulaGrammar::GRAM_OOXML);
310 }
311}
312
313void applyCellFormulaValues(
314 ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector, WorkbookHelper& rWorkbookHelper )
315{
317 const bool bGeneratorKnownGood = rWorkbookHelper.isGeneratorKnownGood();
318 bool bHasCalculatedFormulaCells = rWorkbookHelper.hasCalculatedFormulaCells();
319
320 for (const FormulaBuffer::FormulaValue& rValue : rVector)
321 {
322 const ScAddress& aCellPos = rValue.maAddress;
323 ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
324 const OUString& rValueStr = rValue.maValueStr;
325 if (!pCell)
326 continue;
327
328 switch (rValue.mnCellType)
329 {
330 case XML_n:
331 {
332 const double fVal = rValueStr.toDouble();
333 if (!bHasCalculatedFormulaCells && fVal != 0.0)
334 {
335 rWorkbookHelper.setCalculatedFormulaCells();
336 bHasCalculatedFormulaCells = true;
337 }
338 pCell->SetResultDouble(fVal);
339 pCell->ResetDirty();
340 pCell->SetChanged(false);
341 }
342 break;
343 case XML_str:
344 // Excel uses t="str" for string results (per definition
345 // ECMA-376 18.18.11 ST_CellType (Cell Type) "Cell containing a
346 // formula string.", but that 't' Cell Data Type attribute, "an
347 // enumeration representing the cell's data type", is meant for
348 // the content of the <v> element). We follow that. Other
349 // applications might not and instead use t="str" for the cell
350 // content if formula. Setting an otherwise numeric result as
351 // string result fouls things up, set result strings only for
352 // documents claiming to be generated by a known good
353 // generator. See tdf#98481
354 if (bGeneratorKnownGood)
355 {
356 svl::SharedString aSS = rStrPool.intern(rValueStr);
357 pCell->SetResultToken(new formula::FormulaStringToken(std::move(aSS)));
358 pCell->ResetDirty();
359 pCell->SetChanged(false);
360 }
361 break;
362 default:
363 ;
364 }
365 }
366}
367
368void processSheetFormulaCells(
369 ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter& rFormatter,
370 const Sequence<ExternalLinkInfo>& rExternalLinks, WorkbookHelper& rWorkbookHelper )
371{
372 if (rItem.mpSharedFormulaEntries && rItem.mpSharedFormulaIDs)
373 applySharedFormulas(rDoc, rFormatter, *rItem.mpSharedFormulaEntries,
374 *rItem.mpSharedFormulaIDs, rWorkbookHelper);
375
376 if (rItem.mpCellFormulas)
377 {
378 CachedTokenArray aCache(rDoc.getDoc());
379 applyCellFormulas(rDoc, aCache, rFormatter, rExternalLinks, *rItem.mpCellFormulas);
380 }
381
382 if (rItem.mpArrayFormulas)
383 applyArrayFormulas(rDoc, rFormatter, rExternalLinks, *rItem.mpArrayFormulas);
384
385 if (rItem.mpCellFormulaValues)
386 applyCellFormulaValues(rDoc, *rItem.mpCellFormulaValues, rWorkbookHelper);
387}
388
389}
390
392 const ScAddress& rAddr,
393 OUString aTokenStr, sal_Int32 nSharedId ) :
394 maAddress(rAddr), maTokenStr(std::move(aTokenStr)), mnSharedId(nSharedId) {}
395
397 const ScAddress& rAddr, sal_Int32 nSharedId,
398 OUString aCellValue, sal_Int32 nValueType ) :
399 maAddress(rAddr), maCellValue(std::move(aCellValue)), mnSharedId(nSharedId), mnValueType(nValueType) {}
400
402 mpCellFormulas(nullptr),
403 mpArrayFormulas(nullptr),
404 mpCellFormulaValues(nullptr),
405 mpSharedFormulaEntries(nullptr),
406 mpSharedFormulaIDs(nullptr) {}
407
409{
410}
411
413{
414 maCellFormulas.resize( nSheets );
415 maCellArrayFormulas.resize( nSheets );
416 maSharedFormulas.resize( nSheets );
417 maSharedFormulaIds.resize( nSheets );
418 maCellFormulaValues.resize( nSheets );
419}
420
422{
423 ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
424
426 rDoc.getDoc().SetAutoNameCache(std::make_unique<ScAutoNameCache>(rDoc.getDoc()));
427 ScExternalRefManager::ApiGuard aExtRefGuard(rDoc.getDoc());
428
429 SCTAB nTabCount = rDoc.getDoc().GetTableCount();
430
431 // Fetch all the formulas to process first.
432 std::vector<SheetItem> aSheetItems;
433 aSheetItems.reserve(nTabCount);
434 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
435 aSheetItems.push_back(getSheetItem(nTab));
436
437 for (SheetItem& rItem : aSheetItems)
438 processSheetFormulaCells(rDoc, rItem, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos(),
439 *this);
440
441 // With formula results being set and not recalculated we need to
442 // force-trigger adding all linked external files to the LinkManager.
444
445 rDoc.getDoc().SetAutoNameCache(nullptr);
446
447 xFormulaBar->setPosition( 1.0 );
448}
449
451{
452 std::scoped_lock aGuard(maMtxData);
453
454 SheetItem aItem;
455
456 if( o3tl::make_unsigned(nTab) >= maCellFormulas.size() )
457 {
458 SAL_WARN( "sc", "Tab " << nTab << " out of bounds " << maCellFormulas.size() );
459 return aItem;
460 }
461
462 if( !maCellFormulas[ nTab ].empty() )
463 aItem.mpCellFormulas = &maCellFormulas[ nTab ];
464 if( !maCellArrayFormulas[ nTab ].empty() )
465 aItem.mpArrayFormulas = &maCellArrayFormulas[ nTab ];
466 if( !maCellFormulaValues[ nTab ].empty() )
468 if( !maSharedFormulas[ nTab ].empty() )
470 if( !maSharedFormulaIds[ nTab ].empty() )
471 aItem.mpSharedFormulaIDs = &maSharedFormulaIds[ nTab ];
472
473 return aItem;
474}
475
477 const ScAddress& rAddress,
478 sal_Int32 nSharedId, const OUString& rTokens )
479{
480 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maSharedFormulas.size() );
481 std::vector<SharedFormulaEntry>& rSharedFormulas = maSharedFormulas[ rAddress.Tab() ];
482 SharedFormulaEntry aEntry(rAddress, rTokens, nSharedId);
483 rSharedFormulas.push_back( aEntry );
484}
485
486void FormulaBuffer::setCellFormula( const ScAddress& rAddress, const OUString& rTokenStr )
487{
488 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maCellFormulas.size() );
489 maCellFormulas[ rAddress.Tab() ].emplace_back( rTokenStr, rAddress );
490}
491
493 const ScAddress& rAddress, sal_Int32 nSharedId, const OUString& rCellValue, sal_Int32 nValueType )
494{
495 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maSharedFormulaIds.size() );
496 maSharedFormulaIds[rAddress.Tab()].emplace_back(rAddress, nSharedId, rCellValue, nValueType);
497}
498
499void FormulaBuffer::setCellArrayFormula( const ScRange& rRangeAddress, const ScAddress& rTokenAddress, const OUString& rTokenStr )
500{
501
502 TokenAddressItem tokenPair( rTokenStr, rTokenAddress );
503 assert( rRangeAddress.aStart.Tab() >= 0 && o3tl::make_unsigned(rRangeAddress.aStart.Tab()) < maCellArrayFormulas.size() );
504 maCellArrayFormulas[ rRangeAddress.aStart.Tab() ].emplace_back( tokenPair, rRangeAddress );
505}
506
508 const ScAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
509{
510 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maCellFormulaValues.size() );
511 FormulaValue aVal;
512 aVal.maAddress = rAddress;
513 aVal.maValueStr = rValueStr;
514 aVal.mnCellType = nCellType;
515 maCellFormulaValues[rAddress.Tab()].push_back(aVal);
516}
517
518}
519
520/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int16 mnValueType
SCTAB Tab() const
Definition: address.hxx:283
bool IsValid() const
Definition: address.hxx:305
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
void SetNumberFormatter(SvNumberFormatter *pFormatter)
Definition: compiler.cxx:311
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4691
Accessor class to ScDocument.
void setMatrixCells(const ScRange &rRange, const ScTokenArray &rArray, formula::FormulaGrammar::Grammar eGrammar)
void setFormulaCell(const ScAddress &rPos, const OUString &rFormula, formula::FormulaGrammar::Grammar eGrammar, const double *pResult=nullptr)
ScDocument & getDoc()
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3640
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:625
SC_DLLPUBLIC void SetAutoNameCache(std::unique_ptr< ScAutoNameCache > pCache)
Definition: document.cxx:6886
SC_DLLPUBLIC void SetNumberFormat(const ScAddress &rPos, sal_uInt32 nNumberFormat)
Definition: document.cxx:3682
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:601
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
SC_DLLPUBLIC const ScFormulaCell * GetFormulaCell(const ScAddress &rPos) const
Definition: document.cxx:3714
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
Use this guard when performing something from the API that might query values from external reference...
void addFilesToLinkManager()
Add all known external files to the LinkManager.
void SetResultDouble(double n)
For import only: set a double result.
void SetNeedNumberFormat(bool bVal)
const ScFormulaCellGroupRef & GetCellGroup() const
void SetChanged(bool b)
void AddRecalcMode(ScRecalcMode)
void SetDirty(bool bDirtyFlag=true)
ScFormulaCellGroupRef CreateCellGroup(SCROW nLen, bool bInvariant)
Turn a non-grouped cell into the top of a grouped cell.
void SetResultToken(const formula::FormulaToken *pToken)
ScAddress aPos
ScAddress aStart
Definition: address.hxx:497
std::unique_ptr< ScTokenArray > Clone() const
Definition: token.cxx:1931
OUString CreateString(sc::TokenStringContext &rCxt, const ScAddress &rPos) const
Create a string representation of formula token array without modifying the internal state of the tok...
Definition: token.cxx:5238
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
virtual ISegmentProgressBarRef createSegment(double fLength) override
std::vector< std::vector< TokenRangeAddressItem > > maCellArrayFormulas
std::vector< std::vector< SharedFormulaDesc > > maSharedFormulaIds
SheetItem getSheetItem(SCTAB nTab)
std::vector< std::vector< TokenAddressItem > > maCellFormulas
void createSharedFormulaMapEntry(const ScAddress &rAddress, sal_Int32 nSharedId, const OUString &rTokens)
void SetSheetCount(SCTAB nSheets)
ensure sizes of vectors matches the number of sheets
void setCellFormulaValue(const ScAddress &rAddress, const OUString &rValueStr, sal_Int32 nCellType)
std::vector< std::vector< FormulaValue > > maCellFormulaValues
void setCellArrayFormula(const ScRange &rRangeAddress, const ScAddress &rTokenAddress, const OUString &)
void setCellFormula(const ScAddress &rAddress, const OUString &)
FormulaBuffer(const WorkbookHelper &rHelper)
std::vector< std::vector< SharedFormulaEntry > > maSharedFormulas
Helper class to provide access to global workbook data.
ScDocumentImport & getDocImport()
SegmentProgressBar & getProgressBar() const
Returns the filter progress bar.
ExternalLinkBuffer & getExternalLinks() const
Returns the external links read from the external links substream.
const ScAddress & getOrigin() const
const ScTokenArray * getTokenArray() const
void set(size_t nSharedId, std::unique_ptr< ScTokenArray > pArray)
const SharedFormulaGroupEntry * getEntry(size_t nSharedId) const
SharedString intern(const OUString &rStr)
ScFormulaCell * mpCell
sc::TokenStringContext maCxt
SCROW mnRow
ColCacheType maCache
void * p
#define SAL_WARN(area, stream)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::shared_ptr< ISegmentProgressBar > ISegmentProgressBarRef
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
sal_Int16 nId
SharedFormulaDesc(const ScAddress &rAddr, sal_Int32 nSharedId, OUString aCellValue, sal_Int32 nValueType)
Represents a shared formula definition.
SharedFormulaEntry(const ScAddress &rAddress, OUString aTokenStr, sal_Int32 nSharedId)
std::vector< FormulaValue > * mpCellFormulaValues
std::vector< TokenRangeAddressItem > * mpArrayFormulas
std::vector< SharedFormulaDesc > * mpSharedFormulaIDs
std::vector< SharedFormulaEntry > * mpSharedFormulaEntries
std::vector< TokenAddressItem > * mpCellFormulas
Context for creating string from an array of formula tokens, used in ScTokenArray::CreateString().
sal_Int16 SCTAB
Definition: types.hxx:22
::boost::intrusive_ptr< ScFormulaCellGroup > ScFormulaCellGroupRef
Definition: types.hxx:43
sal_Int32 SCROW
Definition: types.hxx:17
#define SV_COUNTRY_LANGUAGE_OFFSET