xref: /trunk/main/sc/source/filter/excel/excform.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 #include "excform.hxx"
31 #include <osl/endian.h>
32 
33 #include "cell.hxx"
34 #include "document.hxx"
35 #include "rangenam.hxx"
36 #include "global.hxx"
37 #include "formula/errorcodes.hxx"
38 
39 #include "imp_op.hxx"
40 #include "root.hxx"
41 #include "xltracer.hxx"
42 #include "xihelper.hxx"
43 #include "xilink.hxx"
44 #include "xiname.hxx"
45 
46 using ::std::vector;
47 
48 const sal_uInt16 ExcelToSc::nRowMask = 0x3FFF;
49 const sal_uInt16 ExcelToSc::nLastInd = 399;
50 
51 
52 
53 
54 void ImportExcel::Formula25()
55 {
56     XclAddress aXclPos;
57     sal_uInt16  nXF = 0, nFormLen;
58 	double	fCurVal;
59 	sal_uInt8	nAttr0, nFlag0;
60 	sal_Bool	bShrFmla;
61 
62     aIn >> aXclPos;
63 
64     if( GetBiff() == EXC_BIFF2 )
65 	{//						BIFF2
66 		sal_uInt8 nDummy;
67 
68         aIn.Ignore( 3 );
69 
70 		aIn >> fCurVal;
71         aIn.Ignore( 1 );
72 		aIn >> nDummy;
73 		nFormLen = nDummy;
74 		bShrFmla = sal_False;
75 		nAttr0 = 0x01;	// Always calculate
76 	}
77 	else
78 	{//						BIFF5
79 		aIn >> nXF >> fCurVal >> nFlag0;
80         aIn.Ignore( 5 );
81 
82 		aIn >> nFormLen;
83 
84 		bShrFmla = nFlag0 & 0x08;	// shared or not shared
85 	}
86 
87     Formula( aXclPos, nXF, nFormLen, fCurVal, bShrFmla );
88 }
89 
90 
91 void ImportExcel::Formula3()
92 {
93 	Formula4();
94 }
95 
96 
97 void ImportExcel::Formula4()
98 {
99     XclAddress aXclPos;
100     sal_uInt16  nXF, nFormLen;
101 	double	fCurVal;
102 	sal_uInt8	nFlag0;
103 
104     aIn >> aXclPos >> nXF >> fCurVal >> nFlag0;
105     aIn.Ignore( 1 );
106 	aIn >> nFormLen;
107 
108     Formula( aXclPos, nXF, nFormLen, fCurVal, sal_False );
109 }
110 
111 
112 void ImportExcel::Formula( const XclAddress& rXclPos,
113     sal_uInt16 nXF, sal_uInt16 nFormLen, double& rCurVal, sal_Bool bShrFmla )
114 {
115 	ConvErr eErr = ConvOK;
116 
117     ScAddress aScPos( ScAddress::UNINITIALIZED );
118     if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) )
119 	{
120 		// jetzt steht Lesemarke auf Formel, Laenge in nFormLen
121         const ScTokenArray* pErgebnis = 0;
122 		sal_Bool				bConvert;
123 
124         pFormConv->Reset( aScPos );
125 
126 		if( bShrFmla )
127             bConvert = !pFormConv->GetShrFmla( pErgebnis, maStrm, nFormLen );
128 		else
129             bConvert = sal_True;
130 
131         if( bConvert )
132             eErr = pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
133 
134         ScFormulaCell*		pZelle = NULL;
135 
136 		if( pErgebnis )
137 		{
138             pZelle = new ScFormulaCell( pD, aScPos, pErgebnis );
139             pD->PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pZelle, (sal_Bool)sal_True );
140 		}
141 		else
142 		{
143 			CellType		eCellType;
144 			ScBaseCell*		pBaseCell;
145             pD->GetCellType( aScPos.Col(), aScPos.Row(), aScPos.Tab(), eCellType );
146 			if( eCellType == CELLTYPE_FORMULA )
147 			{
148                 pD->GetCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pBaseCell );
149 				pZelle = ( ScFormulaCell* ) pBaseCell;
150 				if( pZelle )
151 					pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
152 			}
153 		}
154 
155 		if( pZelle )
156 		{
157 			if( eErr != ConvOK )
158 				ExcelToSc::SetError( *pZelle, eErr );
159 #if 0
160             else
161                 ExcelToSc::SetCurVal( *pZelle, rCurVal );
162 #else
163             (void)rCurVal;
164 #endif
165 		}
166 
167         GetXFRangeBuffer().SetXF( aScPos, nXF );
168 	}
169 }
170 
171 
172 
173 
174 ExcelToSc::ExcelToSc( const XclImpRoot& rRoot ) :
175     ExcelConverterBase( 512 ),
176     XclImpRoot( rRoot ),
177     maFuncProv( rRoot ),
178     meBiff( rRoot.GetBiff() )
179 {
180 }
181 
182 ExcelToSc::~ExcelToSc()
183 {
184 }
185 
186 void ExcelToSc::GetDummy( const ScTokenArray*& pErgebnis )
187 {
188     aPool.Store( CREATE_STRING( "Dummy()" ) );
189 	aPool >> aStack;
190 	pErgebnis = aPool[ aStack.Get() ];
191 }
192 
193 
194 // if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
195 // otherwise it will seek to the first byte after the additional content (eg
196 // inline arrays) following <nFormulaLen>
197 ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
198 {
199     RootData&       rR = GetOldRoot();
200 	sal_uInt8			nOp, nLen, nByte;
201     sal_uInt16          nUINT16;
202 	sal_Int16			nINT16;
203 	double			fDouble;
204 	String			aString;
205 	sal_Bool			bError = sal_False;
206 	sal_Bool			bArrayFormula = sal_False;
207 	TokenId			nMerk0;
208 	const sal_Bool		bRangeName = eFT == FT_RangeName;
209 	const sal_Bool		bSharedFormula = eFT == FT_SharedFormula;
210 	const sal_Bool		bRNorSF = bRangeName || bSharedFormula;
211 
212 	ScSingleRefData		aSRD;
213 	ScComplexRefData		aCRD;
214     ExtensionTypeVec    aExtensions;
215 
216 	bExternName = sal_False;
217 
218 	if( eStatus != ConvOK )
219 	{
220         aIn.Ignore( nFormulaLen );
221 		return eStatus;
222 	}
223 
224 	if( nFormulaLen == 0 )
225 	{
226         aPool.Store( CREATE_STRING( "-/-" ) );
227 		aPool >> aStack;
228 		pErgebnis = aPool[ aStack.Get() ];
229 		return ConvOK;
230 	}
231 
232     sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
233 
234     while( (aIn.GetRecPos() < nEndPos) && !bError )
235 	{
236 		aIn >> nOp;
237 
238         // #98524# always reset flags
239         aSRD.InitFlags();
240         aCRD.InitFlags();
241 
242 		switch( nOp )	//								Buch Seite:
243 		{			//										SDK4 SDK5
244 			case 0x01: // Array Formula							[325    ]
245 					   // Array Formula or Shared Formula		[    277]
246 			case 0x02: // Data Table							[325 277]
247 				nUINT16 = 3;
248 
249                 if( meBiff != EXC_BIFF2 )
250 					nUINT16++;
251 
252                 aIn.Ignore( nUINT16 );
253 
254 				bArrayFormula = sal_True;
255 				break;
256 			case 0x03: // Addition								[312 264]
257 				aStack >> nMerk0;
258 				aPool <<  aStack << ocAdd << nMerk0;
259 				aPool >> aStack;
260 				break;
261 			case 0x04: // Subtraction							[313 264]
262 				// SECOMD-TOP minus TOP
263 				aStack >> nMerk0;
264 				aPool << aStack << ocSub << nMerk0;
265 				aPool >> aStack;
266 				break;
267 			case 0x05: // Multiplication						[313 264]
268 				aStack >> nMerk0;
269 				aPool << aStack << ocMul << nMerk0;
270 				aPool >> aStack;
271 				break;
272 			case 0x06: // Division								[313 264]
273 				// divide TOP by SECOND-TOP
274 				aStack >> nMerk0;
275 				aPool << aStack << ocDiv << nMerk0;
276 				aPool >> aStack;
277 				break;
278 			case 0x07: // Exponetiation							[313 265]
279 				// raise SECOND-TOP to power of TOP
280 				aStack >> nMerk0;
281 				aPool << aStack << ocPow << nMerk0;
282 				aPool >> aStack;
283 				break;
284 			case 0x08: // Concatenation							[313 265]
285 				// append TOP to SECOND-TOP
286 				aStack >> nMerk0;
287 				aPool << aStack << ocAmpersand << nMerk0;
288 				aPool >> aStack;
289 				break;
290 			case 0x09: // Less Than								[313 265]
291 				// SECOND-TOP < TOP
292 				aStack >> nMerk0;
293 				aPool << aStack << ocLess << nMerk0;
294 				aPool >> aStack;
295 				break;
296 			case 0x0A: // Less Than or Equal					[313 265]
297 				// SECOND-TOP <= TOP
298 				aStack >> nMerk0;
299 				aPool << aStack << ocLessEqual << nMerk0;
300 				aPool >> aStack;
301 				break;
302 			case 0x0B: // Equal									[313 265]
303 				// SECOND-TOP == TOP
304 				aStack >> nMerk0;
305 				aPool << aStack << ocEqual << nMerk0;
306 				aPool >> aStack;
307 				break;
308 			case 0x0C: // Greater Than or Equal					[313 265]
309 				// SECOND-TOP == TOP
310 				aStack >> nMerk0;
311 				aPool << aStack << ocGreaterEqual << nMerk0;
312 				aPool >> aStack;
313 				break;
314 			case 0x0D: // Greater Than							[313 265]
315 				// SECOND-TOP == TOP
316 				aStack >> nMerk0;
317 				aPool << aStack << ocGreater << nMerk0;
318 				aPool >> aStack;
319 				break;
320 			case 0x0E: // Not Equal								[313 265]
321 				// SECOND-TOP == TOP
322 				aStack >> nMerk0;
323 				aPool << aStack << ocNotEqual << nMerk0;
324 				aPool >> aStack;
325 				break;
326 			case 0x0F: // Intersection							[314 265]
327 				aStack >> nMerk0;
328 				aPool << aStack << ocIntersect << nMerk0;
329 				aPool >> aStack;
330 				break;
331 			case 0x10: // Union									[314 265]
332 				// ocSep behelfsweise statt 'ocUnion'
333 				aStack >> nMerk0;
334 //#100928#      aPool << ocOpen << aStack << ocSep << nMerk0 << ocClose;
335                 aPool << aStack << ocSep << nMerk0;
336 					// doesn't fit exactly, but is more Excel-like
337 				aPool >> aStack;
338 				break;
339 			case 0x11: // Range									[314 265]
340 				aStack >> nMerk0;
341 				aPool << aStack << ocRange << nMerk0;
342 				aPool >> aStack;
343 				break;
344 			case 0x12: // Unary Plus							[312 264]
345                 aPool << ocAdd << aStack;
346                 aPool >> aStack;
347 				break;
348 			case 0x13: // Unary Minus							[312 264]
349 				aPool << ocNegSub << aStack;
350 				aPool >> aStack;
351 				break;
352 			case 0x14: // Percent Sign							[312 264]
353                 aPool << aStack << ocPercentSign;
354 				aPool >> aStack;
355 				break;
356 			case 0x15: // Parenthesis							[326 278]
357 				aPool << ocOpen << aStack << ocClose;
358 				aPool >> aStack;
359 				break;
360 			case 0x16: // Missing Argument						[314 266]
361 				aPool << ocMissing;
362 				aPool >> aStack;
363                 GetTracer().TraceFormulaMissingArg();
364 				break;
365 			case 0x17: // String Constant						[314 266]
366 				aIn >> nLen;
367                 aString = aIn.ReadRawByteString( nLen );
368 
369 				aStack << aPool.Store( aString );
370 				break;
371 			case 0x19: // Special Attribute						[327 279]
372 			{
373 				sal_uInt16	nData, nFakt;
374 				sal_uInt8	nOpt;
375 
376 				aIn >> nOpt;
377 
378                 if( meBiff == EXC_BIFF2 )
379 				{
380 					nData = aIn.ReaduInt8();
381 					nFakt = 1;
382 				}
383 				else
384 				{
385 					aIn >> nData;
386 					nFakt = 2;
387 				}
388 
389 				if( nOpt & 0x04 )
390 				{// nFakt -> Bytes oder Words ueberlesen	AttrChoose
391 					nData++;
392                     aIn.Ignore( nData * nFakt );
393 				}
394 				else if( nOpt & 0x10 )						// AttrSum
395 					DoMulArgs( ocSum, 1 );
396 			}
397 				break;
398 			case 0x1A: // External Reference					[330    ]
399                 switch( meBiff )
400 				{
401                     case EXC_BIFF2: aIn.Ignore( 7 );    break;
402                     case EXC_BIFF3:
403                     case EXC_BIFF4: aIn.Ignore( 10 );   break;
404                     case EXC_BIFF5:
405 						DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
406 					default:
407 						DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
408 				}
409 				break;
410 			case 0x1B: // End External Reference				[330    ]
411                 switch( meBiff )
412 				{
413                     case EXC_BIFF2: aIn.Ignore( 3 );    break;
414                     case EXC_BIFF3:
415                     case EXC_BIFF4: aIn.Ignore( 4 );    break;
416                     case EXC_BIFF5:
417 						DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
418 					default:
419 						DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
420 				}
421 				break;
422 			case 0x1C: // Error Value							[314 266]
423 			{
424 				aIn >> nByte;
425 #if 0   // erAck
426                 aPool.StoreError( XclTools::GetScErrorCode( nByte ) );
427 #else
428 				DefTokenId			eOc;
429 				switch( nByte )
430 				{
431                     case EXC_ERR_NULL:
432                     case EXC_ERR_DIV0:
433                     case EXC_ERR_VALUE:
434                     case EXC_ERR_REF:
435                     case EXC_ERR_NAME:
436                     case EXC_ERR_NUM:   eOc = ocStop;       break;
437                     case EXC_ERR_NA:    eOc = ocNotAvail;   break;
438                     default:            eOc = ocNoName;
439 				}
440 				aPool << eOc;
441 				if( eOc != ocStop )
442 					aPool << ocOpen << ocClose;
443 #endif
444 				aPool >> aStack;
445 			}
446 				break;
447 			case 0x1D: // Boolean								[315 266]
448 				aIn >> nByte;
449 				if( nByte == 0 )
450 					aPool << ocFalse << ocOpen << ocClose;
451 				else
452 					aPool << ocTrue << ocOpen << ocClose;
453 				aPool >> aStack;
454 				break;
455 			case 0x1E: // Integer								[315 266]
456 				aIn >> nUINT16;
457 				aStack << aPool.Store( ( double ) nUINT16 );
458 				break;
459 			case 0x1F: // Number								[315 266]
460 				aIn >> fDouble;
461 				aStack << aPool.Store( fDouble );
462 				break;
463 			case 0x40:
464 			case 0x60:
465             case 0x20: // Array Constant						[317 268]
466                 aIn >> nByte >> nUINT16;
467                 aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 );
468                 if( bAllowArrays )
469                 {
470                     aStack << aPool.StoreMatrix();
471                     aExtensions.push_back( EXTENSION_ARRAY );
472                 }
473                 else
474                 {
475                     aPool << ocBad;
476                     aPool >> aStack;
477                 }
478                 break;
479 			case 0x41:
480 			case 0x61:
481 			case 0x21: // Function, Fixed Number of Arguments	[333 282]
482             {
483                 sal_uInt16 nXclFunc;
484                 if( meBiff <= EXC_BIFF3 )
485                     nXclFunc = aIn.ReaduInt8();
486                 else
487                     aIn >> nXclFunc;
488                 if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
489                     DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount, pFuncInfo->mnMinParamCount );
490                 else
491                     DoMulArgs( ocNoName, 0 );
492             }
493             break;
494 			case 0x42:
495 			case 0x62:
496 			case 0x22: // Function, Variable Number of Arg.		[333 283]
497             {
498                 sal_uInt16 nXclFunc;
499                 sal_uInt8 nParamCount;
500                 aIn >> nParamCount;
501                 nParamCount &= 0x7F;
502                 if( meBiff <= EXC_BIFF3 )
503                     nXclFunc = aIn.ReaduInt8();
504                 else
505                     aIn >> nXclFunc;
506                 if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
507                     DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
508                 else
509                     DoMulArgs( ocNoName, 0 );
510             }
511             break;
512 			case 0x43:
513 			case 0x63:
514 			case 0x23: // Name									[318 269]
515             {
516 				aIn >> nUINT16;
517                 switch( meBiff )
518 				{
519                     case EXC_BIFF2: aIn.Ignore( 5 );    break;
520                     case EXC_BIFF3:
521                     case EXC_BIFF4: aIn.Ignore( 8 );    break;
522                     case EXC_BIFF5: aIn.Ignore( 12 );   break;
523 					default:
524 						DBG_ERROR(
525 						"-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
526 				}
527                 const XclImpName* pName = GetNameManager().GetName( nUINT16 );
528 				if(pName && !pName->GetScRangeData())
529 				    aStack << aPool.Store( ocMacro, pName->GetXclName() );
530 				else
531 				    aStack << aPool.Store( nUINT16 );
532 			}
533 				break;
534 			case 0x44:
535 			case 0x64:
536 			case 0x24: // Cell Reference						[319 270]
537 			case 0x4A:
538 			case 0x6A:
539 			case 0x2A: // Deleted Cell Reference				[323 273]
540 				aIn >> nUINT16 >> nByte;
541 				aSRD.nCol = static_cast<SCsCOL>(nByte);
542 				aSRD.nRow = nUINT16 & 0x3FFF;
543 				aSRD.nRelTab = 0;
544 				aSRD.SetTabRel( sal_True );
545 				aSRD.SetFlag3D( bRangeName );
546 
547 				ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
548 
549 				switch ( nOp )
550 				{
551 					case 0x4A:
552 					case 0x6A:
553 					case 0x2A: // Deleted Cell Reference	 	[323 273]
554 						// no information which part is deleted, set both
555 						aSRD.SetColDeleted( sal_True );
556 						aSRD.SetRowDeleted( sal_True );
557 				}
558 
559 				aStack << aPool.Store( aSRD );
560 				break;
561 			case 0x45:
562 			case 0x65:
563 			case 0x25: // Area Reference						[320 270]
564 			case 0x4B:
565 			case 0x6B:
566 			case 0x2B: // Deleted Area Refernce					[323 273]
567 			{
568 				sal_uInt16			nRowFirst, nRowLast;
569 				sal_uInt8			nColFirst, nColLast;
570 				ScSingleRefData&	rSRef1 = aCRD.Ref1;
571 				ScSingleRefData&	rSRef2 = aCRD.Ref2;
572 
573 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
574 
575 				rSRef1.nRelTab = rSRef2.nRelTab = 0;
576 				rSRef1.SetTabRel( sal_True );
577 				rSRef2.SetTabRel( sal_True );
578 				rSRef1.SetFlag3D( bRangeName );
579 				rSRef2.SetFlag3D( bRangeName );
580 
581 				ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
582 				ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
583 
584 				if( IsComplColRange( nColFirst, nColLast ) )
585 					SetComplCol( aCRD );
586 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
587 					SetComplRow( aCRD );
588 
589 				switch ( nOp )
590 				{
591 					case 0x4B:
592 					case 0x6B:
593 					case 0x2B: // Deleted Area Refernce			[323 273]
594 						// no information which part is deleted, set all
595 						rSRef1.SetColDeleted( sal_True );
596 						rSRef1.SetRowDeleted( sal_True );
597 						rSRef2.SetColDeleted( sal_True );
598 						rSRef2.SetRowDeleted( sal_True );
599 				}
600 
601 				aStack << aPool.Store( aCRD );
602 			}
603 				break;
604 			case 0x46:
605 			case 0x66:
606 			case 0x26: // Constant Reference Subexpression		[321 271]
607                 aExtensions.push_back( EXTENSION_MEMAREA );
608                 // fall through
609 
610 			case 0x47:
611 			case 0x67:
612 			case 0x27: // Erroneous Constant Reference Subexpr.	[322 272]
613 			case 0x48:
614 			case 0x68:
615 			case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
616                 aIn.Ignore( (meBiff == EXC_BIFF2) ? 4 : 6 );
617 				break;
618 			case 0x4C:
619 			case 0x6C:
620 			case 0x2C: // Cell Reference Within a Name			[323    ]
621 					   // Cell Reference Within a Shared Formula[    273]
622 			{
623 				aIn >> nUINT16 >> nByte;	// >> Attribute, Row >> Col
624 
625 				aSRD.nRelTab = 0;
626 				aSRD.SetTabRel( sal_True );
627 				aSRD.SetFlag3D( bRangeName );
628 
629 				ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
630 
631 				aStack << aPool.Store( aSRD );
632 			}
633 				break;
634 			case 0x4D:
635 			case 0x6D:
636 			case 0x2D: // Area Reference Within a Name			[324    ]
637 			{	   // Area Reference Within a Shared Formula[    274]
638 				sal_uInt16					nRowFirst, nRowLast;
639 				sal_uInt8					nColFirst, nColLast;
640 
641 				aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
642 				aCRD.Ref1.SetTabRel( sal_True );
643 				aCRD.Ref2.SetTabRel( sal_True );
644 				aCRD.Ref1.SetFlag3D( bRangeName );
645 				aCRD.Ref2.SetFlag3D( bRangeName );
646 
647 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
648 
649 				ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
650 				ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
651 
652 				if( IsComplColRange( nColFirst, nColLast ) )
653 					SetComplCol( aCRD );
654 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
655 					SetComplRow( aCRD );
656 
657 				aStack << aPool.Store( aCRD );
658 			}
659 				break;
660             case 0x49:
661             case 0x69:
662             case 0x29: // Variable Reference Subexpression      [331 281]
663 			case 0x4E:
664 			case 0x6E:
665 			case 0x2E: // Reference Subexpression Within a Name	[332 282]
666 			case 0x4F:
667 			case 0x6F:
668 			case 0x2F: // Incomplete Reference Subexpression...	[332 282]
669                 aIn.Ignore( (meBiff == EXC_BIFF2) ? 1 : 2 );
670 				break;
671 			case 0x58:
672 			case 0x78:
673 			case 0x38: // Command-Equivalent Function			[333    ]
674 				aString.AssignAscii( "COMM_EQU_FUNC" );
675 				aIn >> nByte;
676 				aString += String::CreateFromInt32( nByte );
677 				aIn >> nByte;
678 				aStack << aPool.Store( aString );
679 				DoMulArgs( ocPush, nByte + 1 );
680 				break;
681 			case 0x59:
682 			case 0x79:
683 			case 0x39: // Name or External Name					[    275]
684 				aIn >> nINT16;
685                 aIn.Ignore( 8 );
686 				aIn >> nUINT16;
687 				if( nINT16 >= 0 )
688 				{
689                     const ExtName* pExtName = rR.pExtNameBuff->GetNameByIndex( nINT16, nUINT16 );
690 					if( pExtName && pExtName->IsDDE() &&
691                         rR.pExtSheetBuff->IsLink( ( sal_uInt16 ) nINT16 ) )
692 					{
693 						String			aAppl, aExtDoc;
694 						TokenId			nPar1, nPar2;
695 
696                         rR.pExtSheetBuff->GetLink( ( sal_uInt16 ) nINT16 , aAppl, aExtDoc );
697 						nPar1 = aPool.Store( aAppl );
698 						nPar2 = aPool.Store( aExtDoc );
699 						nMerk0 = aPool.Store( pExtName->aName );
700 						aPool	<< ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
701 								<< nMerk0 << ocClose;
702 
703                         GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT );
704 					}
705 					else
706 						aPool << ocBad;
707 
708 					aPool >> aStack;
709 				}
710 				else
711                     aStack << aPool.Store( nUINT16 );
712                 aIn.Ignore( 12 );
713 				break;
714 			case 0x5A:
715 			case 0x7A:
716 			case 0x3A: // 3-D Cell Reference					[    275]
717 			case 0x5C:
718 			case 0x7C:
719 			case 0x3C: // Deleted 3-D Cell Reference			[    277]
720 			{
721 				sal_uInt16			nTabFirst, nTabLast, nRow;
722 				sal_Int16			nExtSheet;
723 				sal_uInt8			nCol;
724 
725 				aIn >> nExtSheet;
726                 aIn.Ignore( 8 );
727 				aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
728 
729 				if( nExtSheet >= 0 )
730 				{	// von extern
731                     if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
732 					{
733 						nTabFirst = nTabLast;
734 						nExtSheet = 0;		// gefunden
735 					}
736 					else
737 					{
738 						aPool << ocBad;
739 						aPool >> aStack;
740 						nExtSheet = 1;		// verhindert Erzeugung einer SingleRef
741 					}
742 				}
743 
744 				if( nExtSheet <= 0 )
745 				{	// in aktuellem Workbook
746 					aSRD.nTab = static_cast<SCTAB>(nTabFirst);
747                     aSRD.SetFlag3D( sal_True );
748 					aSRD.SetTabRel( sal_False );
749 
750 					ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
751 
752 					switch ( nOp )
753 					{
754 						case 0x5C:
755 						case 0x7C:
756 						case 0x3C: // Deleted 3-D Cell Reference	[    277]
757 							// no information which part is deleted, set both
758 							aSRD.SetColDeleted( sal_True );
759 							aSRD.SetRowDeleted( sal_True );
760 					}
761 					if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
762 						aSRD.SetTabDeleted( sal_True );
763 
764 					if( nTabLast != nTabFirst )
765 					{
766                         aCRD.Ref1 = aCRD.Ref2 = aSRD;
767 						aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
768 						aCRD.Ref2.SetTabDeleted( !ValidTab(static_cast<SCTAB>(nTabLast)) );
769 						aStack << aPool.Store( aCRD );
770 					}
771 					else
772 						aStack << aPool.Store( aSRD );
773 				}
774 			}
775 
776 				break;
777 			case 0x5B:
778 			case 0x7B:
779 			case 0x3B: // 3-D Area Reference					[    276]
780 			case 0x5D:
781 			case 0x7D:
782 			case 0x3D: // Deleted 3-D Area Reference			[    277]
783 			{
784 				sal_uInt16		nTabFirst, nTabLast, nRowFirst, nRowLast;
785 				sal_Int16		nExtSheet;
786 				sal_uInt8		nColFirst, nColLast;
787 
788 				aIn >> nExtSheet;
789                 aIn.Ignore( 8 );
790 				aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
791 					>> nColFirst >> nColLast;
792 
793 				if( nExtSheet >= 0 )
794 					// von extern
795 				{
796                     if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
797 					{
798 						nTabFirst = nTabLast;
799 						nExtSheet = 0;		// gefunden
800 					}
801 					else
802 					{
803 						aPool << ocBad;
804 						aPool >> aStack;
805 						nExtSheet = 1;		// verhindert Erzeugung einer CompleteRef
806 					}
807 				}
808 
809 				if( nExtSheet <= 0 )
810 				{// in aktuellem Workbook
811 					// erster Teil des Bereichs
812 					ScSingleRefData&	rR1 = aCRD.Ref1;
813 					ScSingleRefData&	rR2 = aCRD.Ref2;
814 
815 					rR1.nTab = static_cast<SCTAB>(nTabFirst);
816 					rR2.nTab = static_cast<SCTAB>(nTabLast);
817                     rR1.SetFlag3D( sal_True );
818 					rR1.SetTabRel( sal_False );
819                     rR2.SetFlag3D( nTabFirst != nTabLast );
820 					rR2.SetTabRel( sal_False );
821 
822 					ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
823 					ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
824 
825 					if( IsComplColRange( nColFirst, nColLast ) )
826 						SetComplCol( aCRD );
827 					else if( IsComplRowRange( nRowFirst, nRowLast ) )
828 						SetComplRow( aCRD );
829 
830 					switch ( nOp )
831 					{
832 						case 0x5D:
833 						case 0x7D:
834 						case 0x3D: // Deleted 3-D Area Reference	[    277]
835 						   	// no information which part is deleted, set all
836 							rR1.SetColDeleted( sal_True );
837 							rR1.SetRowDeleted( sal_True );
838 							rR2.SetColDeleted( sal_True );
839 							rR2.SetRowDeleted( sal_True );
840 					}
841 					if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
842 						rR1.SetTabDeleted( sal_True );
843 					if ( !ValidTab(static_cast<SCTAB>(nTabLast)) )
844 						rR2.SetTabDeleted( sal_True );
845 
846 					aStack << aPool.Store( aCRD );
847 				}//ENDE in aktuellem Workbook
848 			}
849 				break;
850 			default: bError = sal_True;
851 		}
852 		bError |= !aIn.IsValid();
853 	}
854 
855 	ConvErr eRet;
856 
857 	if( bError )
858 	{
859 		aPool << ocBad;
860 		aPool >> aStack;
861 		pErgebnis = aPool[ aStack.Get() ];
862 		eRet = ConvErrNi;
863 	}
864     else if( aIn.GetRecPos() != nEndPos )
865 	{
866 		aPool << ocBad;
867 		aPool >> aStack;
868 		pErgebnis = aPool[ aStack.Get() ];
869 		eRet = ConvErrCount;
870 	}
871 	else if( bExternName )
872 	{
873 		pErgebnis = aPool[ aStack.Get() ];
874 		eRet = ConvErrExternal;
875 	}
876 	else if( bArrayFormula )
877 	{
878 		pErgebnis = NULL;
879 		eRet = ConvOK;
880 	}
881 	else
882 	{
883 		pErgebnis = aPool[ aStack.Get() ];
884 		eRet = ConvOK;
885 	}
886 
887     aIn.Seek( nEndPos );
888 
889     if( eRet == ConvOK )
890         ReadExtensions( aExtensions, aIn );
891 
892 	return eRet;
893 }
894 
895 
896 // stream seeks to first byte after <nFormulaLen>
897 ConvErr ExcelToSc::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen, const FORMULA_TYPE eFT )
898 {
899     RootData&       rR = GetOldRoot();
900 	sal_uInt8			nOp, nLen;
901     sal_Size        nIgnore;
902 	sal_uInt16			nUINT16;
903 	sal_uInt8			nByte;
904 	sal_Bool			bError = sal_False;
905 	sal_Bool			bArrayFormula = sal_False;
906 	const sal_Bool		bRangeName = eFT == FT_RangeName;
907 	const sal_Bool		bSharedFormula = eFT == FT_SharedFormula;
908 	const sal_Bool		bRNorSF = bRangeName || bSharedFormula;
909 
910 	ScSingleRefData	aSRD;
911 	ScComplexRefData	aCRD;
912 	aCRD.Ref1.nTab = aCRD.Ref2.nTab = aEingPos.Tab();
913 
914 	bExternName = sal_False;
915 
916 	if( eStatus != ConvOK )
917 	{
918         aIn.Ignore( nFormulaLen );
919 		return eStatus;
920 	}
921 
922 	if( nFormulaLen == 0 )
923 		return ConvOK;
924 
925     sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
926 
927     while( (aIn.GetRecPos() < nEndPos) && !bError )
928 	{
929 		aIn >> nOp;
930 		nIgnore = 0;
931 
932         // #98524# always reset flags
933         aSRD.InitFlags();
934         aCRD.InitFlags();
935 
936 		switch( nOp )	//								Buch Seite:
937 		{			//										SDK4 SDK5
938 			case 0x01: // Array Formula							[325    ]
939 					   // Array Formula or Shared Formula		[    277]
940                 nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
941 				bArrayFormula = sal_True;
942 				break;
943 			case 0x02: // Data Table							[325 277]
944                 nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
945 				break;
946 			case 0x03: // Addition								[312 264]
947 			case 0x04: // Subtraction							[313 264]
948 			case 0x05: // Multiplication						[313 264]
949 			case 0x06: // Division								[313 264]
950 			case 0x07: // Exponetiation							[313 265]
951 			case 0x08: // Concatenation							[313 265]
952 			case 0x09: // Less Than								[313 265]
953 			case 0x0A: // Less Than or Equal					[313 265]
954 			case 0x0B: // Equal									[313 265]
955 			case 0x0C: // Greater Than or Equal					[313 265]
956 			case 0x0D: // Greater Than							[313 265]
957 			case 0x0E: // Not Equal								[313 265]
958 			case 0x0F: // Intersection							[314 265]
959 			case 0x10: // Union									[314 265]
960 			case 0x11: // Range									[314 265]
961 			case 0x12: // Unary Plus							[312 264]
962 			case 0x13: // Unary Minus							[312 264]
963 			case 0x14: // Percent Sign							[312 264]
964 			case 0x15: // Parenthesis							[326 278]
965 			case 0x16: // Missing Argument						[314 266]
966 				break;
967 			case 0x17: // String Constant						[314 266]
968 				aIn >> nLen;
969 				nIgnore = nLen;
970 				break;
971 			case 0x19: // Special Attribute						[327 279]
972 			{
973 				sal_uInt16 nData, nFakt;
974 				sal_uInt8 nOpt;
975 
976 				aIn >> nOpt;
977 
978                 if( meBiff == EXC_BIFF2 )
979 				{
980 					nData = aIn.ReaduInt8();
981 					nFakt = 1;
982 				}
983 				else
984 				{
985 					aIn >> nData;
986 					nFakt = 2;
987 				}
988 
989 				if( nOpt & 0x04 )
990 				{// nFakt -> Bytes oder Words ueberlesen	AttrChoose
991 					nData++;
992                     aIn.Ignore( nData * nFakt );
993 				}
994 			}
995 				break;
996 			case 0x1A: // External Reference					[330    ]
997                 switch( meBiff )
998 				{
999                     case EXC_BIFF2: nIgnore = 7;    break;
1000                     case EXC_BIFF3:
1001                     case EXC_BIFF4: nIgnore = 10;   break;
1002                     case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
1003                     default:        DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
1004 				}
1005 				break;
1006 			case 0x1B: // End External Reference				[330    ]
1007                 switch( meBiff )
1008 				{
1009                     case EXC_BIFF2: nIgnore = 3;        break;
1010                     case EXC_BIFF3:
1011                     case EXC_BIFF4: nIgnore = 4;        break;
1012                     case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
1013                     default:        DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
1014 				}
1015 				break;
1016 			case 0x1C: // Error Value							[314 266]
1017 			case 0x1D: // Boolean								[315 266]
1018 				nIgnore = 1;
1019 				break;
1020 			case 0x1E: // Integer								[315 266]
1021 				nIgnore = 2;
1022 				break;
1023 			case 0x1F: // Number								[315 266]
1024                 nIgnore = 8;
1025 				break;
1026 			case 0x40:
1027 			case 0x60:
1028 			case 0x20: // Array Constant						[317 268]
1029                 nIgnore = (meBiff == EXC_BIFF2) ? 6 : 7;
1030 				break;
1031 			case 0x41:
1032 			case 0x61:
1033 			case 0x21: // Function, Fixed Number of Arguments	[333 282]
1034                 nIgnore = (meBiff <= EXC_BIFF3) ? 1 : 2;
1035 				break;
1036 			case 0x42:
1037 			case 0x62:
1038 			case 0x22: // Function, Variable Number of Arg.		[333 283]
1039                 nIgnore = (meBiff <= EXC_BIFF3) ? 2 : 3;
1040 				break;
1041 			case 0x43:
1042 			case 0x63:
1043 			case 0x23: // Name									[318 269]
1044                 switch( meBiff )
1045 				{
1046                     case EXC_BIFF2: nIgnore = 7;    break;
1047                     case EXC_BIFF3:
1048                     case EXC_BIFF4: nIgnore = 10;   break;
1049                     case EXC_BIFF5: nIgnore = 14;   break;
1050                     default:        DBG_ERROR( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
1051 				}
1052 				break;
1053 			case 0x44:
1054 			case 0x64:
1055 			case 0x24: // Cell Reference						[319 270]
1056 				aIn >> nUINT16 >> nByte;
1057 				aSRD.nCol = static_cast<SCsCOL>(nByte);
1058 				aSRD.nRow = nUINT16 & 0x3FFF;
1059 				aSRD.nRelTab = 0;
1060 				aSRD.SetTabRel( sal_True );
1061 				aSRD.SetFlag3D( bRangeName );
1062 
1063 				ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
1064 
1065 				rRangeList.Append( aSRD );
1066 				break;
1067 			case 0x45:
1068 			case 0x65:
1069 			case 0x25: // Area Reference						[320 270]
1070 			{
1071 				sal_uInt16			nRowFirst, nRowLast;
1072 				sal_uInt8			nColFirst, nColLast;
1073 				ScSingleRefData	&rSRef1 = aCRD.Ref1;
1074 				ScSingleRefData	&rSRef2 = aCRD.Ref2;
1075 
1076 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1077 
1078 				rSRef1.nRelTab = rSRef2.nRelTab = 0;
1079 				rSRef1.SetTabRel( sal_True );
1080 				rSRef2.SetTabRel( sal_True );
1081 				rSRef1.SetFlag3D( bRangeName );
1082 				rSRef2.SetFlag3D( bRangeName );
1083 
1084 				ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
1085 				ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
1086 
1087 				if( IsComplColRange( nColFirst, nColLast ) )
1088 					SetComplCol( aCRD );
1089 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
1090 					SetComplRow( aCRD );
1091 
1092 				rRangeList.Append( aCRD );
1093 			}
1094 				break;
1095 			case 0x46:
1096 			case 0x66:
1097 			case 0x26: // Constant Reference Subexpression		[321 271]
1098 			case 0x47:
1099 			case 0x67:
1100 			case 0x27: // Erroneous Constant Reference Subexpr.	[322 272]
1101 			case 0x48:
1102 			case 0x68:
1103 			case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1104                 nIgnore = (meBiff == EXC_BIFF2) ? 4 : 6;
1105 				break;
1106 			case 0x4A:
1107 			case 0x6A:
1108 			case 0x2A: // Deleted Cell Reference				[323 273]
1109 				nIgnore = 3;
1110 				break;
1111 			case 0x4B:
1112 			case 0x6B:
1113 			case 0x2B: // Deleted Area Refernce					[323 273]
1114 				nIgnore = 6;
1115 				break;
1116 			case 0x4C:
1117 			case 0x6C:
1118 			case 0x2C: // Cell Reference Within a Name			[323    ]
1119 					   // Cell Reference Within a Shared Formula[    273]
1120 			{
1121 				aIn >> nUINT16 >> nByte;	// >> Attribute, Row >> Col
1122 
1123 				aSRD.nRelTab = 0;
1124 				aSRD.SetTabRel( sal_True );
1125 				aSRD.SetFlag3D( bRangeName );
1126 
1127 				ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
1128 
1129 				rRangeList.Append( aSRD );
1130 			}
1131 				break;
1132 			case 0x4D:
1133 			case 0x6D:
1134 			case 0x2D: // Area Reference Within a Name			[324    ]
1135 			{	   // Area Reference Within a Shared Formula[    274]
1136 				sal_uInt16					nRowFirst, nRowLast;
1137 				sal_uInt8					nColFirst, nColLast;
1138 
1139 				aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
1140 				aCRD.Ref1.SetTabRel( sal_True );
1141 				aCRD.Ref2.SetTabRel( sal_True );
1142 				aCRD.Ref1.SetFlag3D( bRangeName );
1143 				aCRD.Ref2.SetFlag3D( bRangeName );
1144 
1145 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1146 
1147 				ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
1148 				ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
1149 
1150 				if( IsComplColRange( nColFirst, nColLast ) )
1151 					SetComplCol( aCRD );
1152 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
1153 					SetComplRow( aCRD );
1154 
1155 				rRangeList.Append( aCRD );
1156 			}
1157 				break;
1158             case 0x49:
1159             case 0x69:
1160             case 0x29: // Variable Reference Subexpression      [331 281]
1161 			case 0x4E:
1162 			case 0x6E:
1163 			case 0x2E: // Reference Subexpression Within a Name	[332 282]
1164 			case 0x4F:
1165 			case 0x6F:
1166 			case 0x2F: // Incomplete Reference Subexpression...	[332 282]
1167                 nIgnore = (meBiff == EXC_BIFF2) ? 1 : 2;
1168 				break;
1169 			case 0x58:
1170 			case 0x78:
1171 			case 0x38: // Command-Equivalent Function			[333    ]
1172 				nIgnore = 2;
1173 				break;
1174 			case 0x59:
1175 			case 0x79:
1176 			case 0x39: // Name or External Name					[    275]
1177 				nIgnore = 24;
1178 				break;
1179 			case 0x5A:
1180 			case 0x7A:
1181 			case 0x3A: // 3-D Cell Reference					[    275]
1182 			{
1183 				sal_uInt16			nTabFirst, nTabLast, nRow;
1184 				sal_Int16			nExtSheet;
1185 				sal_uInt8			nCol;
1186 
1187 				aIn >> nExtSheet;
1188                 aIn.Ignore( 8 );
1189 				aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
1190 
1191 				if( nExtSheet >= 0 )
1192 					// von extern
1193 				{
1194                     if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
1195 					{
1196 						nTabFirst = nTabLast;
1197 						nExtSheet = 0;		// gefunden
1198 					}
1199 					else
1200 					{
1201 						aPool << ocBad;
1202 						aPool >> aStack;
1203 						nExtSheet = 1;		// verhindert Erzeugung einer SingleRef
1204 					}
1205 				}
1206 
1207 				if( nExtSheet <= 0 )
1208 				{// in aktuellem Workbook
1209 					sal_Bool b3D = ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName;
1210 					aSRD.nTab = static_cast<SCTAB>(nTabFirst);
1211 					aSRD.SetFlag3D( b3D );
1212 					aSRD.SetTabRel( sal_False );
1213 
1214 					ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
1215 
1216 					if( nTabLast != nTabFirst )
1217 					{
1218 						aCRD.Ref1 = aSRD;
1219 						aCRD.Ref2.nCol = aSRD.nCol;
1220 						aCRD.Ref2.nRow = aSRD.nRow;
1221 						aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
1222 						b3D = ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() );
1223 						aCRD.Ref2.SetFlag3D( b3D );
1224 						aCRD.Ref2.SetTabRel( sal_False );
1225 						rRangeList.Append( aCRD );
1226 					}
1227 					else
1228 						rRangeList.Append( aSRD );
1229 				}
1230 			}
1231 
1232 				break;
1233 			case 0x5B:
1234 			case 0x7B:
1235 			case 0x3B: // 3-D Area Reference					[    276]
1236 			{
1237 				sal_uInt16		nTabFirst, nTabLast, nRowFirst, nRowLast;
1238 				sal_Int16		nExtSheet;
1239 				sal_uInt8		nColFirst, nColLast;
1240 
1241 				aIn >> nExtSheet;
1242                 aIn.Ignore( 8 );
1243 				aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
1244 					>> nColFirst >> nColLast;
1245 
1246 				if( nExtSheet >= 0 )
1247 					// von extern
1248 				{
1249                     if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
1250 					{
1251 						nTabFirst = nTabLast;
1252 						nExtSheet = 0;		// gefunden
1253 					}
1254 					else
1255 					{
1256 						aPool << ocBad;
1257 						aPool >> aStack;
1258 						nExtSheet = 1;		// verhindert Erzeugung einer CompleteRef
1259 					}
1260 				}
1261 
1262 				if( nExtSheet <= 0 )
1263 				{// in aktuellem Workbook
1264 					// erster Teil des Bereichs
1265 					ScSingleRefData	&rR1 = aCRD.Ref1;
1266 					ScSingleRefData	&rR2 = aCRD.Ref2;
1267 
1268 					rR1.nTab = static_cast<SCTAB>(nTabFirst);
1269 					rR2.nTab = static_cast<SCTAB>(nTabLast);
1270 					rR1.SetFlag3D( ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName );
1271 					rR1.SetTabRel( sal_False );
1272 					rR2.SetFlag3D( ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() ) || bRangeName );
1273 					rR2.SetTabRel( sal_False );
1274 
1275 					ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
1276 					ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
1277 
1278 					if( IsComplColRange( nColFirst, nColLast ) )
1279 						SetComplCol( aCRD );
1280 					else if( IsComplRowRange( nRowFirst, nRowLast ) )
1281 						SetComplRow( aCRD );
1282 
1283 					rRangeList.Append( aCRD );
1284 				}//ENDE in aktuellem Workbook
1285 			}
1286 				break;
1287 			case 0x5C:
1288 			case 0x7C:
1289 			case 0x3C: // Deleted 3-D Cell Reference			[    277]
1290 				nIgnore = 17;
1291 				break;
1292 			case 0x5D:
1293 			case 0x7D:
1294 			case 0x3D: // Deleted 3-D Area Reference			[    277]
1295 				nIgnore = 20;
1296 				break;
1297 			default: bError = sal_True;
1298 		}
1299 		bError |= !aIn.IsValid();
1300 
1301         aIn.Ignore( nIgnore );
1302 	}
1303 
1304 	ConvErr eRet;
1305 
1306 	if( bError )
1307 		eRet = ConvErrNi;
1308     else if( aIn.GetRecPos() != nEndPos )
1309 		eRet = ConvErrCount;
1310 	else if( bExternName )
1311 		eRet = ConvErrExternal;
1312 	else if( bArrayFormula )
1313 		eRet = ConvOK;
1314 	else
1315 		eRet = ConvOK;
1316 
1317     aIn.Seek( nEndPos );
1318 	return eRet;
1319 }
1320 
1321 ConvErr ExcelToSc::ConvertExternName( const ScTokenArray*& /*rpArray*/, XclImpStream& /*rStrm*/, sal_Size /*nFormulaLen*/,
1322                                       const String& /*rUrl*/, const vector<String>& /*rTabNames*/ )
1323 {
1324     // not implemented ...
1325     return ConvErrNi;
1326 }
1327 
1328 sal_Bool ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen )
1329 {
1330     DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF5 );
1331     if( GetBiff() != EXC_BIFF5 )
1332         return sal_False;
1333 
1334     sal_uInt8 nOp;
1335     sal_uInt16 nRow1, nRow2;
1336     sal_uInt8 nCol1, nCol2;
1337     SCTAB nTab1, nTab2;
1338     sal_uInt16 nTabFirst, nTabLast;
1339     sal_Int16 nRefIdx;
1340 
1341     sal_Size nSeek;
1342     sal_Size nEndPos = rStrm.GetRecPos() + nLen;
1343 
1344     while( rStrm.IsValid() && (rStrm.GetRecPos() < nEndPos) )
1345     {
1346         rStrm >> nOp;
1347         nSeek = 0;
1348 
1349         switch( nOp )
1350         {
1351             case 0x44:
1352             case 0x64:
1353             case 0x24: // Cell Reference                        [319 270]
1354             case 0x4C:
1355             case 0x6C:
1356             case 0x2C: // Cell Reference Within a Name          [323    ]
1357                        // Cell Reference Within a Shared Formula[    273]
1358                 rStrm >> nRow1 >> nCol1;
1359 
1360                 nRow2 = nRow1;
1361                 nCol2 = nCol1;
1362                 nTab1 = nTab2 = GetCurrScTab();
1363                 goto _common;
1364             case 0x45:
1365             case 0x65:
1366             case 0x25: // Area Reference                        [320 270]
1367             case 0x4D:
1368             case 0x6D:
1369             case 0x2D: // Area Reference Within a Name          [324    ]
1370                        // Area Reference Within a Shared Formula[    274]
1371                 rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1372 
1373                 nTab1 = nTab2 = GetCurrScTab();
1374                 goto _common;
1375             case 0x5A:
1376             case 0x7A:
1377             case 0x3A: // 3-D Cell Reference                    [    275]
1378                 rStrm >> nRefIdx;
1379                 rStrm.Ignore( 8 );
1380                 rStrm >> nTabFirst >> nTabLast >> nRow1 >> nCol1;
1381 
1382                 nRow2 = nRow1;
1383                 nCol2 = nCol1;
1384 
1385                 goto _3d_common;
1386             case 0x5B:
1387             case 0x7B:
1388             case 0x3B: // 3-D Area Reference                    [    276]
1389                 rStrm >> nRefIdx;
1390                 rStrm.Ignore( 8 );
1391                 rStrm >> nTabFirst >> nTabLast >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1392 
1393     _3d_common:
1394                 nTab1 = static_cast< SCTAB >( nTabFirst );
1395                 nTab2 = static_cast< SCTAB >( nTabLast );
1396 
1397                 // #122885# skip references to deleted sheets
1398                 if( (nRefIdx >= 0) || !ValidTab( nTab1 ) || (nTab1 != nTab2) )
1399                     break;
1400 
1401                 goto _common;
1402     _common:
1403                 // do not check abs/rel flags, linked controls have set them!
1404 //               if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
1405                 {
1406                     ScRange aScRange;
1407                     nRow1 &= 0x3FFF;
1408                     nRow2 &= 0x3FFF;
1409                     if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
1410                         rRangeList.Append( aScRange );
1411                 }
1412                 break;
1413 
1414             case 0x03: // Addition                              [312 264]
1415             case 0x04: // Subtraction                           [313 264]
1416             case 0x05: // Multiplication                        [313 264]
1417             case 0x06: // Division                              [313 264]
1418             case 0x07: // Exponetiation                         [313 265]
1419             case 0x08: // Concatenation                         [313 265]
1420             case 0x09: // Less Than                             [313 265]
1421             case 0x0A: // Less Than or Equal                    [313 265]
1422             case 0x0B: // Equal                                 [313 265]
1423             case 0x0C: // Greater Than or Equal                 [313 265]
1424             case 0x0D: // Greater Than                          [313 265]
1425             case 0x0E: // Not Equal                             [313 265]
1426             case 0x0F: // Intersection                          [314 265]
1427             case 0x10: // Union                                 [314 265]
1428             case 0x11: // Range                                 [314 265]
1429             case 0x12: // Unary Plus                            [312 264]
1430             case 0x13: // Unary Minus                           [312 264]
1431             case 0x14: // Percent Sign                          [312 264]
1432             case 0x15: // Parenthesis                           [326 278]
1433             case 0x16: // Missing Argument                      [314 266]
1434                 break;
1435             case 0x1C: // Error Value                           [314 266]
1436             case 0x1D: // Boolean                               [315 266]
1437                 nSeek = 1;
1438                 break;
1439             case 0x1E: // Integer                               [315 266]
1440             case 0x41:
1441             case 0x61:
1442             case 0x21: // Function, Fixed Number of Arguments   [333 282]
1443             case 0x49:
1444             case 0x69:
1445             case 0x29: // Variable Reference Subexpression      [331 281]
1446             case 0x4E:
1447             case 0x6E:
1448             case 0x2E: // Reference Subexpression Within a Name [332 282]
1449             case 0x4F:
1450             case 0x6F:
1451             case 0x2F: // Incomplete Reference Subexpression... [332 282]
1452             case 0x58:
1453             case 0x78:
1454             case 0x38: // Command-Equivalent Function           [333    ]
1455                 nSeek = 2;
1456                 break;
1457             case 0x42:
1458             case 0x62:
1459             case 0x22: // Function, Variable Number of Arg.     [333 283]
1460             case 0x4A:
1461             case 0x6A:
1462             case 0x2A: // Deleted Cell Reference                [323 273]
1463                 nSeek = 3;
1464                 break;
1465             case 0x01: // Array Formula                         [325    ]
1466                        // Array Formula or Shared Formula       [    277]
1467             case 0x02: // Data Table                            [325 277]
1468                 nSeek = 4;
1469                 break;
1470             case 0x46:
1471             case 0x66:
1472             case 0x26: // Constant Reference Subexpression      [321 271]
1473             case 0x47:
1474             case 0x67:
1475             case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
1476             case 0x48:
1477             case 0x68:
1478             case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1479             case 0x4B:
1480             case 0x6B:
1481             case 0x2B: // Deleted Area Refernce                 [323 273]
1482                 nSeek = 6;
1483                 break;
1484             case 0x40:
1485             case 0x60:
1486             case 0x20: // Array Constant                        [317 268]
1487                 nSeek = 7;
1488                 break;
1489             case 0x1F: // Number                                [315 266]
1490                 nSeek = 8;
1491                 break;
1492             case 0x43:
1493             case 0x63:
1494             case 0x23: // Name                                  [318 269]
1495                 nSeek = 14;
1496                 break;
1497             case 0x5C:
1498             case 0x7C:
1499             case 0x3C: // Deleted 3-D Cell Reference            [    277]
1500                 nSeek = 17;
1501                 break;
1502             case 0x5D:
1503             case 0x7D:
1504             case 0x3D: // Deleted 3-D Area Reference            [    277]
1505                 nSeek = 20;
1506                 break;
1507             case 0x59:
1508             case 0x79:
1509             case 0x39: // Name or External Name                 [    275]
1510                 nSeek = 24;
1511                 break;
1512             case 0x17: // String Constant                       [314 266]
1513                 nSeek = rStrm.ReaduInt8();
1514                 break;
1515             case 0x19: // Special Attribute                     [327 279]
1516             {
1517                 sal_uInt8 nOpt;
1518                 sal_uInt16 nData;
1519                 rStrm >> nOpt >> nData;
1520                 if( nOpt & 0x04 )
1521                     nSeek = nData * 2 + 2;
1522             }
1523                 break;
1524         }
1525 
1526         rStrm.Ignore( nSeek );
1527     }
1528     rStrm.Seek( nEndPos );
1529 
1530     return rRangeList.Count() != 0;
1531 }
1532 
1533 void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz, sal_uInt8 nMinParamCount )
1534 {
1535 	TokenId					eParam[ 256 ];
1536 	sal_Int32					nLauf;
1537 
1538 	if( eId == ocCeil || eId == ocFloor )
1539 	{
1540 		aStack << aPool.Store( 1.0 );	// default, da in Excel nicht vorhanden
1541 		nAnz++;
1542 	}
1543 
1544     for( nLauf = 0; aStack.HasMoreTokens() && (nLauf < nAnz); nLauf++ )
1545 		aStack >> eParam[ nLauf ];
1546     // #i70925# reduce parameter count, if no more tokens available on token stack
1547     if( nLauf < nAnz )
1548         nAnz = static_cast< sal_uInt8 >( nLauf );
1549 
1550 	if( nAnz > 0 && eId == ocExternal )
1551 	{
1552 		TokenId				n = eParam[ nAnz - 1 ];
1553 //##### GRUETZE FUER BASIC-FUNCS RICHTEN!
1554         if( const String* pExt = aPool.GetExternal( n ) )
1555 		{
1556             if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclMacroName( *pExt ) )
1557                 aPool << pFuncInfo->meOpCode;
1558             else
1559                 aPool << n;
1560             nAnz--;
1561 		}
1562 		else
1563 			aPool << eId;
1564 	}
1565 	else
1566 		aPool << eId;
1567 
1568 	aPool << ocOpen;
1569 
1570 	if( nAnz > 0 )
1571 	{
1572 		// attention: 0 = last parameter, nAnz-1 = first parameter
1573 		sal_Int16 nNull = -1;		// skip this parameter
1574 		sal_Int16 nSkipEnd = -1;	// skip all parameters <= nSkipEnd
1575 
1576 		sal_Int16 nLast = nAnz - 1;
1577 
1578 		// Funktionen, bei denen Parameter wegfallen muessen
1579 		if( eId == ocPercentrank && nAnz == 3 )
1580 			nSkipEnd = 0;		// letzten Parameter bei Bedarf weglassen
1581 
1582 		// Joost-Spezialfaelle
1583 		else if( eId == ocIf )
1584 		{
1585 			sal_uInt16			nNullParam = 0;
1586 			for( nLauf = 0 ; nLauf < nAnz ; nLauf++ )
1587 			{
1588 				if( aPool.IsSingleOp( eParam[ nLauf ], ocMissing ) )
1589 				{
1590 					if( !nNullParam )
1591 						nNullParam = (sal_uInt16) aPool.Store( ( double ) 0.0 );
1592 					eParam[ nLauf ] = nNullParam;
1593 				}
1594 			}
1595 		}
1596 
1597 		// FIXME: ideally we'd want to import all missing args, but this
1598 		// conflicts with lots of fn's understanding of nParams - we need
1599 		// a function table, and pre-call argument normalisation 1st.
1600 		sal_Int16 nLastRemovable = nLast - nMinParamCount;
1601 
1602 		// #84453# skip missing parameters at end of parameter list
1603 		while( nSkipEnd < nLastRemovable &&
1604 			   aPool.IsSingleOp( eParam[ nSkipEnd + 1 ], ocMissing ) )
1605 			nSkipEnd++;
1606 
1607 //		fprintf (stderr, "Fn %d nSkipEnd %d nLast %d nMinParamCnt %d %d\n",
1608 //				 eId, nSkipEnd, nLast, nMinParamCount, nLastRemovable);
1609 
1610 		// [Parameter{;Parameter}]
1611 		if( nLast > nSkipEnd )
1612 		{
1613 			aPool << eParam[ nLast ];
1614 			for( nLauf = nLast - 1 ; nLauf > nSkipEnd ; nLauf-- )
1615 			{
1616 				if( nLauf != nNull )
1617 					aPool << ocSep << eParam[ nLauf ];
1618 			}
1619 		}
1620 	}
1621 	aPool << ocClose;
1622 
1623 	aPool >> aStack;
1624 }
1625 
1626 
1627 void ExcelToSc::ExcRelToScRel( sal_uInt16 nRow, sal_uInt8 nCol, ScSingleRefData &rSRD, const sal_Bool bName )
1628 {
1629 	if( bName )
1630 	{
1631 		// C O L
1632 		if( nRow & 0x4000 )
1633 		{//															rel Col
1634 			rSRD.SetColRel( sal_True );
1635 			rSRD.nRelCol = static_cast<SCsCOL>(static_cast<sal_Int8>(nCol));
1636 		}
1637 		else
1638 		{//															abs Col
1639 			rSRD.SetColRel( sal_False );
1640 			rSRD.nCol = static_cast<SCCOL>(nCol);
1641 		}
1642 
1643 		// R O W
1644 		if( nRow & 0x8000 )
1645 		{//															rel Row
1646 			rSRD.SetRowRel( sal_True );
1647 			if( nRow & 0x2000 )	// Bit 13 gesetzt?
1648 				//												-> Row negativ
1649 				rSRD.nRelRow = static_cast<SCsROW>(static_cast<sal_Int16>(nRow | 0xC000));
1650 			else
1651 				//												-> Row positiv
1652 				rSRD.nRelRow = static_cast<SCsROW>(nRow & nRowMask);
1653 		}
1654 		else
1655 		{//															abs Row
1656 			rSRD.SetRowRel( sal_False );
1657 			rSRD.nRow = static_cast<SCROW>(nRow & nRowMask);
1658 		}
1659 
1660 		// T A B
1661 		// #67965# abs needed if rel in shared formula for ScCompiler UpdateNameReference
1662 		if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
1663             rSRD.nTab = GetCurrScTab();
1664 	}
1665 	else
1666 	{
1667 		// C O L
1668 		rSRD.SetColRel( ( nRow & 0x4000 ) > 0 );
1669 		rSRD.nCol = static_cast<SCsCOL>(nCol);
1670 
1671 		// R O W
1672 		rSRD.SetRowRel( ( nRow & 0x8000 ) > 0 );
1673 		rSRD.nRow = static_cast<SCsROW>(nRow & nRowMask);
1674 
1675 		if ( rSRD.IsColRel() )
1676 			rSRD.nRelCol = rSRD.nCol - aEingPos.Col();
1677 		if ( rSRD.IsRowRel() )
1678 			rSRD.nRelRow = rSRD.nRow - aEingPos.Row();
1679 
1680         // T A B
1681         // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
1682         if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
1683             rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
1684 	}
1685 }
1686 
1687 
1688 const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
1689 {
1690 	sal_uInt16					nError;
1691 	aPool.Reset();
1692 	aStack.Reset();
1693 
1694 	DefTokenId				eOc;
1695 
1696 	switch( eType )
1697 	{
1698         case xlErrNull:     eOc = ocStop;       nError = errNoCode;             break;
1699         case xlErrDiv0:     eOc = ocStop;       nError = errDivisionByZero;     break;
1700         case xlErrValue:    eOc = ocStop;       nError = errNoValue;            break;
1701         case xlErrRef:      eOc = ocStop;       nError = errNoRef;              break;
1702         case xlErrName:     eOc = ocStop;       nError = errNoName;             break;
1703         case xlErrNum:      eOc = ocStop;       nError = errIllegalFPOperation; break;
1704         case xlErrNA:       eOc = ocNotAvail;   nError = NOTAVAILABLE;          break;
1705         case xlErrTrue:     eOc = ocTrue;       nError = 0;                     break;
1706         case xlErrFalse:    eOc = ocFalse;      nError = 0;                     break;
1707         case xlErrUnknown:  eOc = ocStop;       nError = errUnknownState;       break;
1708 		default:
1709             DBG_ERROR( "ExcelToSc::GetBoolErr - wrong enum!" );
1710 			eOc = ocNoName;
1711 			nError = errUnknownState;
1712 	}
1713 
1714 	aPool << eOc;
1715 	if( eOc != ocStop )
1716 		aPool << ocOpen << ocClose;
1717 
1718 	aPool >> aStack;
1719 
1720 	const ScTokenArray*		pErgebnis = aPool[ aStack.Get() ];
1721 	if( nError )
1722 		( ( ScTokenArray* ) pErgebnis )->SetCodeError( nError );
1723 
1724 	( ( ScTokenArray* ) pErgebnis )->SetRecalcModeNormal();
1725 
1726 	return pErgebnis;
1727 }
1728 
1729 
1730 // if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
1731 // else stream pointer stays unchanged
1732 sal_Bool ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen )
1733 {
1734 	sal_uInt8			nOp;
1735 	sal_Bool			bRet = sal_True;
1736 
1737 	if( nFormulaLen == 0 )
1738 		bRet = sal_False;
1739 	else
1740 	{
1741 		aIn.PushPosition();
1742 
1743 		aIn >> nOp;
1744 
1745 		if( nOp == 0x01 )	// Shared Formula		[    277]
1746 		{
1747 			sal_uInt16 nCol, nRow;
1748 
1749 			aIn >> nRow >> nCol;
1750 
1751             aStack << aPool.Store( GetOldRoot().pShrfmlaBuff->Find(
1752                 ScAddress( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab() ) ) );
1753 
1754 			bRet = sal_True;
1755 		}
1756 		else
1757 			bRet = sal_False;
1758 
1759 		aIn.PopPosition();
1760 	}
1761 
1762 	if( bRet )
1763 	{
1764         aIn.Ignore( nFormulaLen );
1765 		rpErgebnis = aPool[ aStack.Get() ];
1766 	}
1767 	else
1768 		rpErgebnis = NULL;
1769 
1770 	return bRet;
1771 }
1772 
1773 
1774 #if 0
1775 sal_Bool ExcelToSc::SetCurVal( ScFormulaCell &rCell, double &rfCurVal )
1776 {
1777 	sal_uInt16	nInd;
1778 	sal_uInt8	nType;
1779 	sal_uInt8	nVal;
1780 	sal_Bool	bString = sal_False;
1781 
1782 #ifdef OSL_BIGENDIAN
1783 	// Code fuer alle anstaendigen Prozessoren
1784 	nType = *( ( ( sal_uInt8 * ) &rfCurVal ) + 7 );
1785 	nVal = *( ( ( sal_uInt8 * ) &rfCurVal ) + 5 );
1786 	nInd = *( ( sal_uInt16 * ) &rfCurVal );
1787 #else
1788 	// fuer Schund-Prozessoren
1789 	nType = *( ( sal_uInt8 * ) &rfCurVal );
1790 	nVal = *( ( ( sal_uInt8 * ) &rfCurVal ) + 2 );
1791 	nInd = *( ( ( sal_uInt16 * ) &rfCurVal ) + 3 );
1792 #endif
1793 
1794 	if( ( sal_uInt16 ) ~nInd )
1795 		// Wert ist Float
1796 		rCell.SetHybridDouble( rfCurVal );
1797 	else
1798 	{
1799 		switch( nType )
1800 		{
1801 			case 0:		// String
1802 				bString = sal_True;
1803 				break;
1804 			case 1:		// Bool
1805 				if( nVal )
1806 					rfCurVal = 1.0;
1807 				else
1808 					rfCurVal = 0.0;
1809 				rCell.SetHybridDouble( rfCurVal );
1810 				break;
1811 			case 2:		// Error
1812                 rCell.SetErrCode( XclTools::GetScErrorCode( nVal ) );
1813 				break;
1814 		}
1815 	}
1816 
1817 	return bString;
1818 }
1819 #endif
1820 
1821 
1822 void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr )
1823 {
1824 	sal_uInt16	nInd;
1825 
1826 	switch( eErr )
1827 	{
1828 		case ConvErrNi:			nInd = errUnknownToken; break;
1829 		case ConvErrNoMem:		nInd = errCodeOverflow; break;
1830 		case ConvErrExternal:	nInd = errNoName; break;
1831 		case ConvErrCount:		nInd = errCodeOverflow; break;
1832 		default:				nInd = errNoCode;	// hier fiel mir nichts
1833 													//  Besseres ein...
1834 	}
1835 
1836 	rCell.SetErrCode( nInd );
1837 }
1838 
1839 
1840 void ExcelToSc::SetComplCol( ScComplexRefData &rCRD )
1841 {
1842 	ScSingleRefData	&rSRD = rCRD.Ref2;
1843 	if( rSRD.IsColRel() )
1844 		rSRD.nRelCol = MAXCOL - aEingPos.Col();
1845 	else
1846 		rSRD.nCol = MAXCOL;
1847 }
1848 
1849 
1850 void ExcelToSc::SetComplRow( ScComplexRefData &rCRD )
1851 {
1852 	ScSingleRefData	&rSRD = rCRD.Ref2;
1853 	if( rSRD.IsRowRel() )
1854 		rSRD.nRelRow = MAXROW - aEingPos.Row();
1855 	else
1856 		rSRD.nRow = MAXROW;
1857 }
1858 
1859 void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn )
1860 {
1861     // printf( "inline array;\n" );
1862 
1863     sal_uInt8        nByte;
1864     sal_uInt16      nUINT16;
1865     double      fDouble;
1866     String      aString;
1867     ScMatrix*   pMatrix;
1868 
1869     aIn >> nByte >> nUINT16;
1870 
1871     SCSIZE nC, nCols;
1872     SCSIZE nR, nRows;
1873     if( GetBiff() == EXC_BIFF8 )
1874     {
1875         nCols = nByte + 1;
1876         nRows = nUINT16 + 1;
1877     }
1878     else
1879     {
1880         nCols = nByte ? nByte : 256;
1881         nRows = nUINT16;
1882     }
1883 
1884     pMatrix = aPool.GetMatrix( n );
1885 
1886     if( NULL != pMatrix )
1887     {
1888         pMatrix->Resize(nCols, nRows);
1889         pMatrix->GetDimensions( nC, nR);
1890         if( nC != nCols || nR != nRows )
1891         {
1892             DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - matrix size mismatch" );
1893             pMatrix = NULL;
1894         }
1895     }
1896     else
1897     {
1898         DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - missing matrix" );
1899     }
1900 
1901     for( nR = 0 ; nR < nRows; nR++ )
1902     {
1903         for( nC = 0 ; nC < nCols; nC++ )
1904         {
1905             aIn >> nByte;
1906             switch( nByte )
1907             {
1908                 case EXC_CACHEDVAL_EMPTY:
1909                     aIn.Ignore( 8 );
1910                     if( NULL != pMatrix )
1911                     {
1912                         pMatrix->PutEmpty( nC, nR );
1913                     }
1914                     break;
1915 
1916                 case EXC_CACHEDVAL_DOUBLE:
1917                     aIn >> fDouble;
1918                     if( NULL != pMatrix )
1919                     {
1920                         pMatrix->PutDouble( fDouble, nC, nR );
1921                     }
1922                     break;
1923 
1924                 case EXC_CACHEDVAL_STRING:
1925                     if( GetBiff() == EXC_BIFF8 )
1926                     {
1927                         aIn >> nUINT16;
1928                         aString = aIn.ReadUniString( nUINT16 );
1929                     }
1930                     else
1931                     {
1932                         aIn >> nByte;
1933                         aString = aIn.ReadRawByteString( nByte );
1934                     }
1935                     if( NULL != pMatrix )
1936                     {
1937                         pMatrix->PutString( aString, nC, nR );
1938                     }
1939                     break;
1940 
1941                 case EXC_CACHEDVAL_BOOL:
1942                     aIn >> nByte;
1943                     aIn.Ignore( 7 );
1944                     if( NULL != pMatrix )
1945                     {
1946                         pMatrix->PutBoolean( nByte != 0, nC, nR );
1947                     }
1948                     break;
1949 
1950                 case EXC_CACHEDVAL_ERROR:
1951                     aIn >> nByte;
1952                     aIn.Ignore( 7 );
1953                     if( NULL != pMatrix )
1954                     {
1955                         pMatrix->PutError( XclTools::GetScErrorCode( nByte ), nC, nR );
1956                     }
1957                     break;
1958             }
1959         }
1960     }
1961 }
1962 
1963 void ExcelToSc::ReadExtensionNlr( XclImpStream& aIn )
1964 {
1965     // printf( "natural lang fmla;\n" );
1966 
1967     sal_uInt32 nFlags;
1968     aIn >> nFlags;
1969 
1970     sal_uInt32 nCount = nFlags & EXC_TOK_NLR_ADDMASK;
1971     aIn.Ignore( nCount * 4 ); // Drop the cell positions
1972 }
1973 
1974 void ExcelToSc::ReadExtensionMemArea( XclImpStream& aIn )
1975 {
1976     // printf( "mem area;\n" );
1977 
1978     sal_uInt16 nCount;
1979     aIn >> nCount;
1980 
1981     aIn.Ignore( nCount * ((GetBiff() == EXC_BIFF8) ? 8 : 6) ); // drop the ranges
1982 }
1983 
1984 void ExcelToSc::ReadExtensions( const ExtensionTypeVec& rExtensions,
1985                                 XclImpStream& aIn )
1986 {
1987     unsigned int nArray = 0;
1988 
1989     for( unsigned int i = 0 ; i < rExtensions.size() ; i++ )
1990     {
1991         ExtensionType eType = rExtensions[i];
1992 
1993         switch( eType )
1994         {
1995             case EXTENSION_ARRAY:
1996                 ReadExtensionArray( nArray++, aIn );
1997                 break;
1998 
1999             case EXTENSION_NLR:
2000                 ReadExtensionNlr( aIn );
2001                 break;
2002 
2003             case EXTENSION_MEMAREA:
2004                 ReadExtensionMemArea( aIn );
2005                 break;
2006         }
2007     }
2008 }
2009 
2010