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>
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:
249 {
250 css::util::DateTime aDateTime(maValue.get< css::util::DateTime >());
251 if (aDateTime.Year == 0)
252 {
253 SAL_WARN("sc", "PivotCacheField::getFormattedName - invalid date");
254 return OUString();
255 }
256 return pObj->GetFormattedString(rSaveDim.GetName(), DateTime::Sub(aDateTime, rNullDate));
257 }
258 case XML_e: return maValue.get< OUString >();
259 }
260 OSL_FAIL( "PivotCacheItem::getFormattedName - invalid data type" );
261 return OUString();
262}
263
265 WorkbookHelper( rHelper )
266{
267}
268
269void PivotCacheItemList::importItem( sal_Int32 nElement, const AttributeList& rAttribs )
270{
271 PivotCacheItem& rItem = createItem();
272 switch( nElement )
273 {
274 case XLS_TOKEN( m ): break;
275 case XLS_TOKEN( s ): rItem.readString( rAttribs ); break;
276 case XLS_TOKEN( n ): rItem.readNumeric( rAttribs ); break;
277 case XLS_TOKEN( d ): rItem.readDate( rAttribs ); break;
278 case XLS_TOKEN( b ): rItem.readBool( rAttribs ); break;
279 case XLS_TOKEN( e ): rItem.readError( rAttribs ); break;
280 default: OSL_FAIL( "PivotCacheItemList::importItem - unknown element type" );
281 }
282}
283
285{
286 if( nRecId == BIFF12_ID_PCITEM_ARRAY )
287 {
289 return;
290 }
291
292 PivotCacheItem& rItem = createItem();
293 switch( nRecId )
294 {
296 case BIFF12_ID_PCITEMA_MISSING: break;
298 case BIFF12_ID_PCITEMA_STRING: rItem.readString( rStrm ); break;
300 case BIFF12_ID_PCITEMA_DOUBLE: rItem.readDouble( rStrm ); break;
302 case BIFF12_ID_PCITEMA_DATE: rItem.readDate( rStrm ); break;
304 case BIFF12_ID_PCITEMA_BOOL: rItem.readBool( rStrm ); break;
307 default: OSL_FAIL( "PivotCacheItemList::importItem - unknown record type" );
308 }
309}
310
311const PivotCacheItem* PivotCacheItemList::getCacheItem( sal_Int32 nItemIdx ) const
312{
313 return ContainerHelper::getVectorElement( maItems, nItemIdx );
314}
315
317{
318 for( const auto& [rId, rCaption] : vCaptions )
319 {
320 if ( o3tl::make_unsigned( rId ) < maItems.size() )
321 maItems[ rId ].setStringValue( rCaption );
322 }
323}
324
325void PivotCacheItemList::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
326{
327 orItemNames.clear();
328 orItemNames.reserve( maItems.size() );
329 for( const auto& rItem : maItems )
330 orItemNames.push_back( rItem.getName() );
331}
332
333// private --------------------------------------------------------------------
334
336{
337 maItems.emplace_back();
338 return maItems.back();
339}
340
342{
343 sal_uInt16 nType = rStrm.readuInt16();
344 sal_Int32 nCount = rStrm.readInt32();
345 for( sal_Int32 nIdx = 0; !rStrm.isEof() && (nIdx < nCount); ++nIdx )
346 {
347 switch( nType )
348 {
349 case BIFF12_PCITEM_ARRAY_DOUBLE: createItem().readDouble( rStrm ); break;
350 case BIFF12_PCITEM_ARRAY_STRING: createItem().readString( rStrm ); break;
351 case BIFF12_PCITEM_ARRAY_ERROR: createItem().readError(rStrm, getUnitConverter()); break;
352 case BIFF12_PCITEM_ARRAY_DATE: createItem().readDate( rStrm ); break;
353 default:
354 OSL_FAIL( "PivotCacheItemList::importArray - unknown data type" );
355 return;
356 }
357 }
358}
359
361 mnNumFmtId( 0 ),
362 mnSqlType( 0 ),
363 mnHierarchy( 0 ),
364 mnLevel( 0 ),
365 mnMappingCount( 0 ),
366 mbDatabaseField( true ),
367 mbServerField( false ),
368 mbUniqueList( true ),
369 mbMemberPropField( false )
370{
371}
372
374 mbHasSemiMixed( true ),
375 mbHasNonDate( true ),
376 mbHasDate( false ),
377 mbHasString( true ),
378 mbHasBlank( false ),
379 mbHasMixed( false ),
380 mbIsNumeric( false ),
381 mbIsInteger( false ),
382 mbHasLongText( false )
383{
384}
385
387 mfStartValue( 0.0 ),
388 mfEndValue( 0.0 ),
389 mfInterval( 1.0 ),
390 mnParentField( -1 ),
391 mnBaseField( -1 ),
392 mnGroupBy( XML_range ),
393 mbRangeGroup( false ),
394 mbDateGroup( false ),
395 mbAutoStart( true ),
396 mbAutoEnd( true )
397{
398}
399
401{
402 static const sal_Int32 spnGroupBy[] = { XML_range,
403 XML_seconds, XML_minutes, XML_hours, XML_days, XML_months, XML_quarters, XML_years };
404 mnGroupBy = STATIC_ARRAY_SELECT( spnGroupBy, nGroupBy, XML_range );
405}
406
407PivotCacheField::PivotCacheField( const WorkbookHelper& rHelper, bool bIsDatabaseField ) :
408 WorkbookHelper( rHelper ),
409 maSharedItems( rHelper ),
410 maGroupItems( rHelper )
411{
412 maFieldModel.mbDatabaseField = bIsDatabaseField;
413}
414
416{
417 maFieldModel.maName = rAttribs.getXString( XML_name, OUString() );
418 maFieldModel.maCaption = rAttribs.getXString( XML_caption, OUString() );
419 maFieldModel.maPropertyName = rAttribs.getXString( XML_propertyName, OUString() );
420 maFieldModel.maFormula = rAttribs.getXString( XML_formula, OUString() );
421 maFieldModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
422 maFieldModel.mnSqlType = rAttribs.getInteger( XML_sqlType, 0 );
423 maFieldModel.mnHierarchy = rAttribs.getInteger( XML_hierarchy, 0 );
424 maFieldModel.mnLevel = rAttribs.getInteger( XML_level, 0 );
425 maFieldModel.mnMappingCount = rAttribs.getInteger( XML_mappingCount, 0 );
426 maFieldModel.mbDatabaseField = rAttribs.getBool( XML_databaseField, true );
427 maFieldModel.mbServerField = rAttribs.getBool( XML_serverField, false );
428 maFieldModel.mbUniqueList = rAttribs.getBool( XML_uniqueList, true );
429 maFieldModel.mbMemberPropField = rAttribs.getBool( XML_memberPropertyField, false );
430}
431
433{
434 OSL_ENSURE( maSharedItems.empty(), "PivotCacheField::importSharedItems - multiple shared items elements" );
435 maSharedItemsModel.mbHasSemiMixed = rAttribs.getBool( XML_containsSemiMixedTypes, true );
436 maSharedItemsModel.mbHasNonDate = rAttribs.getBool( XML_containsNonDate, true );
437 maSharedItemsModel.mbHasDate = rAttribs.getBool( XML_containsDate, false );
438 maSharedItemsModel.mbHasString = rAttribs.getBool( XML_containsString, true );
439 maSharedItemsModel.mbHasBlank = rAttribs.getBool( XML_containsBlank, false );
440 maSharedItemsModel.mbHasMixed = rAttribs.getBool( XML_containsMixedTypes, false );
441 maSharedItemsModel.mbIsNumeric = rAttribs.getBool( XML_containsNumber, false );
442 maSharedItemsModel.mbIsInteger = rAttribs.getBool( XML_containsInteger, false );
443 maSharedItemsModel.mbHasLongText = rAttribs.getBool( XML_longText, false );
444}
445
446void PivotCacheField::importSharedItem( sal_Int32 nElement, const AttributeList& rAttribs )
447{
448 maSharedItems.importItem( nElement, rAttribs );
449}
450
452{
453 maFieldGroupModel.mnParentField = rAttribs.getInteger( XML_par, -1 );
454 maFieldGroupModel.mnBaseField = rAttribs.getInteger( XML_base, -1 );
455}
456
458{
459 maFieldGroupModel.maStartDate = rAttribs.getDateTime( XML_startDate, css::util::DateTime() );
460 maFieldGroupModel.maEndDate = rAttribs.getDateTime( XML_endDate, css::util::DateTime() );
461 maFieldGroupModel.mfStartValue = rAttribs.getDouble( XML_startNum, 0.0 );
462 maFieldGroupModel.mfEndValue = rAttribs.getDouble( XML_endNum, 0.0 );
463 maFieldGroupModel.mfInterval = rAttribs.getDouble( XML_groupInterval, 1.0 );
464 maFieldGroupModel.mnGroupBy = rAttribs.getToken( XML_groupBy, XML_range );
467 maFieldGroupModel.mbAutoStart = rAttribs.getBool( XML_autoStart, true );
468 maFieldGroupModel.mbAutoEnd = rAttribs.getBool( XML_autoEnd, true );
469}
470
471void PivotCacheField::importDiscretePrItem( sal_Int32 nElement, const AttributeList& rAttribs )
472{
473 OSL_ENSURE( nElement == XLS_TOKEN( x ), "PivotCacheField::importDiscretePrItem - unexpected element" );
474 if( nElement == XLS_TOKEN( x ) )
475 maDiscreteItems.push_back( rAttribs.getInteger( XML_v, -1 ) );
476}
477
478void PivotCacheField::importGroupItem( sal_Int32 nElement, const AttributeList& rAttribs )
479{
480 maGroupItems.importItem( nElement, rAttribs );
481}
482
484{
485 sal_uInt16 nFlags;
486 nFlags = rStrm.readuInt16();
487 maFieldModel.mnNumFmtId = rStrm.readInt32();
488 maFieldModel.mnSqlType = rStrm.readInt16();
489 maFieldModel.mnHierarchy = rStrm.readInt32();
490 maFieldModel.mnLevel = rStrm.readInt32();
491 maFieldModel.mnMappingCount = rStrm.readInt32();
493 if( getFlag( nFlags, BIFF12_PCDFIELD_HASCAPTION ) )
495 if( getFlag( nFlags, BIFF12_PCDFIELD_HASFORMULA ) )
496 rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
498 rStrm.skip( ::std::max< sal_Int32 >( rStrm.readInt32(), 0 ) );
499 if( getFlag( nFlags, BIFF12_PCDFIELD_HASPROPERTYNAME ) )
501
502 maFieldModel.mbDatabaseField = getFlag( nFlags, BIFF12_PCDFIELD_DATABASEFIELD );
503 maFieldModel.mbServerField = getFlag( nFlags, BIFF12_PCDFIELD_SERVERFIELD );
504 maFieldModel.mbUniqueList = !getFlag( nFlags, BIFF12_PCDFIELD_NOUNIQUEITEMS );
505 maFieldModel.mbMemberPropField = getFlag( nFlags, BIFF12_PCDFIELD_MEMBERPROPFIELD );
506}
507
509{
510 sal_uInt16 nFlags;
511 nFlags = rStrm.readuInt16();
512 maSharedItemsModel.mbHasSemiMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSEMIMIXED );
513 maSharedItemsModel.mbHasNonDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASNONDATE );
514 maSharedItemsModel.mbHasDate = getFlag( nFlags, BIFF12_PCDFSITEMS_HASDATE );
515 maSharedItemsModel.mbHasString = getFlag( nFlags, BIFF12_PCDFSITEMS_HASSTRING );
516 maSharedItemsModel.mbHasBlank = getFlag( nFlags, BIFF12_PCDFSITEMS_HASBLANK );
517 maSharedItemsModel.mbHasMixed = getFlag( nFlags, BIFF12_PCDFSITEMS_HASMIXED );
518 maSharedItemsModel.mbIsNumeric = getFlag( nFlags, BIFF12_PCDFSITEMS_ISNUMERIC );
519 maSharedItemsModel.mbIsInteger = getFlag( nFlags, BIFF12_PCDFSITEMS_ISINTEGER );
520 maSharedItemsModel.mbHasLongText = getFlag( nFlags, BIFF12_PCDFSITEMS_HASLONGTEXT );
521}
522
524{
525 maSharedItems.importItem( nRecId, rStrm );
526}
527
529{
531 maFieldGroupModel.mnBaseField = rStrm.readInt32();
532}
533
535{
536 sal_uInt8 nGroupBy, nFlags;
537 nGroupBy = rStrm.readuChar();
538 nFlags = rStrm.readuChar();
539 maFieldGroupModel.mfStartValue = rStrm.readDouble();
540 maFieldGroupModel.mfEndValue = rStrm.readDouble();
541 maFieldGroupModel.mfInterval = rStrm.readDouble();
542
545 maFieldGroupModel.mbDateGroup = getFlag( nFlags, BIFF12_PCDFRANGEPR_DATEGROUP );
546 maFieldGroupModel.mbAutoStart = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOSTART );
547 maFieldGroupModel.mbAutoEnd = getFlag( nFlags, BIFF12_PCDFRANGEPR_AUTOEND );
548
549 OSL_ENSURE( maFieldGroupModel.mbDateGroup == (maFieldGroupModel.mnGroupBy != XML_range), "PivotCacheField::importPCDFRangePr - wrong date flag" );
551 {
554 }
555}
556
558{
559 OSL_ENSURE( nRecId == BIFF12_ID_PCITEM_INDEX, "PivotCacheField::importPCDFDiscretePrItem - unexpected record" );
560 if( nRecId == BIFF12_ID_PCITEM_INDEX )
561 maDiscreteItems.push_back( rStrm.readInt32() );
562}
563
565{
566 maGroupItems.importItem( nRecId, rStrm );
567}
568
569const PivotCacheItem* PivotCacheField::getCacheItem( sal_Int32 nItemIdx ) const
570{
571 if( hasGroupItems() )
572 return maGroupItems.getCacheItem( nItemIdx );
573 if( hasSharedItems() )
574 return maSharedItems.getCacheItem( nItemIdx );
575 return nullptr;
576}
577
579{
580 if( hasGroupItems() )
581 maGroupItems.applyItemCaptions( vCaptions );
582 if( hasSharedItems() )
583 maSharedItems.applyItemCaptions( vCaptions );
584}
585
586void PivotCacheField::getCacheItemNames( ::std::vector< OUString >& orItemNames ) const
587{
588 if( hasGroupItems() )
589 maGroupItems.getCacheItemNames( orItemNames );
590 else if( hasSharedItems() )
591 maSharedItems.getCacheItemNames( orItemNames );
592}
593
595{
596 if( hasGroupItems() )
597 return maGroupItems;
598 return maSharedItems;
599}
600
601void PivotCacheField::convertNumericGrouping( const Reference< XDataPilotField >& rxDPField ) const
602{
603 OSL_ENSURE( hasGroupItems() && hasNumericGrouping(), "PivotCacheField::convertNumericGrouping - not a numeric group field" );
604 PropertySet aPropSet( rxDPField );
605 if( hasGroupItems() && hasNumericGrouping() && aPropSet.is() )
606 {
607 DataPilotFieldGroupInfo aGroupInfo;
608 aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
609 aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
610 aGroupInfo.HasDateValues = false;
611 aGroupInfo.Start = maFieldGroupModel.mfStartValue;
612 aGroupInfo.End = maFieldGroupModel.mfEndValue;
613 aGroupInfo.Step = maFieldGroupModel.mfInterval;
614 aGroupInfo.GroupBy = 0;
615 aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
616 }
617}
618
619OUString PivotCacheField::createDateGroupField( const Reference< XDataPilotField >& rxBaseDPField ) const
620{
621 OSL_ENSURE( hasGroupItems() && hasDateGrouping(), "PivotCacheField::createDateGroupField - not a numeric group field" );
622 Reference< XDataPilotField > xDPGroupField;
623 PropertySet aPropSet( rxBaseDPField );
624 if( hasGroupItems() && hasDateGrouping() && aPropSet.is() )
625 {
626 bool bDayRanges = (maFieldGroupModel.mnGroupBy == XML_days) && (maFieldGroupModel.mfInterval >= 2.0);
627
628 DataPilotFieldGroupInfo aGroupInfo;
629 aGroupInfo.HasAutoStart = maFieldGroupModel.mbAutoStart;
630 aGroupInfo.HasAutoEnd = maFieldGroupModel.mbAutoEnd;
631 aGroupInfo.HasDateValues = true;
634 aGroupInfo.Step = bDayRanges ? maFieldGroupModel.mfInterval : 0.0;
635
636 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
638 {
639 case XML_years: aGroupInfo.GroupBy = YEARS; break;
640 case XML_quarters: aGroupInfo.GroupBy = QUARTERS; break;
641 case XML_months: aGroupInfo.GroupBy = MONTHS; break;
642 case XML_days: aGroupInfo.GroupBy = DAYS; break;
643 case XML_hours: aGroupInfo.GroupBy = HOURS; break;
644 case XML_minutes: aGroupInfo.GroupBy = MINUTES; break;
645 case XML_seconds: aGroupInfo.GroupBy = SECONDS; break;
646 default: OSL_FAIL( "PivotCacheField::convertRangeGrouping - unknown date/time interval" );
647 }
648
649 try
650 {
651 Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY_THROW );
652 xDPGroupField = xDPGrouping->createDateGroup( aGroupInfo );
653 }
654 catch( Exception& )
655 {
656 }
657 }
658
659 Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
660 return xFieldName.is() ? xFieldName->getName() : OUString();
661}
662
663OUString PivotCacheField::createParentGroupField( const Reference< XDataPilotField >& rxBaseDPField, const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames ) const
664{
665 SAL_WARN_IF( !hasGroupItems() || maDiscreteItems.empty(), "sc", "PivotCacheField::createParentGroupField - not a group field" );
666 SAL_WARN_IF( maDiscreteItems.size() != orItemNames.size(), "sc", "PivotCacheField::createParentGroupField - number of item names does not match grouping info" );
667 Reference< XDataPilotFieldGrouping > xDPGrouping( rxBaseDPField, UNO_QUERY );
668 if( !xDPGrouping.is() ) return OUString();
669
670 // map the group item indexes from maGroupItems to all item indexes from maDiscreteItems
671 std::vector< std::vector<sal_Int32> > aItemMap( maGroupItems.size() );
672 sal_Int32 nIndex = -1;
673 for( const auto& rDiscreteItem : maDiscreteItems )
674 {
675 ++nIndex;
676 if( std::vector<sal_Int32>* pItems = ContainerHelper::getVectorElementAccess( aItemMap, rDiscreteItem ) )
677 {
678 if ( const PivotCacheItem* pItem = rBaseCacheField.getCacheItems().getCacheItem( nIndex ) )
679 {
680 // Skip unspecified or unused entries or errors
681 if ( pItem->isUnused() || ( pItem->getType() == XML_m ) || ( pItem->getType() == XML_e ) )
682 continue;
683 }
684 pItems->push_back( nIndex );
685 }
686 }
687
688 // process all groups
689 Reference< XDataPilotField > xDPGroupField;
690 nIndex = 0;
691 for( const auto& rItems : aItemMap )
692 {
693 SAL_WARN_IF( rItems.empty(), "sc", "PivotCacheField::createParentGroupField - item/group should not be empty" );
694 if( !rItems.empty() )
695 {
696 /* Insert the names of the items that are part of this group. Calc
697 expects the names of the members of the field whose members are
698 grouped (which may be the names of groups too). Excel provides
699 the names of the base field items instead (no group names
700 involved). Therefore, the passed collection of current item
701 names as they are already grouped is used here to resolve the
702 item names. */
703 ::std::vector< OUString > aMembers;
704 for( auto i : rItems )
705 if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, i ) )
706 if( ::std::find( aMembers.begin(), aMembers.end(), pName->maGroupName ) == aMembers.end() )
707 aMembers.push_back( pName->maGroupName );
708
709 /* Check again, that this is not just a group that is not grouped
710 further with other items. */
711 if( !aMembers.empty() ) try
712 {
713 // only the first call of createNameGroup() returns the new field
714 Reference< XDataPilotField > xDPNewField = xDPGrouping->createNameGroup( comphelper::containerToSequence( aMembers ) );
715 SAL_WARN_IF( xDPGroupField.is() == xDPNewField.is(), "sc", "PivotCacheField::createParentGroupField - missing group field" );
716 if( !xDPGroupField.is() )
717 xDPGroupField = xDPNewField;
718
719 // get current grouping info
720 DataPilotFieldGroupInfo aGroupInfo;
721 PropertySet aPropSet( xDPGroupField );
722 aPropSet.getProperty( aGroupInfo, PROP_GroupInfo );
723
724 /* Find the group object and the auto-generated group name.
725 The returned field contains all groups derived from the
726 previous field if that is grouped too. To find the correct
727 group, the first item used to create the group is searched.
728 Calc provides the original item names of the base field
729 when the group is querried for its members. Its does not
730 provide the names of members that are already groups in the
731 field used to create the new groups. (Is this a bug?)
732 Therefore, a name from the passed list of original item
733 names is used to find the correct group. */
734 OUString aFirstItem;
735 if( const PivotCacheGroupItem* pName = ContainerHelper::getVectorElement( orItemNames, rItems.front() ) )
736 aFirstItem = pName->maOrigName;
737 Reference< XNamed > xGroupName;
738 OUString aAutoName;
739 Reference< XIndexAccess > xGroupsIA( aGroupInfo.Groups, UNO_QUERY_THROW );
740 for( sal_Int32 nIdx = 0, nCount = xGroupsIA->getCount(); (nIdx < nCount) && (aAutoName.isEmpty()); ++nIdx ) try
741 {
742 Reference< XNameAccess > xItemsNA( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
743 if( xItemsNA->hasByName( aFirstItem ) )
744 {
745 xGroupName.set( xGroupsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
746 aAutoName = xGroupName->getName();
747 }
748 }
749 catch( Exception const & )
750 {
751 TOOLS_WARN_EXCEPTION("sc", "PivotCacheField::createParentGroupField" );
752 }
753 SAL_WARN_IF( aAutoName.isEmpty(), "sc", "PivotCacheField::createParentGroupField - cannot find auto-generated group name" );
754
755 // get the real group name from the list of group items
756 OUString aGroupName;
757 if( const PivotCacheItem* pGroupItem = maGroupItems.getCacheItem( nIndex ) )
758 aGroupName = pGroupItem->getName();
759 SAL_WARN_IF( aGroupName.isEmpty(), "sc", "PivotCacheField::createParentGroupField - cannot find group name" );
760 if( aGroupName.isEmpty() )
761 aGroupName = aAutoName;
762
763 if( xGroupName.is() && !aGroupName.isEmpty() )
764 {
765 // replace the auto-generated group name with the real name
766 if( aAutoName != aGroupName )
767 {
768 xGroupName->setName( aGroupName );
769 aPropSet.setProperty( PROP_GroupInfo, aGroupInfo );
770 }
771 // replace original item names in passed vector with group name
772 for( auto i : rItems )
774 pName->maGroupName = aGroupName;
775 }
776 }
777 catch( Exception const & )
778 {
779 TOOLS_WARN_EXCEPTION("sc", "PivotCacheField::createParentGroupField" );
780 }
781 }
782 ++nIndex;
783 }
784
785 Reference< XNamed > xFieldName( xDPGroupField, UNO_QUERY );
786 return xFieldName.is() ? xFieldName->getName() : OUString();
787}
788
789void PivotCacheField::writeSourceHeaderCell( const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
790{
791 CellModel aModel;
792 aModel.maCellAddr = ScAddress( SCCOL( nCol ), SCROW( nRow ), rSheetHelper.getSheetIndex() );
793 rSheetHelper.getSheetData().setStringCell( aModel, maFieldModel.maName );
794}
795
796void PivotCacheField::writeSourceDataCell( const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) const
797{
798 bool bHasIndex = rItem.getType() == XML_x;
799 OSL_ENSURE( bHasIndex != maSharedItems.empty(), "PivotCacheField::writeSourceDataCell - shared items missing or not expected" );
800 if( bHasIndex )
801 writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem.getValue().get< sal_Int32 >() );
802 else
803 writeItemToSourceDataCell( rSheetHelper, nCol, nRow, rItem );
804}
805
806void PivotCacheField::importPCRecordItem( SequenceInputStream& rStrm, const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow ) const
807{
808 if( hasSharedItems() )
809 {
810 writeSharedItemToSourceDataCell( rSheetHelper, nCol, nRow, rStrm.readInt32() );
811 }
812 else
813 {
814 PivotCacheItem aItem;
816 aItem.readDouble( rStrm );
818 aItem.readDate( rStrm );
819 else
820 aItem.readString( rStrm );
821 writeItemToSourceDataCell( rSheetHelper, nCol, nRow, aItem );
822 }
823}
824
825// private --------------------------------------------------------------------
826
828 sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem )
829{
830 if( rItem.getType() == XML_m )
831 return;
832
833 CellModel aModel;
834 aModel.maCellAddr = ScAddress( SCCOL( nCol ), SCROW( nRow ), rSheetHelper.getSheetIndex() );
835 SheetDataBuffer& rSheetData = rSheetHelper.getSheetData();
836 switch( rItem.getType() )
837 {
838 case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() ); break;
839 case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() ); break;
840 case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() ); break;
841 case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< css::util::DateTime >() ); break;
842 case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() ); break;
843 case XML_e: rSheetData.setErrorCell(aModel, rItem.getValue().get<OUString>()); break;
844 default: OSL_FAIL( "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" );
845 }
846}
847
849 const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nItemIdx ) const
850{
851 if( const PivotCacheItem* pCacheItem = maSharedItems.getCacheItem( nItemIdx ) )
852 writeItemToSourceDataCell( rSheetHelper, nCol, nRow, *pCacheItem );
853}
854
856 mfRefreshedDate( 0.0 ),
857 mnRecords( 0 ),
858 mnMissItemsLimit( 0 ),
859 mbInvalid( false ),
860 mbSaveData( true ),
861 mbRefreshOnLoad( false ),
862 mbOptimizeMemory( false ),
863 mbEnableRefresh( true ),
864 mbBackgroundQuery( false ),
865 mbUpgradeOnRefresh( false ),
866 mbTupleCache( false ),
867 mbSupportSubquery( false ),
868 mbSupportDrill( false )
869{
870}
871
873 mnSourceType( XML_TOKEN_INVALID ),
874 mnConnectionId( 0 )
875{
876}
877
879{
881}
882
884 WorkbookHelper( rHelper ),
885 mnCurrRow( -1 ),
886 mbValidSource( false ),
887 mbDummySheet( false )
888{
889}
890
892{
893 maDefModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
894 maDefModel.maRefreshedBy = rAttribs.getXString( XML_refreshedBy, OUString() );
895 maDefModel.mfRefreshedDate = rAttribs.getDouble( XML_refreshedDate, 0.0 );
896 maDefModel.mnRecords = rAttribs.getInteger( XML_recordCount, 0 );
897 maDefModel.mnMissItemsLimit = rAttribs.getInteger( XML_missingItemsLimit, 0 );
898 maDefModel.mbInvalid = rAttribs.getBool( XML_invalid, false );
899 maDefModel.mbSaveData = rAttribs.getBool( XML_saveData, true );
900 maDefModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
901 maDefModel.mbOptimizeMemory = rAttribs.getBool( XML_optimizeMemory, false );
902 maDefModel.mbEnableRefresh = rAttribs.getBool( XML_enableRefresh, true );
903 maDefModel.mbBackgroundQuery = rAttribs.getBool( XML_backgroundQuery, false );
904 maDefModel.mbUpgradeOnRefresh = rAttribs.getBool( XML_upgradeOnRefresh, false );
905 maDefModel.mbTupleCache = rAttribs.getBool( XML_tupleCache, false );
906 maDefModel.mbSupportSubquery = rAttribs.getBool( XML_supportSubquery, false );
907 maDefModel.mbSupportDrill = rAttribs.getBool( XML_supportAdvancedDrill, false );
908}
909
911{
913 maSourceModel.mnConnectionId = rAttribs.getInteger( XML_connectionId, 0 );
914}
915
916void PivotCache::importWorksheetSource( const AttributeList& rAttribs, const Relations& rRelations )
917{
918 maSheetSrcModel.maRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
919 maSheetSrcModel.maSheet = rAttribs.getXString( XML_sheet, OUString() );
920 maSheetSrcModel.maDefName = rAttribs.getXString( XML_name, OUString() );
921
922 // resolve URL of external document
923 maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
924 // store range address unchecked with sheet index 0, will be resolved/checked later
926}
927
929{
930 sal_uInt8 nFlags1, nFlags2;
931 rStrm.skip( 3 ); // create/refresh version id's
932 nFlags1 = rStrm.readuChar();
933 maDefModel.mnMissItemsLimit = rStrm.readInt32();
934 maDefModel.mfRefreshedDate = rStrm.readDouble();
935 nFlags2 = rStrm.readuChar();
936 maDefModel.mnRecords = rStrm.readInt32();
937 if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASUSERNAME ) )
939 if( getFlag( nFlags2, BIFF12_PCDEFINITION_HASRELID ) )
941
942 maDefModel.mbInvalid = getFlag( nFlags1, BIFF12_PCDEFINITION_INVALID );
943 maDefModel.mbSaveData = getFlag( nFlags1, BIFF12_PCDEFINITION_SAVEDATA );
944 maDefModel.mbRefreshOnLoad = getFlag( nFlags1, BIFF12_PCDEFINITION_REFRESHONLOAD );
945 maDefModel.mbOptimizeMemory = getFlag( nFlags1, BIFF12_PCDEFINITION_OPTIMIZEMEMORY );
946 maDefModel.mbEnableRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_ENABLEREFRESH );
947 maDefModel.mbBackgroundQuery = getFlag( nFlags1, BIFF12_PCDEFINITION_BACKGROUNDQUERY );
948 maDefModel.mbUpgradeOnRefresh = getFlag( nFlags1, BIFF12_PCDEFINITION_UPGRADEONREFR );
949 maDefModel.mbTupleCache = getFlag( nFlags1, BIFF12_PCDEFINITION_TUPLECACHE );
950 maDefModel.mbSupportSubquery = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTSUBQUERY );
951 maDefModel.mbSupportDrill = getFlag( nFlags2, BIFF12_PCDEFINITION_SUPPORTDRILL );
952}
953
955{
956 sal_Int32 nSourceType;
957 nSourceType = rStrm.readInt32();
958 maSourceModel.mnConnectionId = rStrm.readInt32();
959 static const sal_Int32 spnSourceTypes[] = { XML_worksheet, XML_external, XML_consolidation, XML_scenario };
960 maSourceModel.mnSourceType = STATIC_ARRAY_SELECT( spnSourceTypes, nSourceType, XML_TOKEN_INVALID );
961}
962
963void PivotCache::importPCDSheetSource( SequenceInputStream& rStrm, const Relations& rRelations )
964{
965 sal_uInt8 nIsDefName, nIsBuiltinName, nFlags;
966 nIsDefName = rStrm.readuChar();
967 nIsBuiltinName = rStrm.readuChar();
968 nFlags = rStrm.readuChar();
969 if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASSHEET ) )
971 if( getFlag( nFlags, BIFF12_PCDWBSOURCE_HASRELID ) )
973
974 // read cell range or defined name
975 if( nIsDefName == 0 )
976 {
977 BinRange aBinRange;
978 rStrm >> aBinRange;
979 // store range address unchecked with sheet index 0, will be resolved/checked later
981 }
982 else
983 {
985 if( nIsBuiltinName != 0 )
987 }
988
989 // resolve URL of external document
990 maTargetUrl = rRelations.getExternalTargetFromRelId( maSheetSrcModel.maRelId );
991}
992
994{
995 PivotCacheFieldVector::value_type xCacheField = std::make_shared<PivotCacheField>( *this, true/*bIsDatabaseField*/ );
996 maFields.push_back( xCacheField );
997 return *xCacheField;
998}
999
1001{
1002 // collect all fields that are based on source data (needed to finalize source data below)
1003 OSL_ENSURE( !maFields.empty(), "PivotCache::finalizeImport - no pivot cache fields found" );
1004 for( PivotCacheFieldVector::const_iterator aIt = maFields.begin(), aEnd = maFields.end(); aIt != aEnd; ++aIt )
1005 {
1006 if( (*aIt)->isDatabaseField() )
1007 {
1008 OSL_ENSURE( (aIt == maFields.begin()) || (*(aIt - 1))->isDatabaseField(),
1009 "PivotCache::finalizeImport - database field follows a calculated field" );
1010 maDatabaseIndexes.push_back( static_cast< sal_Int32 >( maDatabaseFields.size() ) );
1011 maDatabaseFields.push_back( *aIt );
1012 }
1013 else
1014 {
1015 maDatabaseIndexes.push_back( -1 );
1016 }
1017 }
1018 OSL_ENSURE( !maDatabaseFields.empty(), "PivotCache::finalizeImport - no pivot cache source fields found" );
1019
1020 // finalize source data depending on source type
1021 switch( maSourceModel.mnSourceType )
1022 {
1023 case XML_worksheet:
1024 {
1025 // decide whether an external document is used
1026 bool bInternal = maTargetUrl.isEmpty() && maSheetSrcModel.maRelId.isEmpty();
1027 bool bExternal = !maTargetUrl.isEmpty(); // relation ID may be empty, e.g. BIFF import
1028 OSL_ENSURE( bInternal || bExternal, "PivotCache::finalizeImport - invalid external document URL" );
1029 if( bInternal )
1031 else if( bExternal )
1033 }
1034 break;
1035
1036 // currently, we only support worksheet data sources
1037 case XML_external:
1038 break;
1039 case XML_consolidation:
1040 break;
1041 case XML_scenario:
1042 break;
1043 }
1044}
1045
1047{
1048 return maFields.get( nFieldIdx ).get();
1049}
1050
1051const PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx ) const
1052{
1053 return maFields.get( nFieldIdx ).get();
1054}
1055
1056sal_Int32 PivotCache::getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const
1057{
1059}
1060
1062{
1063 OSL_ENSURE( static_cast< size_t >( maSheetSrcModel.maRange.aEnd.Col() - maSheetSrcModel.maRange.aStart.Col() + 1 ) == maDatabaseFields.size(),
1064 "PivotCache::writeSourceHeaderCells - source cell range width does not match number of source fields" );
1068 mnCurrRow = -1;
1069 updateSourceDataRow( nRow );
1070 for( const auto& rxDatabaseField : maDatabaseFields )
1071 {
1072 if (nCol > nMaxCol)
1073 break;
1074 rxDatabaseField->writeSourceHeaderCell( rSheetHelper, nCol, nRow );
1075 ++nCol;
1076 }
1077}
1078
1079void PivotCache::writeSourceDataCell( const WorksheetHelper& rSheetHelper, sal_Int32 nColIdx, sal_Int32 nRowIdx, const PivotCacheItem& rItem ) const
1080{
1081 SCCOL nCol = maSheetSrcModel.maRange.aStart.Col() + nColIdx;
1082 OSL_ENSURE( ( maSheetSrcModel.maRange.aStart.Col() <= nCol ) && ( nCol <= maSheetSrcModel.maRange.aEnd.Col() ), "PivotCache::writeSourceDataCell - invalid column index" );
1083 SCROW nRow = maSheetSrcModel.maRange.aStart.Row() + nRowIdx;
1084 OSL_ENSURE( ( maSheetSrcModel.maRange.aStart.Row() < nRow ) && ( nRow <= maSheetSrcModel.maRange.aEnd.Row() ), "PivotCache::writeSourceDataCell - invalid row index" );
1085 updateSourceDataRow( nRow );
1086 if( const PivotCacheField* pCacheField = maDatabaseFields.get( nColIdx ).get() )
1087 pCacheField->writeSourceDataCell( rSheetHelper, nCol, nRow, rItem );
1088}
1089
1090void PivotCache::importPCRecord( SequenceInputStream& rStrm, const WorksheetHelper& rSheetHelper, sal_Int32 nRowIdx ) const
1091{
1092 SCROW nRow = maSheetSrcModel.maRange.aStart.Row() + nRowIdx;
1093 OSL_ENSURE( ( maSheetSrcModel.maRange.aStart.Row() < nRow ) && ( nRow <= maSheetSrcModel.maRange.aEnd.Row() ), "PivotCache::importPCRecord - invalid row index" );
1096 for( const auto& rxDatabaseField : maDatabaseFields )
1097 {
1098 if( rStrm.isEof() || (nCol > nMaxCol) )
1099 break;
1100 rxDatabaseField->importPCRecordItem( rStrm, rSheetHelper, nCol, nRow );
1101 ++nCol;
1102 }
1103}
1104
1105// private --------------------------------------------------------------------
1106
1108{
1109 // resolve sheet name to sheet index
1111
1112 // if cache is based on a defined name or table, try to resolve to cell range
1113 if( !maSheetSrcModel.maDefName.isEmpty() )
1114 {
1115 // local or global defined name
1116 if( const DefinedName* pDefName = getDefinedNames().getByModelName( maSheetSrcModel.maDefName, nSheet ).get() )
1117 {
1118 mbValidSource = pDefName->getAbsoluteRange( maSheetSrcModel.maRange );
1119 }
1120 // table
1121 else if( const Table* pTable = getTables().getTable( maSheetSrcModel.maDefName ).get() )
1122 {
1123 // get original range from table, but exclude the totals row(s)
1124 maSheetSrcModel.maRange = pTable->getOriginalRange();
1125 mbValidSource = (pTable->getHeight() - pTable->getTotalsRows()) > 1;
1126 if( mbValidSource )
1127 maSheetSrcModel.maRange.aEnd.SetRow( maSheetSrcModel.maRange.aEnd.Row() - pTable->getTotalsRows() );
1128 }
1129 }
1130 // else try the cell range (if the sheet exists)
1131 else if( nSheet >= 0 )
1132 {
1133 // insert sheet index into the range, range address will be checked below
1135 mbValidSource = true;
1136 }
1137 // else sheet has been deleted, generate the source data from cache
1138 else if( !maSheetSrcModel.maSheet.isEmpty() )
1139 {
1141 // return here to skip the source range check below
1142 return;
1143 }
1144
1145 // check range location, do not allow ranges that overflow the sheet partly
1149}
1150
1152{
1153 /* If pivot cache is based on external sheet data, try to restore sheet
1154 data from cache records. No support for external defined names or tables,
1155 sheet name and path to cache records fragment (OOXML only) are required. */
1156 bool bHasRelation = !maDefModel.maRelId.isEmpty();
1157 if( bHasRelation && maSheetSrcModel.maDefName.isEmpty() && !maSheetSrcModel.maSheet.isEmpty() )
1159}
1160
1162{
1164 // data will be inserted in top-left cell, sheet index is still set to 0 (will be set below)
1165 rRange.aEnd.SetCol( rRange.aEnd.Col() - rRange.aStart.Col() );
1166 rRange.aStart.SetCol( 0 );
1167 rRange.aEnd.SetRow( rRange.aEnd.Row() - rRange.aStart.Row() );
1168 rRange.aStart.SetRow( 0 );
1169 // check range location, do not allow ranges that overflow the sheet partly
1170 if( getAddressConverter().checkCellRange( rRange, false, true ) )
1171 {
1172 maColSpans.insert( ValueRange( rRange.aStart.Col(), rRange.aEnd.Col() ) );
1173 OUString aSheetName = "DPCache_" + maSheetSrcModel.maSheet;
1174 rRange.aStart.SetTab( getWorksheets().insertEmptySheet( aSheetName ) );
1175 mbValidSource = mbDummySheet = rRange.aStart.Tab() >= 0;
1176 }
1177}
1178
1179void PivotCache::updateSourceDataRow( sal_Int32 nRow ) const
1180{
1181 if( mnCurrRow != nRow )
1182 {
1183 mnCurrRow = nRow;
1184 }
1185}
1186
1188 WorkbookHelper( rHelper )
1189{
1190}
1191
1192void PivotCacheBuffer::registerPivotCacheFragment( sal_Int32 nCacheId, const OUString& rFragmentPath )
1193{
1194 OSL_ENSURE( nCacheId >= 0, "PivotCacheBuffer::registerPivotCacheFragment - invalid pivot cache identifier" );
1195 OSL_ENSURE( maFragmentPaths.count( nCacheId ) == 0, "PivotCacheBuffer::registerPivotCacheFragment - fragment path exists already" );
1196 if( (nCacheId >= 0) && !rFragmentPath.isEmpty() )
1197 maFragmentPaths[ nCacheId ] = rFragmentPath;
1198}
1199
1201{
1202 /* OOXML/BIFF12 filter: On first call for the cache ID, the pivot
1203 cache object is created and inserted into maCaches. Then, the cache
1204 definition fragment is read and the cache is returned. On
1205 subsequent calls, the created cache will be found in maCaches and
1206 returned immediately. */
1207 // try to find an imported pivot cache
1208 if( PivotCache* pCache = maCaches.get( nCacheId ).get() )
1209 return pCache;
1210
1211 // check if a fragment path exists for the passed cache identifier
1212 FragmentPathMap::iterator aIt = maFragmentPaths.find( nCacheId );
1213 if( aIt == maFragmentPaths.end() )
1214 return nullptr;
1215
1216 /* Import the cache fragment. This may create a dummy data sheet
1217 for external sheet sources. */
1218 PivotCache& rCache = createPivotCache( nCacheId );
1219 importOoxFragment( new PivotCacheDefinitionFragment( *this, aIt->second, rCache ) );
1220 return &rCache;
1221}
1222
1224{
1225 maCacheIds.push_back( nCacheId );
1226 PivotCacheMap::mapped_type& rxCache = maCaches[ nCacheId ];
1227 rxCache = std::make_shared<PivotCache>( *this );
1228 return *rxCache;
1229}
1230
1231} // namespace oox
1232
1233/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char * pName
double d
static double Sub(const DateTime &rDateTime1, const DateTime &rDateTime2)
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)
bool checkCellRange(const ScRange &rRange, bool bAllowOverflow, bool bTrackOverflow)
Checks the passed cell range if it fits into the spreadsheet limits.
static bool convertToCellRangeUnchecked(ScRange &orRange, std::u16string_view aString, sal_Int16 nSheet)
Converts the passed string to a cell range address, without checking any sheet 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 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 updateSourceDataRow(sal_Int32 nRow) const
Checks, if the row index has changed since last call, and initializes the sheet data buffer.
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 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)
#define SAL_WARN(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