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 bool bGeneratorKnownGood)
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 // Process formulas that use shared formulas.
134 for (const FormulaBuffer::SharedFormulaDesc& rDesc : rCells)
135 {
136 const ScAddress& aPos = rDesc.maAddress;
137 const sc::SharedFormulaGroupEntry* pEntry = aGroups.getEntry(rDesc.mnSharedId);
138 if (!pEntry)
139 continue;
140
141 const ScTokenArray* pArray = pEntry->getTokenArray();
142 assert(pArray);
143 const ScAddress& rOrigin = pEntry->getOrigin();
144 assert(rOrigin.IsValid());
145
146 ScFormulaCell* pCell;
147 // In case of shared-formula along a row, do not let
148 // these cells share the same token objects.
149 // If we do, any reference-updates on these cells
150 // (while editing) will mess things up. Pass the cloned array as a
151 // pointer and not as reference to avoid any further allocation.
152 if (rOrigin.Col() != aPos.Col())
153 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, pArray->Clone());
154 else
155 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, *pArray);
156
157 rDoc.setFormulaCell(aPos, pCell);
158 const bool bNeedNumberFormat = ((rDoc.getDoc().GetNumberFormat(
159 aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET) == 0);
160 if (bNeedNumberFormat)
161 pCell->SetNeedNumberFormat(true);
162
163 if (rDesc.maCellValue.isEmpty())
164 {
165 // No cached cell value. Mark it for re-calculation.
166 pCell->SetDirty();
167 // Recalc even if AutoCalc is disabled. Must be after
168 // SetDirty() as it also calls SetDirtyVar().
169 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
170 continue;
171 }
172
173 // Set cached formula results. For now, we only use boolean,
174 // numeric and string-formula results. Find out how to utilize
175 // cached results of other types.
176 switch (rDesc.mnValueType)
177 {
178 case XML_b:
179 // boolean value.
180 if (bNeedNumberFormat)
181 {
182 rDoc.getDoc().SetNumberFormat( aPos,
183 rDoc.getDoc().GetFormatTable()->GetStandardFormat( SvNumFormatType::LOGICAL));
184 }
185 if (rDesc.maCellValue == "1" || rDesc.maCellValue == "0")
186 pCell->SetResultDouble(rDesc.maCellValue == "1" ? 1.0 : 0.0);
187 else
188 {
189 // Recalc even if AutoCalc is disabled.
190 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
191 }
192 break;
193 case XML_n:
194 // numeric value.
195 pCell->SetResultDouble(rDesc.maCellValue.toDouble());
196 /* TODO: is it on purpose that we never reset dirty here
197 * and thus recalculate anyway if cell was dirty? Or is it
198 * never dirty and therefore set dirty below otherwise? This
199 * is different from the non-shared case in
200 * applyCellFormulaValues(). */
201 break;
202 case XML_str:
203 if (bGeneratorKnownGood)
204 {
205 // See applyCellFormulaValues
206 svl::SharedString aSS = rStrPool.intern(rDesc.maCellValue);
207 pCell->SetResultToken(new formula::FormulaStringToken(std::move(aSS)));
208 // If we don't reset dirty, then e.g. disabling macros makes all cells
209 // that use macro functions to show #VALUE!
210 pCell->ResetDirty();
211 pCell->SetChanged(false);
212 break;
213 }
214 [[fallthrough]];
215 default:
216 // Mark it for re-calculation.
217 pCell->SetDirty();
218 // Recalc even if AutoCalc is disabled. Must be after
219 // SetDirty() as it also calls SetDirtyVar().
220 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
221 }
222 }
223 }
224}
225
226void applyCellFormulas(
227 ScDocumentImport& rDoc, CachedTokenArray& rCache, SvNumberFormatter& rFormatter,
228 const Sequence<ExternalLinkInfo>& rExternalLinks,
229 const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
230{
231 for (const FormulaBuffer::TokenAddressItem& rItem : rCells)
232 {
233 const ScAddress& aPos = rItem.maAddress;
234 CachedTokenArray::Item* p = rCache.get(aPos, rItem.maTokenStr);
235 if (p)
236 {
237 // Use the cached version to avoid re-compilation.
238
239 ScFormulaCell* pCell = nullptr;
240 if (p->mnRow + 1 == aPos.Row())
241 {
242 // Put them in the same formula group.
243 ScFormulaCell& rPrev = *p->mpCell;
244 ScFormulaCellGroupRef xGroup = rPrev.GetCellGroup();
245 if (!xGroup)
246 {
247 // Last cell is not grouped yet. Start a new group.
248 assert(rPrev.aPos.Row() == p->mnRow);
249 xGroup = rPrev.CreateCellGroup(1, false);
250 }
251 ++xGroup->mnLength;
252
253 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, xGroup);
254 }
255 else
256 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, p->mpCell->GetCode()->Clone());
257
258 rDoc.setFormulaCell(aPos, pCell);
259 if (rDoc.getDoc().GetNumberFormat(aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET == 0)
260 pCell->SetNeedNumberFormat(true);
261
262 // Update the cache.
263 p->mnRow = aPos.Row();
264 p->mpCell = pCell;
265 continue;
266 }
267
268 ScCompiler aCompiler(rDoc.getDoc(), aPos, formula::FormulaGrammar::GRAM_OOXML, true, false);
269 aCompiler.SetNumberFormatter(&rFormatter);
270 aCompiler.SetExternalLinks(rExternalLinks);
271 std::unique_ptr<ScTokenArray> pCode = aCompiler.CompileString(rItem.maTokenStr);
272 if (!pCode)
273 continue;
274
275 aCompiler.CompileTokenArray(); // Generate RPN tokens.
276
277 ScFormulaCell* pCell = new ScFormulaCell(rDoc.getDoc(), aPos, std::move(pCode));
278 rDoc.setFormulaCell(aPos, pCell);
279 if (rDoc.getDoc().GetNumberFormat(aPos.Col(), aPos.Row(), aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET == 0)
280 pCell->SetNeedNumberFormat(true);
281 rCache.store(aPos, pCell);
282 }
283}
284
285void applyArrayFormulas(
286 ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
287 const Sequence<ExternalLinkInfo>& rExternalLinks,
288 const std::vector<FormulaBuffer::TokenRangeAddressItem>& rArrays )
289{
290 for (const FormulaBuffer::TokenRangeAddressItem& rAddressItem : rArrays)
291 {
292 const ScAddress& aPos = rAddressItem.maTokenAndAddress.maAddress;
293
295 aComp.SetNumberFormatter(&rFormatter);
296 aComp.SetExternalLinks(rExternalLinks);
297 std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(rAddressItem.maTokenAndAddress.maTokenStr));
298 if (pArray)
299 rDoc.setMatrixCells(rAddressItem.maRange, *pArray, formula::FormulaGrammar::GRAM_OOXML);
300 }
301}
302
303void applyCellFormulaValues(
304 ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector, bool bGeneratorKnownGood )
305{
307
308 for (const FormulaBuffer::FormulaValue& rValue : rVector)
309 {
310 const ScAddress& aCellPos = rValue.maAddress;
311 ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
312 const OUString& rValueStr = rValue.maValueStr;
313 if (!pCell)
314 continue;
315
316 switch (rValue.mnCellType)
317 {
318 case XML_n:
319 {
320 pCell->SetResultDouble(rValueStr.toDouble());
321 pCell->ResetDirty();
322 pCell->SetChanged(false);
323 }
324 break;
325 case XML_str:
326 // Excel uses t="str" for string results (per definition
327 // ECMA-376 18.18.11 ST_CellType (Cell Type) "Cell containing a
328 // formula string.", but that 't' Cell Data Type attribute, "an
329 // enumeration representing the cell's data type", is meant for
330 // the content of the <v> element). We follow that. Other
331 // applications might not and instead use t="str" for the cell
332 // content if formula. Setting an otherwise numeric result as
333 // string result fouls things up, set result strings only for
334 // documents claiming to be generated by a known good
335 // generator. See tdf#98481
336 if (bGeneratorKnownGood)
337 {
338 svl::SharedString aSS = rStrPool.intern(rValueStr);
339 pCell->SetResultToken(new formula::FormulaStringToken(std::move(aSS)));
340 pCell->ResetDirty();
341 pCell->SetChanged(false);
342 }
343 break;
344 default:
345 ;
346 }
347 }
348}
349
350void processSheetFormulaCells(
351 ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter& rFormatter,
352 const Sequence<ExternalLinkInfo>& rExternalLinks, bool bGeneratorKnownGood )
353{
354 if (rItem.mpSharedFormulaEntries && rItem.mpSharedFormulaIDs)
355 applySharedFormulas(rDoc, rFormatter, *rItem.mpSharedFormulaEntries,
356 *rItem.mpSharedFormulaIDs, bGeneratorKnownGood);
357
358 if (rItem.mpCellFormulas)
359 {
360 CachedTokenArray aCache(rDoc.getDoc());
361 applyCellFormulas(rDoc, aCache, rFormatter, rExternalLinks, *rItem.mpCellFormulas);
362 }
363
364 if (rItem.mpArrayFormulas)
365 applyArrayFormulas(rDoc, rFormatter, rExternalLinks, *rItem.mpArrayFormulas);
366
367 if (rItem.mpCellFormulaValues)
368 applyCellFormulaValues(rDoc, *rItem.mpCellFormulaValues, bGeneratorKnownGood);
369}
370
371}
372
374 const ScAddress& rAddr,
375 OUString aTokenStr, sal_Int32 nSharedId ) :
376 maAddress(rAddr), maTokenStr(std::move(aTokenStr)), mnSharedId(nSharedId) {}
377
379 const ScAddress& rAddr, sal_Int32 nSharedId,
380 OUString aCellValue, sal_Int32 nValueType ) :
381 maAddress(rAddr), maCellValue(std::move(aCellValue)), mnSharedId(nSharedId), mnValueType(nValueType) {}
382
384 mpCellFormulas(nullptr),
385 mpArrayFormulas(nullptr),
386 mpCellFormulaValues(nullptr),
387 mpSharedFormulaEntries(nullptr),
388 mpSharedFormulaIDs(nullptr) {}
389
391{
392}
393
395{
396 maCellFormulas.resize( nSheets );
397 maCellArrayFormulas.resize( nSheets );
398 maSharedFormulas.resize( nSheets );
399 maSharedFormulaIds.resize( nSheets );
400 maCellFormulaValues.resize( nSheets );
401}
402
404{
405 ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
406
408 rDoc.getDoc().SetAutoNameCache(std::make_unique<ScAutoNameCache>(rDoc.getDoc()));
409 ScExternalRefManager::ApiGuard aExtRefGuard(rDoc.getDoc());
410
411 SCTAB nTabCount = rDoc.getDoc().GetTableCount();
412
413 // Fetch all the formulas to process first.
414 std::vector<SheetItem> aSheetItems;
415 aSheetItems.reserve(nTabCount);
416 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
417 aSheetItems.push_back(getSheetItem(nTab));
418
419 for (SheetItem& rItem : aSheetItems)
420 processSheetFormulaCells(rDoc, rItem, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos(),
422
423 // With formula results being set and not recalculated we need to
424 // force-trigger adding all linked external files to the LinkManager.
426
427 rDoc.getDoc().SetAutoNameCache(nullptr);
428
429 xFormulaBar->setPosition( 1.0 );
430}
431
433{
434 std::scoped_lock aGuard(maMtxData);
435
436 SheetItem aItem;
437
438 if( o3tl::make_unsigned(nTab) >= maCellFormulas.size() )
439 {
440 SAL_WARN( "sc", "Tab " << nTab << " out of bounds " << maCellFormulas.size() );
441 return aItem;
442 }
443
444 if( !maCellFormulas[ nTab ].empty() )
445 aItem.mpCellFormulas = &maCellFormulas[ nTab ];
446 if( !maCellArrayFormulas[ nTab ].empty() )
447 aItem.mpArrayFormulas = &maCellArrayFormulas[ nTab ];
448 if( !maCellFormulaValues[ nTab ].empty() )
450 if( !maSharedFormulas[ nTab ].empty() )
452 if( !maSharedFormulaIds[ nTab ].empty() )
453 aItem.mpSharedFormulaIDs = &maSharedFormulaIds[ nTab ];
454
455 return aItem;
456}
457
459 const ScAddress& rAddress,
460 sal_Int32 nSharedId, const OUString& rTokens )
461{
462 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maSharedFormulas.size() );
463 std::vector<SharedFormulaEntry>& rSharedFormulas = maSharedFormulas[ rAddress.Tab() ];
464 SharedFormulaEntry aEntry(rAddress, rTokens, nSharedId);
465 rSharedFormulas.push_back( aEntry );
466}
467
468void FormulaBuffer::setCellFormula( const ScAddress& rAddress, const OUString& rTokenStr )
469{
470 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maCellFormulas.size() );
471 maCellFormulas[ rAddress.Tab() ].emplace_back( rTokenStr, rAddress );
472}
473
475 const ScAddress& rAddress, sal_Int32 nSharedId, const OUString& rCellValue, sal_Int32 nValueType )
476{
477 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maSharedFormulaIds.size() );
478 maSharedFormulaIds[rAddress.Tab()].emplace_back(rAddress, nSharedId, rCellValue, nValueType);
479}
480
481void FormulaBuffer::setCellArrayFormula( const ScRange& rRangeAddress, const ScAddress& rTokenAddress, const OUString& rTokenStr )
482{
483
484 TokenAddressItem tokenPair( rTokenStr, rTokenAddress );
485 assert( rRangeAddress.aStart.Tab() >= 0 && o3tl::make_unsigned(rRangeAddress.aStart.Tab()) < maCellArrayFormulas.size() );
486 maCellArrayFormulas[ rRangeAddress.aStart.Tab() ].emplace_back( tokenPair, rRangeAddress );
487}
488
490 const ScAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
491{
492 assert( rAddress.Tab() >= 0 && o3tl::make_unsigned(rAddress.Tab()) < maCellFormulaValues.size() );
493 FormulaValue aVal;
494 aVal.maAddress = rAddress;
495 aVal.maValueStr = rValueStr;
496 aVal.mnCellType = nCellType;
497 maCellFormulaValues[rAddress.Tab()].push_back(aVal);
498}
499
500}
501
502/* 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:3689
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:633
SC_DLLPUBLIC void SetAutoNameCache(std::unique_ptr< ScAutoNameCache > pCache)
Definition: document.cxx:7058
SC_DLLPUBLIC void SetNumberFormat(const ScAddress &rPos, sal_uInt32 nNumberFormat)
Definition: document.cxx:3735
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:603
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
SC_DLLPUBLIC const ScFormulaCell * GetFormulaCell(const ScAddress &rPos) const
Definition: document.cxx:3769
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:317
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:5217
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.
bool isGeneratorKnownGood() const
Returns true when reading a file generated by a known good generator.
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