LibreOffice Module sc (master) 1
pivotcachebuffer.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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <pivotcachebuffer.hxx>
21
22#include <com/sun/star/beans/XPropertySet.hpp>
23#include <com/sun/star/container/XIndexAccess.hpp>
24#include <com/sun/star/container/XNameAccess.hpp>
25#include <com/sun/star/container/XNamed.hpp>
26#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
27#include <com/sun/star/sheet/DataPilotFieldGroupInfo.hpp>
28#include <com/sun/star/sheet/XDataPilotFieldGrouping.hpp>
29
31#include <o3tl/safeint.hxx>
32#include <osl/diagnose.h>
33#include <sal/log.hxx>
38#include <oox/token/namespaces.hxx>
39#include <oox/token/properties.hxx>
40#include <oox/token/tokens.hxx>
41#include <tools/diagnose_ex.h>
42#include <defnamesbuffer.hxx>
44#include <sheetdatabuffer.hxx>
45#include <tablebuffer.hxx>
46#include <unitconverter.hxx>
47#include <worksheetbuffer.hxx>
48#include <dpobject.hxx>
49#include <dpsave.hxx>
50#include <tools/datetime.hxx>
51#include <addressconverter.hxx>
52#include <biffhelper.hxx>
53
54namespace oox::xls {
55
56using namespace ::com::sun::star::container;
57using namespace ::com::sun::star::sheet;
58using namespace ::com::sun::star::uno;
59
60using ::oox::core::Relations;
61
62namespace {
63
64const sal_uInt16 BIFF12_PCDFIELD_SERVERFIELD = 0x0001;
65const sal_uInt16 BIFF12_PCDFIELD_NOUNIQUEITEMS = 0x0002;
66const sal_uInt16 BIFF12_PCDFIELD_DATABASEFIELD = 0x0004;
67const sal_uInt16 BIFF12_PCDFIELD_HASCAPTION = 0x0008;
68const sal_uInt16 BIFF12_PCDFIELD_MEMBERPROPFIELD = 0x0010;
69const sal_uInt16 BIFF12_PCDFIELD_HASFORMULA = 0x0100;
70const sal_uInt16 BIFF12_PCDFIELD_HASPROPERTYNAME = 0x0200;
71
72const sal_uInt16 BIFF12_PCDFSITEMS_HASSEMIMIXED = 0x0001;
73const sal_uInt16 BIFF12_PCDFSITEMS_HASNONDATE = 0x0002;
74const sal_uInt16 BIFF12_PCDFSITEMS_HASDATE = 0x0004;
75const sal_uInt16 BIFF12_PCDFSITEMS_HASSTRING = 0x0008;
76const sal_uInt16 BIFF12_PCDFSITEMS_HASBLANK = 0x0010;
77const sal_uInt16 BIFF12_PCDFSITEMS_HASMIXED = 0x0020;
78const sal_uInt16 BIFF12_PCDFSITEMS_ISNUMERIC = 0x0040;
79const sal_uInt16 BIFF12_PCDFSITEMS_ISINTEGER = 0x0080;
80const sal_uInt16 BIFF12_PCDFSITEMS_HASLONGTEXT = 0x0200;
81
82const sal_uInt16 BIFF12_PCITEM_ARRAY_DOUBLE = 0x0001;
83const sal_uInt16 BIFF12_PCITEM_ARRAY_STRING = 0x0002;
84const sal_uInt16 BIFF12_PCITEM_ARRAY_ERROR = 0x0010;
85const sal_uInt16 BIFF12_PCITEM_ARRAY_DATE = 0x0020;
86
87const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOSTART = 0x01;
88const sal_uInt8 BIFF12_PCDFRANGEPR_AUTOEND = 0x02;
89const sal_uInt8 BIFF12_PCDFRANGEPR_DATEGROUP = 0x04;
90
91const sal_uInt8 BIFF12_PCDEFINITION_SAVEDATA = 0x01;
92const sal_uInt8 BIFF12_PCDEFINITION_INVALID = 0x02;
93const sal_uInt8 BIFF12_PCDEFINITION_REFRESHONLOAD = 0x04;
94const sal_uInt8 BIFF12_PCDEFINITION_OPTIMIZEMEMORY = 0x08;
95const sal_uInt8 BIFF12_PCDEFINITION_ENABLEREFRESH = 0x10;
96const sal_uInt8 BIFF12_PCDEFINITION_BACKGROUNDQUERY = 0x20;
97const sal_uInt8 BIFF12_PCDEFINITION_UPGRADEONREFR = 0x40;
98const sal_uInt8 BIFF12_PCDEFINITION_TUPLECACHE = 0x80;
99
100const sal_uInt8 BIFF12_PCDEFINITION_HASUSERNAME = 0x01;
101const sal_uInt8 BIFF12_PCDEFINITION_HASRELID = 0x02;
102const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTSUBQUERY = 0x04;
103const sal_uInt8 BIFF12_PCDEFINITION_SUPPORTDRILL = 0x08;
104
105const sal_uInt8 BIFF12_PCDWBSOURCE_HASRELID = 0x01;
106const sal_uInt8 BIFF12_PCDWBSOURCE_HASSHEET = 0x02;
107
108
116void lclAdjustBinDateTime( css::util::DateTime& orDateTime )
117{
118 if( (orDateTime.Year == 1900) && (orDateTime.Month <= 2) )
119 {
120 OSL_ENSURE( (orDateTime.Month == 1) || ((orDateTime.Month == 2) && (orDateTime.Day > 0)), "lclAdjustBinDateTime - invalid date" );
121 switch( orDateTime.Month )
122 {
123 case 2: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; --orDateTime.Month; } break;
124 case 1: if( orDateTime.Day > 1 ) --orDateTime.Day; else { orDateTime.Day += 30; orDateTime.Month = 12; --orDateTime.Year; } break;
125 }
126 }
127}
128
129} // namespace
130
132 mnType( XML_m ), mbUnused( false )
133{
134}
135
137{
138 maValue <<= rAttribs.getXString( XML_v, OUString() );
139 mnType = XML_s;
140}
141
143{
144 maValue <<= rAttribs.getDouble( XML_v, 0.0 );
145 mnType = XML_n;
146 mbUnused = rAttribs.getBool( XML_u, false );
147}
148
150{
151 maValue <<= rAttribs.getDateTime( XML_v, css::util::DateTime() );
152 mnType = XML_d;
153}
154
156{
157 maValue <<= rAttribs.getBool( XML_v, false );
158 mnType = XML_b;
159}
160
162{
163 maValue <<= rAttribs.getXString( XML_v, OUString() );
164 mnType = XML_e;
165}
166
168{
169 maValue <<= rAttribs.getInteger( XML_v, -1 );
170 mnType = XML_x;
171}
172
174{
176 mnType = XML_s;
177}
178
180{
181 maValue <<= rStrm.readDouble();
182 mnType = XML_n;
183}
184
186{
187 css::util::DateTime aDateTime;
188 aDateTime.Year = rStrm.readuInt16();
189 aDateTime.Month = rStrm.readuInt16();
190 aDateTime.Day = rStrm.readuInt8();
191 aDateTime.Hours = rStrm.readuInt8();
192 aDateTime.Minutes = rStrm.readuInt8();
193 aDateTime.Seconds = rStrm.readuInt8();
194 lclAdjustBinDateTime( aDateTime );
195 maValue <<= aDateTime;
196 mnType = XML_d;
197}
198
200{
201 maValue <<= (rStrm.readuInt8() != 0);
202 mnType = XML_b;
203}
204
206{
207 maValue <<= rUnitConverter.calcErrorString(rStrm.readuInt8());
208 mnType = XML_e;
209}
210
212{
213 maValue <<= rStrm.readInt32();
214 mnType = XML_x;
215}
216
217void PivotCacheItem::setStringValue( const OUString& sString )
218{
219 mnType = XML_s;
220 maValue <<= sString;
221}
222
224{
225 switch( mnType )
226 {
227 case XML_m: return OUString();
228 case XML_s: return maValue.get< OUString >();
229 case XML_n: return OUString::number( maValue.get< double >() ); // !TODO
230 case XML_i: return OUString::number( maValue.get< sal_Int32 >() );
231 case XML_d: return OUString(); // !TODO
232 case XML_b: return OUString::boolean( maValue.get< bool >() ); // !TODO
233 case XML_e: return OUString(); // !TODO
234 }
235 OSL_FAIL( "PivotCacheItem::getName - invalid data type" );
236 return OUString();
237}
238
239OUString PivotCacheItem::getFormattedName(const ScDPSaveDimension& rSaveDim, ScDPObject* pObj, const DateTime& rNullDate) const
240{
241 switch( mnType )
242 {
243 case XML_m: return OUString();
244 case XML_s: return maValue.get< OUString >();
245 case XML_n: return pObj->GetFormattedString(rSaveDim.GetName(), maValue.get<double>());
246 case XML_i: return pObj->GetFormattedString(rSaveDim.GetName(), static_cast<double>(maValue.get< sal_Int32 >()));
247 case XML_b: return pObj->GetFormattedString(rSaveDim.GetName(), static_cast<double>(maValue.get< bool >()));
248 case XML_d: return pObj->GetFormattedString(rSaveDim.GetName(), maValue.get< css::util::DateTime >() - rNullDate);
249 case XML_e: return maValue.get< OUString >();
250 }
251 OSL_FAIL( "PivotCacheItem::getFormattedName - invalid data type" );
252 return OUString();
253}
254
256 WorkbookHelper( rHelper )
257{
258}
259
260void PivotCacheItemList::importItem( sal_Int32 nElement, const AttributeList& rAttribs )
261{
262 PivotCacheItem& rItem = createItem();
263 switch( nElement )
264 {
265 case XLS_TOKEN( m ): break;
266 case XLS_TOKEN( s ): rItem.readString( rAttribs ); break;
267 case XLS_TOKEN( n ): rItem.readNumeric( rAttribs ); break;
268 case XLS_TOKEN( d ): rItem.readDate( rAttribs ); break;
269 case XLS_TOKEN( b ): rItem.readBool( rAttribs ); break;
270 case XLS_TOKEN( e ): rItem.readError( rAttribs ); break;
271 default: OSL_FAIL( "PivotCacheItemList::importItem - unknown element type" );
272 }
273}
274
276{
277 if( nRecId == BIFF12_ID_PCITEM_ARRAY )
278 {
280 return;
281 }
282
283 PivotCacheItem& rItem = createItem();
284 switch( nRecId )
285 {
287 case BIFF12_ID_PCITEMA_MISSING: break;
289 case BIFF12_ID_PCITEMA_STRING: rItem.readString( rStrm ); break;
291 case BIFF12_ID_PCITEMA_DOUBLE: rItem.readDouble( rStrm ); break;
293 case BIFF12_ID_PCITEMA_DATE: rItem.readDate( rStrm ); break;
295 case BIFF12_ID_PCITEMA_BOOL: rItem.readBool( rStrm ); break;
298 default: OSL_FAIL( "PivotCacheItemList::importItem - unknown record type" );
299 }
300}
301
302const PivotCacheItem* PivotCacheItemList::getCacheItem( sal_Int32 nItemIdx ) const
303{
304 return ContainerHelper::getVectorElement( maItems, nItemIdx );
305}
306
308{
309 for( const auto& [rId, rCaption] : vCaptions )
310 {
311 if ( o3tl::make_unsigned( rId ) < maItems.size() )
312 maItems[ rId ].setStringValue( rCaption );
313 }
314}
315
316void PivotCacheItemList::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
317{
318 orItemNames.clear();
319 orItemNames.reserve( maItems.size() );
320 for( const auto& rItem : maItems )
321 orItemNames.push_back( rItem.getName() );
322}
323
324// private --------------------------------------------------------------------
325
327{
328 maItems.emplace_back();
329 return maItems.back();
330}
331
333{
334 sal_uInt16 nType = rStrm.readuInt16();
335 sal_Int32 nCount = rStrm.readInt32();
336 for( sal_Int32 nIdx = 0; !rStrm.isEof() && (nIdx < nCount); ++nIdx )
337 {
338 switch( nType )
339 {
340 case BIFF12_PCITEM_ARRAY_DOUBLE: createItem().readDouble( rStrm ); break;
341 case BIFF12_PCITEM_ARRAY_STRING: createItem().readString( rStrm ); break;
342 case BIFF12_PCITEM_ARRAY_ERROR: createItem().readError(rStrm, getUnitConverter()); break;
343 case BIFF12_PCITEM_ARRAY_DATE: createItem().readDate( rStrm ); break;
344 default:
345 OSL_FAIL( "PivotCacheItemList::importArray - unknown data type" );
346 return;
347 }
348 }
349}
350
352 mnNumFmtId( 0 ),
353 mnSqlType( 0 ),
354 mnHierarchy( 0 ),
355 mnLevel( 0 ),
356 mnMappingCount( 0 ),
357 mbDatabaseField( true ),
358 mbServerField( false ),
359 mbUniqueList( true ),
360 mbMemberPropField( false )
361{
362}
363
365 mbHasSemiMixed( true ),
366 mbHasNonDate( true ),
367 mbHasDate( false ),
368 mbHasString( true ),
369 mbHasBlank( false ),
370 mbHasMixed( false ),
371 mbIsNumeric( false ),
372 mbIsInteger( false ),
373 mbHasLongText( false )
374{
375}
376
378 mfStartValue( 0.0 ),
379 mfEndValue( 0.0 ),
380 mfInterval( 1.0 ),
381 mnParentField( -1 ),
382 mnBaseField( -1 ),
383 mnGroupBy( XML_range ),
384 mbRangeGroup( false ),
385 mbDateGroup( false ),
386 mbAutoStart( true ),
387 mbAutoEnd( true )
388{
389}
390
392{
393 static const sal_Int32 spnGroupBy[] = { XML_range,
394 XML_seconds, XML_minutes, XML_hours, XML_days, XML_months, XML_quarters, XML_years };
395 mnGroupBy = STATIC_ARRAY_SELECT( spnGroupBy, nGroupBy, XML_range );
396}
397
398PivotCacheField::PivotCacheField( const WorkbookHelper& rHelper, bool bIsDatabaseField ) :
399 WorkbookHelper( rHelper ),
400 maSharedItems( rHelper ),
401 maGroupItems( rHelper )
402{
403 maFieldModel.mbDatabaseField = bIsDatabaseField;
404}
405
407{
408 maFieldModel.maName = rAttribs.getXString( XML_name, OUString() );
409 maFieldModel.maCaption = rAttribs.getXString( XML_caption, OUString() );
410 maFieldModel.maPropertyName = rAttribs.getXString( XML_propertyName, OUString() );
411 maFieldModel.maFormula = rAttribs.getXString( XML_formula, OUString() );
412 maFieldModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
413 maFieldModel.mnSqlType = rAttribs.getInteger( XML_sqlType, 0 );
414 maFieldModel.mnHierarchy = rAttribs.getInteger( XML_hierarchy, 0 );
415 maFieldModel.mnLevel = rAttribs.getInteger( XML_level, 0 );
416 maFieldModel.mnMappingCount = rAttribs.getInteger( XML_mappingCount, 0 );
417 maFieldModel.mbDatabaseField = rAttribs.getBool( XML_databaseField, true );
418 maFieldModel.mbServerField = rAttribs.getBool( XML_serverField, false );
419 maFieldModel.mbUniqueList = rAttribs.getBool( XML_uniqueList, true );
420 maFieldModel.mbMemberPropField = rAttribs.getBool( XML_memberPropertyField, false );
421}
422
424{
425 OSL_ENSURE( maSharedItems.empty(), "PivotCacheField::importSharedItems - multiple shared items elements" );
426 maSharedItemsModel.mbHasSemiMixed = rAttribs.getBool( XML_containsSemiMixedTypes, true );
427 maSharedItemsModel.mbHasNonDate = rAttribs.getBool( XML_containsNonDate, true );
428 maSharedItemsModel.mbHasDate = rAttribs.getBool( XML_containsDate, false );
429 maSharedItemsModel.mbHasString = rAttribs.getBool( XML_containsString, true );
430 maSharedItemsModel.mbHasBlank = rAttribs.getBool( XML_containsBlank, false );
431 maSharedItemsModel.mbHasMixed = rAttribs.getBool( XML_containsMixedTypes, false );
432 maSharedItemsModel.mbIsNumeric = rAttribs.getBool( XML_containsNumber, false );
433 maSharedItemsModel.mbIsInteger = rAttribs.getBool( XML_containsInteger, false );
434 maSharedItemsModel.mbHasLongText = rAttribs.getBool( XML_longText, false );
435}
436
437void PivotCacheField::importSharedItem( sal_Int32 nElement, const AttributeList& rAttribs )
438{
439 maSharedItems.importItem( nElement, rAttribs );
440}
441
443{
444 maFieldGroupModel.mnParentField = rAttribs.getInteger( XML_par, -1 );
445 maFieldGroupModel.mnBaseField = rAttribs.getInteger( XML_base, -1 );
446}
447
449{
450 maFieldGroupModel.maStartDate = rAttribs.getDateTime( XML_startDate, css::util::DateTime() );
451 maFieldGroupModel.maEndDate = rAttribs.getDateTime( XML_endDate, css::util::DateTime() );
452 maFieldGroupModel.mfStartValue = rAttribs.getDouble( XML_startNum, 0.0 );
453 maFieldGroupModel.mfEndValue = rAttribs.getDouble( XML_endNum, 0.0 );
454 maFieldGroupModel.mfInterval = rAttribs.getDouble( XML_groupInterval, 1.0 );
455 maFieldGroupModel.mnGroupBy = rAttribs.getToken( XML_groupBy, XML_range );
458 maFieldGroupModel.mbAutoStart = rAttribs.getBool( XML_autoStart, true );
459 maFieldGroupModel.mbAutoEnd = rAttribs.getBool( XML_autoEnd, true );
460}
461
462void PivotCacheField::importDiscretePrItem( sal_Int32 nElement, const AttributeList& rAttribs )
463{
464 OSL_ENSURE( nElement == XLS_TOKEN( x ), "PivotCacheField::importDiscretePrItem - unexpected element" );
465 if( nElement == XLS_TOKEN( x ) )
466 maDiscreteItems.push_back( rAttribs.getInteger( XML_v, -1 ) );
467}
468
469void PivotCacheField::importGroupItem( sal_Int32 nElement, const AttributeList& rAttribs )
470{
471 maGroupItems.importItem( nElement, rAttribs );
472}
473
475{
476 sal_uInt16 nFlags;
477 nFlags = rStrm.readuInt16();
478 maFieldModel.mnNumFmtId = rStrm.readInt32();
479 maFieldModel.mnSqlType = rStrm.readInt16();
480 maFieldModel.mnHierarchy = rStrm.readInt32();
481 maFieldModel.mnLevel = rStrm.readInt32();
482 maFieldModel.mnMappingCount = rStrm.readInt32();
484 if( getFlag( nFlags, BIFF12_PCDFIELD_HASCAPTION ) )
486 if( getFlag( nFlags, BIFF12_PCDFIELD_HASFORMULA ) )
487 rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
489 rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
490 if( getFlag( nFlags, BIFF12_PCDFIELD_HASPROPERTYNAME ) )
492
493 maFieldModel.mbDatabaseField = getFlag( nFlags, BIFF12_PCDFIELD_DATABASEFIELD );
494 maFieldModel.mbServerField = getFlag( nFlags, BIFF12_PCDFIELD_SERVERFIELD );
495 maFieldModel.mbUniqueList = !getFlag( nFlags, BIFF12_PCDFIELD_NOUNIQUEITEMS );
496 maFieldModel.mbMemberPropField = getFlag( nFlags, BIFF12_PCDFIELD_MEMBERPROPFIELD );
497}
498
500{
501 sal_uInt16 nFlags;
502 nFlags = rStrm.readuInt16();
503 maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSEMIMIXED );
504 maSharedItemsModel.mbHasNonDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASNONDATE );
505 maSharedItemsModel.mbHasDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASDATE );
506 maSharedItemsModel.mbHasString = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSTRING );
507 maSharedItemsModel.mbHasBlank = getFlag( nFlags, BIFF12_PCDFSITEMS_HASBLANK );
508 maSharedItemsModel.mbHasMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASMIXED );
509 maSharedItemsModel.mbIsNumeric = getFlag( nFlags, BIFF12_PCDFSITEMS_ISNUMERIC );
510 maSharedItemsModel.mbIsInteger = getFlag( nFlags, BIFF12_PCDFSITEMS_ISINTEGER );
511 maSharedItemsModel.mbHasLongText = getFlag( nFlags, BIFF12_PCDFSITEMS_HASLONGTEXT );
512}
513
515{
516 maSharedItems.importItem( nRecId, rStrm );
517}
518
520{
522 maFieldGroupModel.mnBaseField = rStrm.readInt32();
523}
524
526{
527 sal_uInt8 nGroupBy, nFlags;
528 nGroupBy = rStrm.readuChar();
529 nFlags = rStrm.readuChar();
530 maFieldGroupModel.mfStartValue = rStrm.readDouble();
531 maFieldGroupModel.mfEndValue = rStrm.readDouble();
532 maFieldGroupModel.mfInterval = rStrm.readDouble();
533
536 maFieldGroupModel.mbDateGroup = getFlag( nFlags, BIFF12_PCDFRANGEPR_DATEGROUP );
537 maFieldGroupModel.mbAutoStart = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOSTART );
538 maFieldGroupModel.mbAutoEnd = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOEND );
539
540 OSL_ENSURE( maFieldGroupModel.mbDateGroup == (maFieldGroupModel.mnGroupBy != XML_range), "PivotCacheField::importPCDFRangePr - wrong date flag" );
542 {
545 }
546}
547
549{
550 OSL_ENSURE( nRecId == BIFF12_ID_PCITEM_INDEX, "PivotCacheField::importPCDFDiscretePrItem - unexpected record" );
551 if( nRecId == BIFF12_ID_PCITEM_INDEX )
552 maDiscreteItems.push_back( rStrm.readInt32() );
553}
554
556{
557 maGroupItems.importItem( nRecId, rStrm );
558}
559
560const PivotCacheItem* PivotCacheField::getCacheItem( sal_Int32 nItemIdx ) const
561{
562 if( hasGroupItems() )
563 return maGroupItems.getCacheItem( nItemIdx );
564 if( hasSharedItems() )
565 return maSharedItems.getCacheItem( nItemIdx );
566 return nullptr;
567}
568
570{
571 if( hasGroupItems() )
572 maGroupItems.applyItemCaptions( vCaptions );
573 if( hasSharedItems() )
574 maSharedItems.applyItemCaptions( vCaptions );
575}
576
577void PivotCacheField::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
578{
579 if( hasGroupItems() )
580 maGroupItems.getCacheItemNames( orItemNames );
581 else if( hasSharedItems() )
582 maSharedItems.getCacheItemNames( orItemNames );
583}
584
586{
587 if( hasGroupItems() )
588 return maGroupItems;
589 return maSharedItems;
590}
591
592void PivotCacheField::convertNumericGrouping( const Reference< XDataPilotField >& rxDPField ) const
593{
594 OSL_ENSURE( hasGroupItems() && hasNumericGrouping(), "PivotCacheField::convertNumericGrouping - not a numeric group field" );
595 PropertySet aPropSet( rxDPField );
596 if( hasGroupItems() && hasNumericGrouping() && aPropSet.is() )
597 {
598 DataPilotFieldGroupInfo aGroupInfo;
599 aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
600 aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
601 aGroupInfo.HasDateValues = false;
602 aGroupInfo.Start = maFieldGroupModel.mfStartValue;
603 aGroupInfo.End = maFieldGroupModel.mfEndValue;
604 aGroupInfo.Step = maFieldGroupModel.mfInterval;
605 aGroupInfo.GroupBy = 0;
606 aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
607 }
608}
609
610OUString PivotCacheField::createDateGroupField( const Reference< XDataPilotField >& rxBaseDPField ) const
611{
612 OSL_ENSURE( hasGroupItems() && hasDateGrouping(), "PivotCacheField::createDateGroupField - not a numeric group field" );
613 Reference< XDataPilotField > xDPGroupField;
614 PropertySet aPropSet( rxBaseDPField );
615 if( hasGroupItems() && hasDateGrouping() && aPropSet.is() )
616 {
617 bool bDayRanges = (maFieldGroupModel.mnGroupBy == XML_days) && (maFieldGroupModel.mfInterval >= 2.0);
618
619 DataPilotFieldGroupInfo aGroupInfo;
620 aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
621 aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
622 aGroupInfo.HasDateValues = true;
625 aGroupInfo.Step = bDayRanges ? maFieldGroupModel.mfInterval : 0.0;
626
627 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
629 {
630 case XML_years: aGroupInfo.GroupBy = YEARS; break;
631 case XML_quarters: aGroupInfo.GroupBy = QUARTERS; break;
632 case XML_months: aGroupInfo.GroupBy = MONTHS; break;
633 case XML_days: aGroupInfo.GroupBy = DAYS; break;
634 case XML_hours: aGroupInfo.GroupBy = HOURS; break;
635 case XML_minutes: aGroupInfo.GroupBy = MINUTES; break;
636 case XML_seconds: aGroupInfo.GroupBy = SECONDS; break;
637 default: OSL_FAIL( "PivotCacheField::convertRangeGrouping - unknown date/time interval" );
638 }
639
640 try
641 {
642 Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY_THROW );
643 xDPGroupField = xDPGrouping->createDateGroup( aGroupInfo );
644 }
645 catch( Exception& )
646 {
647 }
648 }
649
650 Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
651 return xFieldName.is() ? xFieldName->getName() : OUString();
652}
653
654OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotField >& rxBaseDPField, const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames ) const
655{
656 SAL_WARN_IF( !hasGroupItems() || maDiscreteItems.empty(), "sc", "PivotCacheField::createParentGroupField - not a group field" );
657 SAL_WARN_IF( maDiscreteItems.size() != orItemNames.size(), "sc", "PivotCacheField::createParentGroupField - number of item names does not match grouping info" );
658 Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY );
659 if( !xDPGrouping.is() ) return OUString();
660
661 // map the group item indexes from maGroupItems to all item indexes from maDiscreteItems
662 std::vector< std::vector<sal_Int32> > aItemMap( maGroupItems.size() );
663 sal_Int32 nIndex = -1;
664 for( const auto& rDiscreteItem : maDiscreteItems )
665 {
666 ++nIndex;
667 if( std::vector<sal_Int32>* pItems = ContainerHelper::getVectorElementAccess( aItemMap, rDiscreteItem ) )
668 {
669 if ( const PivotCacheItem* pItem = rBaseCacheField.getCacheItems().getCacheItem( nIndex ) )
670 {
671 // Skip unspecified or unused entries or errors
672 if ( pItem->isUnused() || ( pItem->getType() == XML_m ) || ( pItem->getType() == XML_e ) )
673 continue;
674 }
675 pItems->push_back( nIndex );
676 }
677 }
678
679 // process all groups
680 Reference< XDataPilotField > xDPGroupField;
681 nIndex = 0;
682 for( const auto& rItems : aItemMap )
683 {
684 SAL_WARN_IF( rItems.empty(), "sc", "PivotCacheField::createParentGroupField - item/group should not be empty" );
685 if( !rItems.empty() )
686 {
687 /* Insert the names of the items that are part of this group. Calc
688 expects the names of the members of the field whose members are
689 grouped (which may be the names of groups too). Excel provides
690 the names of the base field items instead (no group names
691 involved). Therefore, the passed collection of current item
692 names as they are already grouped is used here to resolve the
693 item names. */
694 ::std::vector< OUString > aMembers;
695 for( auto i : rItems )
696 if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, i ) )
697 if( ::std::find( aMembers.begin(), aMembers.end(), pName->maGroupName ) == aMembers.end() )
698 aMembers.push_back( pName->maGroupName );
699
700 /* Check again, that this is not just a group that is not grouped
701 further with other items. */
702 if( !aMembers.empty() ) try
703 {
704 // only the first call of createNameGroup() returns the new field
705 Reference< XDataPilotField > xDPNewField = xDPGrouping->createNameGroup( comphelper::containerToSequence( aMembers ) );
706 SAL_WARN_IF( xDPGroupField.is() == xDPNewField.is(), "sc", "PivotCacheField::createParentGroupField - missing group field" );
707 if( !xDPGroupField.is() )
708 xDPGroupField = xDPNewField;
709
710 // get current grouping info
711 DataPilotFieldGroupInfo aGroupInfo;
712 PropertySet aPropSet( xDPGroupField );
713 aPropSet.getProperty( aGroupInfo, PROP_GroupInfo );
714
715 /* Find the group object and the auto-generated group name.
716 The returned field contains all groups derived from the
717 previous field if that is grouped too. To find the correct
718 group, the first item used to create the group is searched.
719 Calc provides the original item names of the base field
720 when the group is querried for its members. Its does not
721 provide the names of members that are already groups in the
722 field used to create the new groups. (Is this a bug?)
723 Therefore, a name from the passed list of original item
724 names is used to find the correct group. */
725 OUString aFirstItem;
726 if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, rItems.front() ) )
727 aFirstItem = pName->maOrigName;
728 Reference< XNamed > xGroupName;
729 OUString aAutoName;
730 Reference< XIndexAccess > xGroupsIA( aGroupInfo.Groups, UNO_QUERY_THROW );
731 for( sal_Int32 nIdx = 0, nCount = xGroupsIA->getCount(); (nIdx < nCount) && (aAutoName.isEmpty()); ++nIdx ) try
732 {
733 Reference< XNameAccess > xItemsNA( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
734 if( xItemsNA->hasByName( aFirstItem ) )
735 {
736 xGroupName.set( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
737 aAutoName = xGroupName->getName();
738 }
739 }
740 catch( Exception const & )
741 {
742 TOOLS_WARN_EXCEPTION("sc", "PivotCacheField::createParentGroupField" );
743 }
744 SAL_WARN_IF( aAutoName.isEmpty(), "sc", "PivotCacheField::createParentGroupField - cannot find auto-generated group name" );
745
746 // get the real group name from the list of group items
747 OUString aGroupName;
748 if( const PivotCacheItem* pGroupItem = maGroupItems.getCacheItem( nIndex ) )
749 aGroupName = pGroupItem->getName();
750 SAL_WARN_IF( aGroupName.isEmpty(), "sc", "PivotCacheField::createParentGroupField - cannot find group name" );
751 if( aGroupName.isEmpty() )
752 aGroupName = aAutoName;
753
754 if( xGroupName.is() && !aGroupName.isEmpty() )
755 {
756 // replace the auto-generated group name with the real name
757 if( aAutoName != aGroupName )
758 {
759 xGroupName->setName( aGroupName );
760 aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
761 }
762 // replace original item names in passed vector with group name
763 for( auto i : rItems )
765 pName->maGroupName = aGroupName;
766 }
767 }
768 catch( Exception const & )
769 {
770 TOOLS_WARN_EXCEPTION("sc", "PivotCacheField::createParentGroupField" );
771 }
772 }
773 ++nIndex;
774 }
775
776 Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
777 return xFieldName.is() ? xFieldName->getName() : OUString();
778}
779
780void PivotCacheField::writeSourceHeaderCell( const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
781{
782 CellModel aModel;
783 aModel.maCellAddr = ScAddress( SCCOL( nCol ), SCROW( nRow ), rSheetHelper.getSheetIndex() );
784 rSheetHelper.getSheetData().setStringCell( aModel, maFieldModel.maName );
785}
786
787void PivotCacheField::writeSourceDataCell( const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
788{
789 bool bHasIndex = rItem.getType() == XML_x;
790 OSL_ENSURE( bHasIndex != maSharedItems.empty(), "PivotCacheField::writeSourceDataCell - shared items missing or not expected" );
791 if( bHasIndex )
792 writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem.getValue().get< sal_Int32 >() );
793 else
794 writeItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem );
795}
796
797void PivotCacheField::importPCRecordItem( SequenceInputStream& rStrm, const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
798{
799 if( hasSharedItems() )
800 {
801 writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rStrm.readInt32() );
802 }
803 else
804 {
805 PivotCacheItem aItem;
807 aItem.readDouble( rStrm );
809 aItem.readDate( rStrm );
810 else
811 aItem.readString( rStrm );
812 writeItemToSourceDataCell( rSheetHelper, nCol, nRow, aItem );
813 }
814}
815
816// private --------------------------------------------------------------------
817
819 sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem )
820{
821 if( rItem.getType() == XML_m )
822 return;
823
824 CellModel aModel;
825 aModel.maCellAddr = ScAddress( SCCOL( nCol ), SCROW( nRow ), rSheetHelper.getSheetIndex() );
826 SheetDataBuffer& rSheetData = rSheetHelper.getSheetData();
827 switch( rItem.getType() )
828 {
829 case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() ); break;
830 case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() ); break;
831 case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() ); break;
832 case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< css::util::DateTime >() ); break;
833 case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() ); break;
834 case XML_e: rSheetData.setErrorCell(aModel, rItem.getValue().get<OUString>()); break;
835 default: OSL_FAIL( "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" );
836 }
837}
838
840 const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx ) const
841{
842 if( const PivotCacheItem* pCacheItem = maSharedItems.getCacheItem( nItemIdx ) )
843 writeItemToSourceDataCell( rSheetHelper, nCol, nRow, *pCacheItem );
844}
845
847 mfRefreshedDate( 0.0 ),
848 mnRecords( 0 ),
849 mnMissItemsLimit( 0 ),
850 mbInvalid( false ),
851 mbSaveData( true ),
852 mbRefreshOnLoad( false ),
853 mbOptimizeMemory( false ),
854 mbEnableRefresh( true ),
855 mbBackgroundQuery( false ),
856 mbUpgradeOnRefresh( false ),
857 mbTupleCache( false ),
858 mbSupportSubquery( false ),
859 mbSupportDrill( false )
860{
861}
862
864 mnSourceType( XML_TOKEN_INVALID ),
865 mnConnectionId( 0 )
866{
867}
868
870{
872}
873
875 WorkbookHelper( rHelper ),
876 mnCurrRow( -1 ),
877 mbValidSource( false ),
878 mbDummySheet( false )
879{
880}
881
883{
884 maDefModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
885 maDefModel.maRefreshedBy = rAttribs.getXString( XML_refreshedBy, OUString() );
886 maDefModel.mfRefreshedDate = rAttribs.getDouble( XML_refreshedDate, 0.0 );
887 maDefModel.mnRecords = rAttribs.getInteger( XML_recordCount, 0 );
888 maDefModel.mnMissItemsLimit = rAttribs.getInteger( XML_missingItemsLimit, 0 );
889 maDefModel.mbInvalid = rAttribs.getBool( XML_invalid, false );
890 maDefModel.mbSaveData = rAttribs.getBool( XML_saveData, true );
891 maDefModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
892 maDefModel.mbOptimizeMemory = rAttribs.getBool( XML_optimizeMemory, false );
893 maDefModel.mbEnableRefresh = rAttribs.getBool( XML_enableRefresh, true );
894 maDefModel.mbBackgroundQuery = rAttribs.getBool( XML_backgroundQuery, false );
895 maDefModel.mbUpgradeOnRefresh = rAttribs.getBool( XML_upgradeOnRefresh, false );
896 maDefModel.mbTupleCache = rAttribs.getBool( XML_tupleCache, false );
897 maDefModel.mbSupportSubquery = rAttribs.getBool( XML_supportSubquery, false );
898 maDefModel.mbSupportDrill = rAttribs.getBool( XML_supportAdvancedDrill, false );
899}
900
902{
904 maSourceModel.mnConnectionId = rAttribs.getInteger( XML_connectionId, 0 );
905}
906
907void PivotCache::importWorksheetSource( const AttributeList& rAttribs, const Relations& rRelations )
908{
909 maSheetSrcModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
910 maSheetSrcModel.maSheet = rAttribs.getXString( XML_sheet, OUString() );
911 maSheetSrcModel.maDefName = rAttribs.getXString( XML_name, OUString() );
912
913 // resolve URL of external document
914 maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
915 // store range address unchecked with sheet index 0, will be resolved/checked later
917}
918
920{
921 sal_uInt8 nFlags1, nFlags2;
922 rStrm.skip( 3 ); // create/refresh version id's
923 nFlags1 = rStrm.readuChar();
924 maDefModel.mnMissItemsLimit = rStrm.readInt32();
925 maDefModel.mfRefreshedDate = rStrm.readDouble();
926 nFlags2 = rStrm.readuChar();
927 maDefModel.mnRecords = rStrm.readInt32();
928 if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASUSERNAME ) )
930 if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASRELID ) )
932
933 maDefModel.mbInvalid = getFlag( nFlags1, BIFF12_PCDEFINITION_INVALID );
934 maDefModel.mbSaveData = getFlag( nFlags1, BIFF12_PCDEFINITION_SAVEDATA );
935 maDefModel.mbRefreshOnLoad = getFlag( nFlags1, BIFF12_PCDEFINITION_REFRESHONLOAD );
936 maDefModel.mbOptimizeMemory = getFlag( nFlags1, BIFF12_PCDEFINITION_OPTIMIZEMEMORY );
937 maDefModel.mbEnableRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_ENABLEREFRESH );
938 maDefModel.mbBackgroundQuery = getFlag( nFlags1, BIFF12_PCDEFINITION_BACKGROUNDQUERY );
939 maDefModel.mbUpgradeOnRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_UPGRADEONREFR );
940 maDefModel.mbTupleCache = getFlag( nFlags1, BIFF12_PCDEFINITION_TUPLECACHE );
941 maDefModel.mbSupportSubquery = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTSUBQUERY );
942 maDefModel.mbSupportDrill = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTDRILL );
943}
944
946{
947 sal_Int32 nSourceType;
948 nSourceType = rStrm.readInt32();
949 maSourceModel.mnConnectionId = rStrm.readInt32();
950 static const sal_Int32 spnSourceTypes[] = { XML_worksheet, XML_external, XML_consolidation, XML_scenario };
951 maSourceModel.mnSourceType = STATIC_ARRAY_SELECT( spnSourceTypes, nSourceType, XML_TOKEN_INVALID );
952}
953
954void PivotCache::importPCDSheetSource( SequenceInputStream& rStrm, const Relations& rRelations )
955{
956 sal_uInt8 nIsDefName, nIsBuiltinName, nFlags;
957 nIsDefName = rStrm.readuChar();
958 nIsBuiltinName = rStrm.readuChar();
959 nFlags = rStrm.readuChar();
960 if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASSHEET ) )
962 if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASRELID ) )
964
965 // read cell range or defined name
966 if( nIsDefName == 0 )
967 {
968 BinRange aBinRange;
969 rStrm >> aBinRange;
970 // store range address unchecked with sheet index 0, will be resolved/checked later
972 }
973 else
974 {
976 if( nIsBuiltinName != 0 )
978 }
979
980 // resolve URL of external document
981 maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
982}
983
985{
986 PivotCacheFieldVector::value_type xCacheField = std::make_shared<PivotCacheField>( *this, true/*bIsDatabaseField*/ );
987 maFields.push_back( xCacheField );
988 return *xCacheField;
989}
990
992{
993 // collect all fields that are based on source data (needed to finalize source data below)
994 OSL_ENSURE( !maFields.empty(), "PivotCache::finalizeImport - no pivot cache fields found" );
995 for( PivotCacheFieldVector::const_iterator aIt = maFields.begin(), aEnd = maFields.end(); aIt != aEnd; ++aIt )
996 {
997 if( (*aIt)->isDatabaseField() )
998 {
999 OSL_ENSURE( (aIt == maFields.begin()) || (*(aIt - 1))->isDatabaseField(),
1000 "PivotCache::finalizeImport - database field follows a calculated field" );
1001 maDatabaseIndexes.push_back( static_cast< sal_Int32 >( maDatabaseFields.size() ) );
1002 maDatabaseFields.push_back( *aIt );
1003 }
1004 else
1005 {
1006 maDatabaseIndexes.push_back( -1 );
1007 }
1008 }
1009 OSL_ENSURE( !maDatabaseFields.empty(), "PivotCache::finalizeImport - no pivot cache source fields found" );
1010
1011 // finalize source data depending on source type
1012 switch( maSourceModel.mnSourceType )
1013 {
1014 case XML_worksheet:
1015 {
1016 // decide whether an external document is used
1017 bool bInternal = maTargetUrl.isEmpty() && maSheetSrcModel.maRelId.isEmpty();
1018 bool bExternal = !maTargetUrl.isEmpty(); // relation ID may be empty, e.g. BIFF import
1019 OSL_ENSURE( bInternal || bExternal, "PivotCache::finalizeImport - invalid external document URL" );
1020 if( bInternal )
1022 else if( bExternal )
1024 }
1025 break;
1026
1027 // currently, we only support worksheet data sources
1028 case XML_external:
1029 break;
1030 case XML_consolidation:
1031 break;
1032 case XML_scenario:
1033 break;
1034 }
1035}
1036
1038{
1039 return maFields.get( nFieldIdx ).get();
1040}
1041
1042const PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx ) const
1043{
1044 return maFields.get( nFieldIdx ).get();
1045}
1046
1047sal_Int32 PivotCache::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
1048{
1050}
1051
1053{
1054 OSL_ENSURE( static_cast< size_t >( maSheetSrcModel.maRange.aEnd.Col() - maSheetSrcModel.maRange.aStart.Col() + 1 ) == maDatabaseFields.size(),
1055 "PivotCache::writeSourceHeaderCells - source cell range width does not match number of source fields" );
1059 mnCurrRow = -1;
1060 updateSourceDataRow( rSheetHelper, nRow );
1061 for( const auto& rxDatabaseField : maDatabaseFields )
1062 {
1063 if (nCol > nMaxCol)
1064 break;
1065 rxDatabaseField->writeSourceHeaderCell( rSheetHelper, nCol, nRow );
1066 ++nCol;
1067 }
1068}
1069
1070void PivotCache::writeSourceDataCell( const WorksheetHelper& rSheetHelper, sal_Int32 nColIdx, sal_Int32 nRowIdx, const PivotCacheItem& rItem ) const
1071{
1072 SCCOL nCol = maSheetSrcModel.maRange.aStart.Col() + nColIdx;
1073 OSL_ENSURE( ( maSheetSrcModel.maRange.aStart.Col() <= nCol ) && ( nCol <= maSheetSrcModel.maRange.aEnd.Col() ), "PivotCache::writeSourceDataCell - invalid column index" );
1074 SCROW nRow = maSheetSrcModel.maRange.aStart.Row() + nRowIdx;
1075 OSL_ENSURE( ( maSheetSrcModel.maRange.aStart.Row() < nRow ) && ( nRow <= maSheetSrcModel.maRange.aEnd.Row() ), "PivotCache::writeSourceDataCell - invalid row index" );
1076 updateSourceDataRow( rSheetHelper, nRow );
1077 if( const PivotCacheField* pCacheField = maDatabaseFields.get( nColIdx ).get() )
1078 pCacheField->writeSourceDataCell( rSheetHelper, nCol, nRow, rItem );
1079}
1080
1081void PivotCache::importPCRecord( SequenceInputStream& rStrm, const WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const
1082{
1083 SCROW nRow = maSheetSrcModel.maRange.aStart.Row() + nRowIdx;
1084 OSL_ENSURE( ( maSheetSrcModel.maRange.aStart.Row() < nRow ) && ( nRow <= maSheetSrcModel.maRange.aEnd.Row() ), "PivotCache::importPCRecord - invalid row index" );
1087 for( const auto& rxDatabaseField : maDatabaseFields )
1088 {
1089 if( rStrm.isEof() || (nCol > nMaxCol) )
1090 break;
1091 rxDatabaseField->importPCRecordItem( rStrm, rSheetHelper, nCol, nRow );
1092 ++nCol;
1093 }
1094}
1095
1096// private --------------------------------------------------------------------
1097
1099{
1100 // resolve sheet name to sheet index
1102
1103 // if cache is based on a defined name or table, try to resolve to cell range
1104 if( !maSheetSrcModel.maDefName.isEmpty() )
1105 {
1106 // local or global defined name
1107 if( const DefinedName* pDefName = getDefinedNames().getByModelName( maSheetSrcModel.maDefName, nSheet ).get() )
1108 {
1109 mbValidSource = pDefName->getAbsoluteRange( maSheetSrcModel.maRange );
1110 }
1111 // table
1112 else if( const Table* pTable = getTables().getTable( maSheetSrcModel.maDefName ).get() )
1113 {
1114 // get original range from table, but exclude the totals row(s)
1115 maSheetSrcModel.maRange = pTable->getOriginalRange();
1116 mbValidSource = (pTable->getHeight() - pTable->getTotalsRows()) > 1;
1117 if( mbValidSource )
1118 maSheetSrcModel.maRange.aEnd.SetRow( maSheetSrcModel.maRange.aEnd.Row() - pTable->getTotalsRows() );
1119 }
1120 }
1121 // else try the cell range (if the sheet exists)
1122 else if( nSheet >= 0 )
1123 {
1124 // insert sheet index into the range, range address will be checked below
1126 mbValidSource = true;
1127 }
1128 // else sheet has been deleted, generate the source data from cache
1129 else if( !maSheetSrcModel.maSheet.isEmpty() )
1130 {
1132 // return here to skip the source range check below
1133 return;
1134 }
1135
1136 // check range location, do not allow ranges that overflow the sheet partly
1140}
1141
1143{
1144 /* If pivot cache is based on external sheet data, try to restore sheet
1145 data from cache records. No support for external defined names or tables,
1146 sheet name and path to cache records fragment (OOXML only) are required. */
1147 bool bHasRelation = !maDefModel.maRelId.isEmpty();
1148 if( bHasRelation && maSheetSrcModel.maDefName.isEmpty() && !maSheetSrcModel.maSheet.isEmpty() )
1150}
1151
1153{
1155 // data will be inserted in top-left cell, sheet index is still set to 0 (will be set below)
1156 rRange.aEnd.SetCol( rRange.aEnd.Col() - rRange.aStart.Col() );
1157 rRange.aStart.SetCol( 0 );
1158 rRange.aEnd.SetRow( rRange.aEnd.Row() - rRange.aStart.Row() );
1159 rRange.aStart.SetRow( 0 );
1160 // check range location, do not allow ranges that overflow the sheet partly
1161 if( getAddressConverter().checkCellRange( rRange, false, true ) )
1162 {
1163 maColSpans.insert( ValueRange( rRange.aStart.Col(), rRange.aEnd.Col() ) );
1164 OUString aSheetName = "DPCache_" + maSheetSrcModel.maSheet;
1165 rRange.aStart.SetTab( getWorksheets().insertEmptySheet( aSheetName ) );
1166 mbValidSource = mbDummySheet = rRange.aStart.Tab() >= 0;
1167 }
1168}
1169
1170void PivotCache::updateSourceDataRow( const WorksheetHelper& rSheetHelper, sal_Int32 nRow ) const
1171{
1172 if( mnCurrRow != nRow )
1173 {
1174 rSheetHelper.getSheetData().setColSpans( nRow, maColSpans );
1175 mnCurrRow = nRow;
1176 }
1177}
1178
1180 WorkbookHelper( rHelper )
1181{
1182}
1183
1184void PivotCacheBuffer::registerPivotCacheFragment( sal_Int32 nCacheId, const OUString& rFragmentPath )
1185{
1186 OSL_ENSURE( nCacheId >= 0, "PivotCacheBuffer::registerPivotCacheFragment - invalid pivot cache identifier" );
1187 OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::registerPivotCacheFragment - fragment path exists already" );
1188 if( (nCacheId >= 0) && !rFragmentPath.isEmpty() )
1189 maFragmentPaths[ nCacheId ] = rFragmentPath;
1190}
1191
1193{
1194 /* OOXML/BIFF12 filter: On first call for the cache ID, the pivot
1195 cache object is created and inserted into maCaches. Then, the cache
1196 definition fragment is read and the cache is returned. On
1197 subsequent calls, the created cache will be found in maCaches and
1198 returned immediately. */
1199 // try to find an imported pivot cache
1200 if( PivotCache* pCache = maCaches.get( nCacheId ).get() )
1201 return pCache;
1202
1203 // check if a fragment path exists for the passed cache identifier
1204 FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
1205 if( aIt == maFragmentPaths.end() )
1206 return nullptr;
1207
1208 /* Import the cache fragment. This may create a dummy data sheet
1209 for external sheet sources. */
1210 PivotCache& rCache = createPivotCache( nCacheId );
1211 importOoxFragment( new PivotCacheDefinitionFragment( *this, aIt->second, rCache ) );
1212 return &rCache;
1213}
1214
1216{
1217 maCacheIds.push_back( nCacheId );
1218 PivotCacheMap::mapped_type& rxCache = maCaches[ nCacheId ];
1219 rxCache = std::make_shared<PivotCache>( *this );
1220 return *rxCache;
1221}
1222
1223} // namespace oox
1224
1225/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char * pName
double d
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
SCCOL Col() const
Definition: address.hxx:279
OUString GetFormattedString(std::u16string_view rDimName, const double fValue)
Definition: dpobject.cxx:1441
const OUString & GetName() const
Definition: dpsave.hxx:139
void SetInvalid()
Definition: address.hxx:539
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
std::optional< css::util::DateTime > getDateTime(sal_Int32 nAttrToken) const
std::optional< OUString > getXString(sal_Int32 nAttrToken) const
std::optional< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
std::optional< OUString > getString(sal_Int32 nAttrToken) const
std::optional< bool > getBool(sal_Int32 nAttrToken) const
std::optional< sal_Int32 > getToken(sal_Int32 nAttrToken) const
std::optional< double > getDouble(sal_Int32 nAttrToken) const
static VectorType::value_type * getVectorElementAccess(VectorType &rVector, sal_Int32 nIndex)
static const VectorType::value_type * getVectorElement(const VectorType &rVector, sal_Int32 nIndex)
bool is() const
bool getProperty(Type &orValue, sal_Int32 nPropId) const
bool setProperty(sal_Int32 nPropId, const Type &rValue)
mapped_type get(key_type nKey) const
container_type::mapped_type mapped_type
value_type get(sal_Int32 nIndex) const
container_type::value_type value_type
void insert(const ValueRange &rRange)
static bool convertToCellRangeUnchecked(ScRange &orRange, const OUString &rString, sal_Int16 nSheet)
Converts the passed string to a cell range address, without checking any sheet limits.
bool checkCellRange(const ScRange &rRange, bool bAllowOverflow, bool bTrackOverflow)
Checks the passed cell range if it fits into the spreadsheet limits.
const ScAddress & getMaxApiAddress() const
Returns the biggest valid cell address in the own Calc document.
static OUString readString(SequenceInputStream &rStrm, bool b32BitLen=true)
Reads a BIFF12 string with leading 16-bit or 32-bit length field.
Definition: biffhelper.cxx:79
std::vector< sal_Int32 > maCacheIds
PivotCache * importPivotCacheFragment(sal_Int32 nCacheId)
Imports and stores a pivot cache definition fragment on first call, returns the imported cache on sub...
void registerPivotCacheFragment(sal_Int32 nCacheId, const OUString &rFragmentPath)
Registers a pivot cache definition fragment.
PivotCache & createPivotCache(sal_Int32 nCacheId)
Creates and returns a new pivot cache object with the passed identifier.
PivotCacheBuffer(const WorkbookHelper &rHelper)
OUString createParentGroupField(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField, const PivotCacheField &rBaseCacheField, PivotCacheGroupItemVector &orItemNames) const
Creates a new grouped DataPilot field and returns its name.
void writeSourceHeaderCell(const WorksheetHelper &rSheetHelper, sal_Int32 nCol, sal_Int32 nRow) const
Writes the title of the field into the passed sheet at the passed address.
void getCacheItemNames(::std::vector< OUString > &orItemNames) const
Returns the names of all shared or group items.
const PivotCacheItemList & getCacheItems() const
Returns shared or group items.
bool hasSharedItems() const
Returns true, if the field contains a list of shared items.
IndexVector maDiscreteItems
All group items of this field.
OUString createDateGroupField(const css::uno::Reference< css::sheet::XDataPilotField > &rxBaseDPField) const
Creates inplace date grouping settings or a new date group field.
bool hasDateGrouping() const
Returns true, if the field has inplace date grouping settings.
void importPCDFSharedItem(sal_Int32 nRecId, SequenceInputStream &rStrm)
Imports one or more shared items from the passed record.
PCFieldGroupModel maFieldGroupModel
Settings for shared items.
void importPCDFGroupItem(sal_Int32 nRecId, SequenceInputStream &rStrm)
Imports one or more group items from the passed record.
PCSharedItemsModel maSharedItemsModel
Settings for this cache field.
void importFieldGroup(const AttributeList &rAttribs)
Imports grouping settings from the fieldGroup element.
PivotCacheItemList maGroupItems
All shared items of this field.
const PivotCacheItem * getCacheItem(sal_Int32 nItemIdx) const
Returns the shared or group item with the specified index.
void importPCDFSharedItems(SequenceInputStream &rStrm)
Imports shared items settings from the PCDFSHAREDITEMS record.
void convertNumericGrouping(const css::uno::Reference< css::sheet::XDataPilotField > &rxDPField) const
Creates inplace numeric grouping settings.
void writeSourceDataCell(const WorksheetHelper &rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem &rItem) const
Writes a source field item value into the passed sheet.
bool hasGroupItems() const
Returns true, if the field contains a list of grouping items.
void importGroupItem(sal_Int32 nElement, const AttributeList &rAttribs)
Imports a group item from the passed element.
void importPCRecordItem(SequenceInputStream &rStrm, const WorksheetHelper &rSheetHelper, sal_Int32 nCol, sal_Int32 nRow) const
Reads an item from the PCRECORD record and writes it to the passed sheet.
void importCacheField(const AttributeList &rAttribs)
Imports pivot cache field settings from the cacheField element.
PivotCacheItemList maSharedItems
bool hasNumericGrouping() const
Returns true, if the field has inplace numeric grouping settings.
void applyItemCaptions(const IdCaptionPairList &vCaptions)
Apply user Captions to imported group data.
static void writeItemToSourceDataCell(const WorksheetHelper &rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem &rItem)
Tries to write the passed value to the passed sheet position.
void importSharedItem(sal_Int32 nElement, const AttributeList &rAttribs)
Imports a shared item from the passed element.
void importDiscretePrItem(sal_Int32 nElement, const AttributeList &rAttribs)
Imports an item of the mapping between group items and base items from the passed element.
void importRangePr(const AttributeList &rAttribs)
Imports numeric grouping settings from the rangePr element.
void writeSharedItemToSourceDataCell(const WorksheetHelper &rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx) const
Tries to write the value of a shared item to the passed sheet position.
PCFieldModel maFieldModel
Mapping between group and base items.
void importPCDField(SequenceInputStream &rStrm)
Imports pivot cache field settings from the PCDFIELD record.
void importSharedItems(const AttributeList &rAttribs)
Imports shared items settings from the sharedItems element.
void importPCDFDiscretePrItem(sal_Int32 nRecId, SequenceInputStream &rStrm)
Imports an item of the mapping between group items and base items from the passed record.
void importPCDFRangePr(SequenceInputStream &rStrm)
Imports numeric grouping settings from the PCDFRANGEPR record.
PivotCacheField(const WorkbookHelper &rHelper, bool bIsDatabaseField)
void importPCDFieldGroup(SequenceInputStream &rStrm)
Imports grouping settings from the PCDFIELDGROUP record.
std::vector< PivotCacheItem > maItems
bool empty() const
Returns true, if this item list is empty.
const PivotCacheItem * getCacheItem(sal_Int32 nItemIdx) const
Returns the specified item.
void applyItemCaptions(const IdCaptionPairList &vCaptions)
PivotCacheItemList(const WorkbookHelper &rHelper)
size_t size() const
Returns the size of the item list.
void getCacheItemNames(::std::vector< OUString > &orItemNames) const
Returns the names of all items.
void importItem(sal_Int32 nElement, const AttributeList &rAttribs)
Imports the item from the passed attribute list.
PivotCacheItem & createItem()
Creates and returns a new item at the end of the items list.
void importArray(SequenceInputStream &rStrm)
Imports an array of items from the PCITEM_ARRAY record.
void readString(const AttributeList &rAttribs)
Reads the string value from a pivot cache item.
sal_Int32 getType() const
Returns the type of the item.
void readBool(const AttributeList &rAttribs)
Reads the boolean value from a pivot cache item.
OUString getName() const
Returns the string representation of the item.
bool mbUnused
Value type (OOXML token identifier).
OUString getFormattedName(const ScDPSaveDimension &rSaveDim, ScDPObject *pObj, const DateTime &rNullDate) const
Returns the string representation of the item, using the actual formatting.
void readIndex(const AttributeList &rAttribs)
Reads the index of a shared item.
void readDate(const AttributeList &rAttribs)
Reads the date/time value from a pivot cache item.
void setStringValue(const OUString &sName)
const css::uno::Any & getValue() const
Returns the value of the item.
void readError(const AttributeList &rAttribs)
Reads the error code value from a pivot cache item.
sal_Int32 mnType
Value of the item.
void readNumeric(const AttributeList &rAttribs)
Reads the double value from a pivot cache item.
void readDouble(SequenceInputStream &rStrm)
Reads the double value from a pivot cache item.
void finalizeInternalSheetSource()
Finalizes the pivot cache if it is based on internal sheet data.
void updateSourceDataRow(const WorksheetHelper &rSheetHelper, sal_Int32 nRow) const
Checks, if the row index has changed since last call, and initializes the sheet data buffer.
void importPCDSheetSource(SequenceInputStream &rStrm, const ::oox::core::Relations &rRelations)
Reads sheet source settings from the PCDSHEETSOURCE record.
PCDefinitionModel maDefModel
Database field index for all fields.
PivotCacheFieldVector maDatabaseFields
All pivot cache fields.
ValueRangeSet maColSpans
Sheet source data if cache type is sheet.
PivotCacheField * getCacheField(sal_Int32 nFieldIdx)
Returns the cache field with the specified index.
void importPivotCacheDefinition(const AttributeList &rAttribs)
Reads pivot cache global settings from the pivotCacheDefinition element.
void importPCRecord(SequenceInputStream &rStrm, const WorksheetHelper &rSheetHelper, sal_Int32 nRowIdx) const
Reads a PCRECORD record and writes all item values to the passed sheet.
void importPCDefinition(SequenceInputStream &rStrm)
Reads pivot cache global settings from the PCDEFINITION record.
sal_Int32 mnCurrRow
URL of an external source document.
PCSourceModel maSourceModel
Global pivot cache settings.
void importCacheSource(const AttributeList &rAttribs)
Reads cache source settings from the cacheSource element.
bool mbDummySheet
True = pivot cache is based on supported data source.
bool mbValidSource
Current row index in dummy sheet.
PCWorksheetSourceModel maSheetSrcModel
Pivot cache source settings.
OUString maTargetUrl
Column spans used by SheetDataBuffer for optimized cell import.
void finalizeExternalSheetSource()
Finalizes the pivot cache if it is based on sheet data of an external spreadsheet document.
PivotCacheField & createCacheField()
Creates and returns a new pivot cache field.
void finalizeImport()
Checks validity of source data and creates a dummy data sheet for external sheet sources.
void prepareSourceDataSheet()
Creates a dummy sheet that will be filled with the pivot cache data.
void importPCDSource(SequenceInputStream &rStrm)
Reads cache source settings from the PCDSOURCE record.
PivotCache(const WorkbookHelper &rHelper)
sal_Int32 getCacheDatabaseIndex(sal_Int32 nFieldIdx) const
Returns the source column index of the field with the passed index.
void importWorksheetSource(const AttributeList &rAttribs, const ::oox::core::Relations &rRelations)
Reads sheet source settings from the worksheetSource element.
void writeSourceHeaderCells(const WorksheetHelper &rSheetHelper) const
Writes the titles of all source fields into the passed sheet.
void writeSourceDataCell(const WorksheetHelper &rSheetHelper, sal_Int32 nColIdx, sal_Int32 nRowIdx, const PivotCacheItem &rItem) const
Writes a source field item value into the passed sheet.
IndexVector maDatabaseIndexes
All cache fields that are based on source data.
PivotCacheFieldVector maFields
Manages the cell contents and cell formatting of a sheet.
void setErrorCell(const CellModel &rModel, const OUString &rErrorCode)
Inserts an error cell from the passed error code into the sheet.
void setColSpans(sal_Int32 nRow, const ValueRangeSet &rColSpans)
Sets column span information for a row.
void setValueCell(const CellModel &rModel, double fValue)
Inserts a value cell into the sheet.
void setDateTimeCell(const CellModel &rModel, const css::util::DateTime &rDateTime)
Inserts a date/time cell into the sheet and adjusts number format.
void setBooleanCell(const CellModel &rModel, bool bValue)
Inserts a boolean cell into the sheet and adjusts number format.
void setStringCell(const CellModel &rModel, const OUString &rText)
Inserts a simple string cell into the sheet.
Helper class that provides functions to convert values from and to different units.
double calcSerialFromDateTime(const css::util::DateTime &rDateTime) const
Returns the serial value of the passed datetime, based on current nulldate.
OUString calcErrorString(sal_uInt8 nErrorCode) const
Returns an error string from the passed BIFF error code.
css::util::DateTime calcDateTimeFromSerial(double fSerial) const
Returns the datetime of the passed serial value, based on current nulldate.
Helper class to provide access to global workbook data.
bool importOoxFragment(const rtl::Reference< oox::core::FragmentHandler > &rxHandler)
Imports a fragment using the passed fragment handler, which contains the full path to the fragment st...
WorksheetBuffer & getWorksheets() const
Returns the worksheet buffer containing sheet names and properties.
AddressConverter & getAddressConverter() const
Returns the converter for string to cell address/range conversion.
DefinedNamesBuffer & getDefinedNames() const
Returns the defined names read from the workbook globals.
UnitConverter & getUnitConverter() const
Returns the measurement unit converter.
TableBuffer & getTables() const
Returns the tables collection (equivalent to Calc's database ranges).
sal_Int16 getCalcSheetIndex(sal_Int32 nWorksheet) const
Returns the Calc index of the specified worksheet.
SheetDataBuffer & getSheetData() const
Returns the buffer for cell contents and cell formatting.
SCTAB getSheetIndex() const
Returns the index of the current sheet.
sal_Int16 mnLevel
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
float x
#define STATIC_ARRAY_SELECT(array, index, def)
sal_Int32 nIndex
sal_Int64 n
#define SAL_WARN_IF(condition, area, stream)
@ Exception
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
int i
void SvStream & rStrm
m
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const sal_Int32 BIFF12_ID_PCITEMA_BOOL
Definition: biffhelper.hxx:173
const sal_Int32 BIFF12_ID_PCITEMA_DATE
Definition: biffhelper.hxx:174
::std::vector< IdCaptionPair > IdCaptionPairList
const sal_Int32 BIFF12_ID_PCITEM_ARRAY
Definition: biffhelper.hxx:165
const sal_Int32 BIFF12_ID_PCITEM_INDEX
Definition: biffhelper.hxx:170
const sal_Int32 BIFF12_ID_PCITEM_MISSING
Definition: biffhelper.hxx:171
const sal_Int32 BIFF12_ID_PCITEMA_ERROR
Definition: biffhelper.hxx:176
const sal_Int32 BIFF12_ID_PCITEMA_DOUBLE
Definition: biffhelper.hxx:175
const sal_Int32 BIFF12_ID_PCITEMA_STRING
Definition: biffhelper.hxx:178
const sal_Int32 BIFF12_ID_PCITEMA_MISSING
Definition: biffhelper.hxx:177
const sal_Int32 BIFF12_ID_PCITEM_BOOL
Definition: biffhelper.hxx:166
const sal_Int32 BIFF12_ID_PCITEM_DATE
Definition: biffhelper.hxx:167
const sal_Int32 BIFF12_ID_PCITEM_DOUBLE
Definition: biffhelper.hxx:168
const sal_Int32 BIFF12_ID_PCITEM_ERROR
Definition: biffhelper.hxx:169
::std::vector< PivotCacheGroupItem > PivotCacheGroupItemVector
const sal_Int32 BIFF12_ID_PCITEM_STRING
Definition: biffhelper.hxx:172
bool getFlag(Type nBitField, Type nMask)
XML_type
XML_TOKEN_INVALID
sal_Int32 mnNumFmtId
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
sal_Int32 mnType
A 2D cell range address struct for binary filters.
Stores basic data about cell values and formatting.
PCDefinitionModel()
True = data source supports drilldown.
OUString maRefreshedBy
Relation identifier for cache records fragment.
bool mbSaveData
True = cache needs refresh.
bool mbOptimizeMemory
True = try to refresh cache on load.
bool mbEnableRefresh
True = application may optimize memory usage.
bool mbTupleCache
True = application may upgrade cache version.
bool mbSupportDrill
True = data source supports subqueries.
bool mbBackgroundQuery
True = refreshing cache is enabled in UI.
bool mbSupportSubquery
True = cache stores OLAP functions.
double mfRefreshedDate
Name of user who last refreshed the cache.
bool mbInvalid
Limit for discarding unused items.
sal_Int32 mnMissItemsLimit
Number of data records in the cache.
bool mbUpgradeOnRefresh
True = application queries data asynchronously.
bool mbRefreshOnLoad
True = cached item values are present.
sal_Int32 mnRecords
Date/time of last refresh.
bool mbDateGroup
True = items are grouped by numeric ranges or date ranges.
sal_Int32 mnBaseField
Index of cache field that contains item groups based on this field.
PCFieldGroupModel()
Finalized group name of this field used in internal pivot table collection.
bool mbRangeGroup
Type of numeric or date range grouping.
sal_Int32 mnGroupBy
Index of cache field this grouped field is based on.
sal_Int32 mnParentField
Interval for numeric range grouping.
css::util::DateTime maEndDate
Manual or calculated start date for range grouping.
double mfInterval
Manual or calculated end value for range grouping.
bool mbAutoStart
True = items are grouped by date ranges or by item names.
void setBiffGroupBy(sal_uInt8 nGroupBy)
Sets the group-by value for BIFF import.
bool mbAutoEnd
True = start value for range groups is calculated from source data.
double mfStartValue
Manual or calculated end date for range grouping.
css::util::DateTime maStartDate
double mfEndValue
Manual or calculated start value for range grouping.
bool mbServerField
True = field from source data; false = calculated field.
OUString maPropertyName
Caption of the cache field.
sal_Int32 mnHierarchy
Data type from ODBC data source.
bool mbMemberPropField
True = list of unique ODBC items exists.
bool mbDatabaseField
Number of property mappings.
OUString maCaption
Fixed name of the cache field.
sal_Int32 mnNumFmtId
Formula of a calculated field.
sal_Int32 mnLevel
Hierarchy this field is part of.
bool mbUniqueList
True = ODBC server-based page field.
sal_Int32 mnMappingCount
Hierarchy level this field is part of.
sal_Int32 mnSqlType
Number format for all items.
PCFieldModel()
True = contains OLAP member properties.
OUString maFormula
OLAP property name.
bool mbHasDate
True = has non-date item(s), maybe date items.
PCSharedItemsModel()
True = contains strings with >255 characters.
bool mbHasString
True = has date item(s), maybe other types.
bool mbHasBlank
True = has (string|bool|error) item(s), maybe other types.
bool mbHasLongText
True = has numeric item(s) with only integers, maybe other types except date.
bool mbIsInteger
True = has numeric item(s), maybe other types except date.
bool mbHasMixed
True = has blank item(s), maybe other types.
bool mbHasNonDate
True = has (blank|string|bool|error) item(s), maybe other types.
bool mbIsNumeric
True = has [(string|bool|error) and (number|date)] or (number and date).
PCSourceModel()
Connection identifier for external data source.
sal_Int32 mnConnectionId
Type of the source data (sheet, consolidation, scenario, external).
PCWorksheetSourceModel()
Source cell range of the data.
OUString maSheet
Relation identifier for an external document URL.
ScRange maRange
Defined name containing a cell range if present.
OUString maDefName
Sheet name for cell range or sheet-local defined names.
Helper struct for mapping original item names from/to group item names.
unsigned char sal_uInt8
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17