1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28
29 // INCLUDE ---------------------------------------------------------------
30
31 #include <stdio.h>
32 #include <tools/urlobj.hxx>
33 #include <svl/converter.hxx>
34 #include <svl/zforlist.hxx>
35 #include <comphelper/types.hxx>
36 #include <ucbhelper/content.hxx>
37 #include <unotools/sharedunocomponent.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <svx/txenctab.hxx>
40 #include <svx/dbcharsethelper.hxx>
41
42 #include <com/sun/star/sdb/CommandType.hpp>
43 #include <com/sun/star/sdbc/DataType.hpp>
44 #include <com/sun/star/sdbc/XConnection.hpp>
45 #include <com/sun/star/sdbc/XDriver.hpp>
46 #include <com/sun/star/sdbc/XDriverAccess.hpp>
47 #include <com/sun/star/sdbc/XDriverManager.hpp>
48 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
49 #include <com/sun/star/sdbc/XRow.hpp>
50 #include <com/sun/star/sdbc/XRowSet.hpp>
51 #include <com/sun/star/sdbc/XRowUpdate.hpp>
52 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
53 #include <com/sun/star/sdbcx/XAppend.hpp>
54 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
55 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
56 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
57 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
58 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
59 #include <com/sun/star/beans/XPropertySet.hpp>
60 #include <com/sun/star/container/XEnumerationAccess.hpp>
61 #include <com/sun/star/lang/XComponent.hpp>
62 #include <com/sun/star/ucb/NameClash.hpp>
63 #include <com/sun/star/ucb/TransferInfo.hpp>
64 #include <com/sun/star/ucb/XCommandInfo.hpp>
65
66 #include "scerrors.hxx"
67 #include "docsh.hxx"
68 #include "filter.hxx"
69 #include "progress.hxx"
70 #include "collect.hxx"
71 #include "cell.hxx"
72 #include "editutil.hxx"
73 #include "cellform.hxx"
74 #include "dbdocutl.hxx"
75 #include "dociter.hxx"
76 #include "globstr.hrc"
77
78 using namespace com::sun::star;
79
80 // -----------------------------------------------------------------------
81
82 #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
83 #define SC_SERVICE_DRVMAN "com.sun.star.sdbc.DriverManager"
84
85 //! move to a header file?
86 //#define SC_DBPROP_DATASOURCENAME "DataSourceName"
87 #define SC_DBPROP_ACTIVECONNECTION "ActiveConnection"
88 #define SC_DBPROP_COMMAND "Command"
89 #define SC_DBPROP_COMMANDTYPE "CommandType"
90
91 #define SC_DBPROP_NAME "Name"
92 #define SC_DBPROP_TYPE "Type"
93 #define SC_DBPROP_PRECISION "Precision"
94 #define SC_DBPROP_SCALE "Scale"
95
96 #define SC_DBPROP_EXTENSION "Extension"
97 #define SC_DBPROP_CHARSET "CharSet"
98
99 #define SC_ROWCOUNT_ERROR (-1)
100
101 namespace
102 {
lcl_getDBaseConnection(uno::Reference<sdbc::XDriverManager> & _rDrvMgr,uno::Reference<sdbc::XConnection> & _rConnection,String & _rTabName,const String & rFullFileName,rtl_TextEncoding eCharSet)103 sal_uLong lcl_getDBaseConnection(uno::Reference<sdbc::XDriverManager>& _rDrvMgr,uno::Reference<sdbc::XConnection>& _rConnection,String& _rTabName,const String& rFullFileName,rtl_TextEncoding eCharSet)
104 {
105 INetURLObject aURL;
106 aURL.SetSmartProtocol( INET_PROT_FILE );
107 aURL.SetSmartURL( rFullFileName );
108 _rTabName = aURL.getBase( INetURLObject::LAST_SEGMENT, true,
109 INetURLObject::DECODE_UNAMBIGUOUS );
110 String aExtension = aURL.getExtension();
111 aURL.removeSegment();
112 aURL.removeFinalSlash();
113 String aPath = aURL.GetMainURL(INetURLObject::NO_DECODE);
114 uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
115 if (!xFactory.is()) return SCERR_EXPORT_CONNECT;
116
117 _rDrvMgr.set( xFactory->createInstance(
118 rtl::OUString::createFromAscii( SC_SERVICE_DRVMAN ) ),
119 uno::UNO_QUERY);
120 DBG_ASSERT( _rDrvMgr.is(), "can't get DriverManager" );
121 if (!_rDrvMgr.is()) return SCERR_EXPORT_CONNECT;
122
123 // get connection
124
125 String aConnUrl = String::CreateFromAscii("sdbc:dbase:");
126 aConnUrl += aPath;
127
128 svxform::ODataAccessCharsetHelper aHelper;
129 ::std::vector< rtl_TextEncoding > aEncodings;
130 aHelper.getSupportedTextEncodings( aEncodings );
131 ::std::vector< rtl_TextEncoding >::iterator aIter = ::std::find(aEncodings.begin(),aEncodings.end(),(rtl_TextEncoding) eCharSet);
132 if ( aIter == aEncodings.end() )
133 {
134 DBG_ERRORFILE( "DBaseImport: dbtools::OCharsetMap doesn't know text encoding" );
135 return SCERR_IMPORT_CONNECT;
136 } // if ( aIter == aMap.end() )
137 rtl::OUString aCharSetStr;
138 if ( RTL_TEXTENCODING_DONTKNOW != *aIter )
139 { // it's not the virtual "system charset"
140 const char* pIanaName = rtl_getMimeCharsetFromTextEncoding( *aIter );
141 OSL_ENSURE( pIanaName, "invalid mime name!" );
142 if ( pIanaName )
143 aCharSetStr = ::rtl::OUString::createFromAscii( pIanaName );
144 }
145
146 uno::Sequence<beans::PropertyValue> aProps(2);
147 aProps[0].Name = rtl::OUString::createFromAscii(SC_DBPROP_EXTENSION);
148 aProps[0].Value <<= rtl::OUString( aExtension );
149 aProps[1].Name = rtl::OUString::createFromAscii(SC_DBPROP_CHARSET);
150 aProps[1].Value <<= aCharSetStr;
151
152 _rConnection = _rDrvMgr->getConnectionWithInfo( aConnUrl, aProps );
153 return 0L;
154 }
155 }
156 // -----------------------------------------------------------------------
157 // MoveFile/KillFile/IsDocument: similar to SfxContentHelper
158
159 // static
MoveFile(const INetURLObject & rSourceObj,const INetURLObject & rDestObj)160 sal_Bool ScDocShell::MoveFile( const INetURLObject& rSourceObj, const INetURLObject& rDestObj )
161 {
162 sal_Bool bMoveData = sal_True;
163 sal_Bool bRet = sal_True, bKillSource = sal_False;
164 if ( rSourceObj.GetProtocol() != rDestObj.GetProtocol() )
165 {
166 bMoveData = sal_False;
167 bKillSource = sal_True;
168 }
169 String aName = rDestObj.getName();
170 INetURLObject aDestPathObj = rDestObj;
171 aDestPathObj.removeSegment();
172 aDestPathObj.setFinalSlash();
173
174 try
175 {
176 ::ucbhelper::Content aDestPath( aDestPathObj.GetMainURL(INetURLObject::NO_DECODE),
177 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
178 uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands();
179 rtl::OUString aTransferName = rtl::OUString::createFromAscii( "transfer" );
180 if ( xInfo->hasCommandByName( aTransferName ) )
181 {
182 aDestPath.executeCommand( aTransferName, uno::makeAny(
183 ::com::sun::star::ucb::TransferInfo( bMoveData, rSourceObj.GetMainURL(INetURLObject::NO_DECODE), aName,
184 ::com::sun::star::ucb::NameClash::ERROR ) ) );
185 }
186 else
187 {
188 DBG_ERRORFILE( "transfer command not available" );
189 }
190 }
191 catch( uno::Exception& )
192 {
193 // ucb may throw different exceptions on failure now
194 bRet = sal_False;
195 }
196
197 if ( bKillSource )
198 KillFile( rSourceObj );
199
200 return bRet;
201 }
202
203
204 // static
KillFile(const INetURLObject & rURL)205 sal_Bool ScDocShell::KillFile( const INetURLObject& rURL )
206 {
207 sal_Bool bRet = sal_True;
208 try
209 {
210 ::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE),
211 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
212 aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ),
213 comphelper::makeBoolAny( sal_True ) );
214 }
215 catch( uno::Exception& )
216 {
217 // ucb may throw different exceptions on failure now
218 bRet = sal_False;
219 }
220
221 return bRet;
222 }
223
224 // static
IsDocument(const INetURLObject & rURL)225 sal_Bool ScDocShell::IsDocument( const INetURLObject& rURL )
226 {
227 sal_Bool bRet = sal_False;
228 try
229 {
230 ::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE),
231 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
232 bRet = aCnt.isDocument();
233 }
234 catch( uno::Exception& )
235 {
236 // ucb may throw different exceptions on failure now - warning only
237 DBG_WARNING( "Any other exception" );
238 }
239
240 return bRet;
241 }
242
243 // -----------------------------------------------------------------------
244
DBaseImport(const String & rFullFileName,CharSet eCharSet,sal_Bool bSimpleColWidth[MAXCOLCOUNT])245 sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
246 sal_Bool bSimpleColWidth[MAXCOLCOUNT] )
247 {
248 sal_uLong nErr = eERR_OK;
249 long i;
250 long nColCount = 0;
251
252 try
253 {
254 String aTabName;
255 uno::Reference<sdbc::XDriverManager> xDrvMan;
256 uno::Reference<sdbc::XConnection> xConnection;
257 sal_uLong nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
258 if ( !xConnection.is() || !xDrvMan.is() )
259 return nRet;
260 ::utl::DisposableComponent aConnectionHelper(xConnection);
261
262 ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), 0 );
263 uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
264 uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(
265 rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
266 uno::UNO_QUERY);
267 ::utl::DisposableComponent aRowSetHelper(xRowSet);
268 uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
269 DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
270 if (!xRowProp.is()) return SCERR_IMPORT_CONNECT;
271
272 sal_Int32 nType = sdb::CommandType::TABLE;
273 uno::Any aAny;
274
275 aAny <<= xConnection;
276 xRowProp->setPropertyValue(
277 rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny );
278
279 aAny <<= nType;
280 xRowProp->setPropertyValue(
281 rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
282
283 aAny <<= rtl::OUString( aTabName );
284 xRowProp->setPropertyValue(
285 rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
286
287 xRowSet->execute();
288
289 uno::Reference<sdbc::XResultSetMetaData> xMeta;
290 uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY );
291 if ( xMetaSupp.is() )
292 xMeta = xMetaSupp->getMetaData();
293 if ( xMeta.is() )
294 nColCount = xMeta->getColumnCount(); // this is the number of real columns
295
296 if ( nColCount > MAXCOL+1 )
297 {
298 nColCount = MAXCOL+1;
299 nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning
300 }
301
302 uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY );
303 DBG_ASSERT( xRow.is(), "can't get Row" );
304 if (!xRow.is()) return SCERR_IMPORT_CONNECT;
305
306 // currency flag is not needed for dBase
307 uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types
308 sal_Int32* pTypeArr = aColTypes.getArray();
309 for (i=0; i<nColCount; i++)
310 pTypeArr[i] = xMeta->getColumnType( i+1 );
311
312 // read column names
313 //! add type descriptions
314
315 aProgress.SetState( 0 );
316 ScColumn::bDoubleAlloc = sal_True; // row count isn't readily available in advance
317
318 for (i=0; i<nColCount; i++)
319 {
320 String aHeader = xMeta->getColumnLabel( i+1 );
321
322 switch ( pTypeArr[i] )
323 {
324 case sdbc::DataType::BIT:
325 aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" ));
326 break;
327 case sdbc::DataType::DATE:
328 aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" ));
329 break;
330 case sdbc::DataType::LONGVARCHAR:
331 aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" ));
332 break;
333 case sdbc::DataType::VARCHAR:
334 aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," ));
335 aHeader += String::CreateFromInt32( xMeta->getColumnDisplaySize( i+1 ) );
336 break;
337 case sdbc::DataType::DECIMAL:
338 {
339 long nPrec = xMeta->getPrecision( i+1 );
340 long nScale = xMeta->getScale( i+1 );
341 aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," ));
342 aHeader += String::CreateFromInt32(
343 SvDbaseConverter::ConvertPrecisionToDbase(
344 nPrec, nScale ) );
345 aHeader += ',';
346 aHeader += String::CreateFromInt32( nScale );
347 }
348 break;
349 }
350
351 aDocument.SetString( static_cast<SCCOL>(i), 0, 0, aHeader );
352 }
353
354 SCROW nRow = 1; // 0 is column titles
355 sal_Bool bEnd = sal_False;
356 while ( !bEnd && xRowSet->next() )
357 {
358 if ( nRow <= MAXROW )
359 {
360 SCCOL nCol = 0;
361 for (i=0; i<nColCount; i++)
362 {
363 ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0,
364 xRow, i+1, pTypeArr[i], sal_False,
365 &bSimpleColWidth[nCol] );
366 ++nCol;
367 }
368 ++nRow;
369 }
370 else // past the end of the spreadsheet
371 {
372 bEnd = sal_True; // don't continue
373 nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning message
374 }
375 }
376 }
377 catch ( sdbc::SQLException& )
378 {
379 nErr = SCERR_IMPORT_CONNECT;
380 }
381 catch ( uno::Exception& )
382 {
383 DBG_ERROR("Unexpected exception in database");
384 nErr = ERRCODE_IO_GENERAL;
385 }
386
387 ScColumn::bDoubleAlloc = sal_False;
388 if ( nColCount > 0 )
389 aDocument.DoColResize( 0, 0, static_cast<SCCOL>(nColCount) - 1, 0 );
390
391 return nErr;
392 }
393
394 // -----------------------------------------------------------------------
395
IsAsciiDigit(sal_Unicode c)396 inline sal_Bool IsAsciiDigit( sal_Unicode c )
397 {
398 return 0x30 <= c && c <= 0x39;
399 }
400
IsAsciiAlpha(sal_Unicode c)401 inline sal_Bool IsAsciiAlpha( sal_Unicode c )
402 {
403 return (0x41 <= c && c <= 0x5a) || (0x61 <= c && c <= 0x7a);
404 }
405
lcl_GetColumnTypes(ScDocShell & rDocShell,const ScRange & rDataRange,sal_Bool bHasFieldNames,rtl::OUString * pColNames,sal_Int32 * pColTypes,sal_Int32 * pColLengths,sal_Int32 * pColScales,sal_Bool & bHasMemo,CharSet eCharSet)406 void lcl_GetColumnTypes( ScDocShell& rDocShell,
407 const ScRange& rDataRange, sal_Bool bHasFieldNames,
408 rtl::OUString* pColNames, sal_Int32* pColTypes,
409 sal_Int32* pColLengths, sal_Int32* pColScales,
410 sal_Bool& bHasMemo, CharSet eCharSet )
411 {
412 // updating of column titles didn't work in 5.2 and isn't always wanted
413 // (saving normally shouldn't modify the document)
414 //! read flag from configuration
415 sal_Bool bUpdateTitles = sal_False;
416
417 ScDocument* pDoc = rDocShell.GetDocument();
418 SvNumberFormatter* pNumFmt = pDoc->GetFormatTable();
419
420 SCTAB nTab = rDataRange.aStart.Tab();
421 SCCOL nFirstCol = rDataRange.aStart.Col();
422 SCROW nFirstRow = rDataRange.aStart.Row();
423 SCCOL nLastCol = rDataRange.aEnd.Col();
424 SCROW nLastRow = rDataRange.aEnd.Row();
425
426 ScStrCollection aFieldNamesCollection;
427
428 long nField = 0;
429 SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
430 for ( SCCOL nCol = nFirstCol; nCol <= nLastCol; nCol++ )
431 {
432 sal_Bool bTypeDefined = sal_False;
433 sal_Bool bPrecDefined = sal_False;
434 sal_Int32 nFieldLen = 0;
435 sal_Int32 nPrecision = 0;
436 sal_Int32 nDbType = sdbc::DataType::SQLNULL;
437 String aFieldName, aString;
438
439 // Feldname[,Type[,Width[,Prec]]]
440 // Typ etc.: L; D; C[,W]; N[,W[,P]]
441 if ( bHasFieldNames )
442 {
443 pDoc->GetString( nCol, nFirstRow, nTab, aString );
444 aString.ToUpperAscii();
445 xub_StrLen nToken = aString.GetTokenCount( ',' );
446 if ( nToken > 1 )
447 {
448 aFieldName = aString.GetToken( 0, ',' );
449 aString.EraseAllChars( ' ' );
450 switch ( aString.GetToken( 1, ',' ).GetChar(0) )
451 {
452 case 'L' :
453 nDbType = sdbc::DataType::BIT;
454 nFieldLen = 1;
455 bTypeDefined = sal_True;
456 bPrecDefined = sal_True;
457 break;
458 case 'D' :
459 nDbType = sdbc::DataType::DATE;
460 nFieldLen = 8;
461 bTypeDefined = sal_True;
462 bPrecDefined = sal_True;
463 break;
464 case 'M' :
465 nDbType = sdbc::DataType::LONGVARCHAR;
466 nFieldLen = 10;
467 bTypeDefined = sal_True;
468 bPrecDefined = sal_True;
469 bHasMemo = sal_True;
470 break;
471 case 'C' :
472 nDbType = sdbc::DataType::VARCHAR;
473 bTypeDefined = sal_True;
474 bPrecDefined = sal_True;
475 break;
476 case 'N' :
477 nDbType = sdbc::DataType::DECIMAL;
478 bTypeDefined = sal_True;
479 break;
480 }
481 if ( bTypeDefined && !nFieldLen && nToken > 2 )
482 {
483 nFieldLen = aString.GetToken( 2, ',' ).ToInt32();
484 if ( !bPrecDefined && nToken > 3 )
485 {
486 String aTmp( aString.GetToken( 3, ',' ) );
487 if ( CharClass::isAsciiNumeric(aTmp) )
488 {
489 nPrecision = aTmp.ToInt32();
490 bPrecDefined = sal_True;
491 }
492 }
493 }
494 }
495 else
496 aFieldName = aString;
497
498 // Feldnamen pruefen und ggbf. gueltigen Feldnamen erzeugen.
499 // Erstes Zeichen muss Buchstabe sein,
500 // weitere nur alphanumerisch und Unterstrich erlaubt,
501 // "_DBASELOCK" ist reserviert (obsolet weil erstes Zeichen kein Buchstabe),
502 // keine doppelten Namen.
503 if ( !IsAsciiAlpha( aFieldName.GetChar(0) ) )
504 aFieldName.Insert( 'N', 0 );
505 String aTmpStr;
506 sal_Unicode c;
507 for ( const sal_Unicode* p = aFieldName.GetBuffer(); ( c = *p ) != 0; p++ )
508 {
509 if ( IsAsciiAlpha( c ) || IsAsciiDigit( c ) || c == '_' )
510 aTmpStr += c;
511 else
512 aTmpStr += '_';
513 }
514 aFieldName = aTmpStr;
515 if ( aFieldName.Len() > 10 )
516 aFieldName.Erase( 10 );
517 StrData* pStrData = new StrData( aFieldName );
518 if ( !aFieldNamesCollection.Insert( pStrData ) )
519 { // doppelter Feldname, numerisch erweitern
520 sal_uInt16 nSub = 1;
521 String aFixPart( aFieldName );
522 do
523 {
524 ++nSub;
525 String aVarPart = String::CreateFromInt32( nSub );
526 if ( aFixPart.Len() + aVarPart.Len() > 10 )
527 aFixPart.Erase( 10 - aVarPart.Len() );
528 aFieldName = aFixPart;
529 aFieldName += aVarPart;
530 pStrData->SetString( aFieldName );
531 } while ( !aFieldNamesCollection.Insert( pStrData ) );
532 }
533 }
534 else
535 {
536 aFieldName = 'N';
537 aFieldName += String::CreateFromInt32(nCol+1);
538 }
539
540 if ( !bTypeDefined )
541 { // Feldtyp
542 ScBaseCell* pCell;
543 pDoc->GetCell( nCol, nFirstDataRow, nTab, pCell );
544 if ( !pCell || pCell->HasStringData() )
545 nDbType = sdbc::DataType::VARCHAR;
546 else
547 {
548 sal_uInt32 nFormat;
549 pDoc->GetNumberFormat( nCol, nFirstDataRow, nTab, nFormat );
550 if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
551 && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) )
552 {
553 nFormat = ScGlobal::GetStandardFormat(
554 ((ScFormulaCell*)pCell)->GetValue(), *pNumFmt, nFormat,
555 ((ScFormulaCell*)pCell)->GetFormatType() );
556 }
557 switch ( pNumFmt->GetType( nFormat ) )
558 {
559 case NUMBERFORMAT_LOGICAL :
560 nDbType = sdbc::DataType::BIT;
561 nFieldLen = 1;
562 break;
563 case NUMBERFORMAT_DATE :
564 nDbType = sdbc::DataType::DATE;
565 nFieldLen = 8;
566 break;
567 case NUMBERFORMAT_TIME :
568 case NUMBERFORMAT_DATETIME :
569 nDbType = sdbc::DataType::VARCHAR;
570 break;
571 default:
572 nDbType = sdbc::DataType::DECIMAL;
573 }
574 }
575 }
576 sal_Bool bSdbLenAdjusted = sal_False;
577 sal_Bool bSdbLenBad = sal_False;
578 // Feldlaenge
579 if ( nDbType == sdbc::DataType::VARCHAR && !nFieldLen )
580 { // maximale Feldbreite bestimmen
581 nFieldLen = pDoc->GetMaxStringLen( nTab, nCol, nFirstDataRow,
582 nLastRow, eCharSet );
583 if ( nFieldLen == 0 )
584 nFieldLen = 1;
585 }
586 else if ( nDbType == sdbc::DataType::DECIMAL )
587 { // maximale Feldbreite und Nachkommastellen bestimmen
588 xub_StrLen nLen;
589 sal_uInt16 nPrec;
590 nLen = pDoc->GetMaxNumberStringLen( nPrec, nTab, nCol,
591 nFirstDataRow, nLastRow );
592 // dBaseIII Limit Nachkommastellen: 15
593 if ( nPrecision > 15 )
594 nPrecision = 15;
595 if ( nPrec > 15 )
596 nPrec = 15;
597 if ( bPrecDefined && nPrecision != nPrec )
598 { // Laenge auf vorgegebene Nachkommastellen anpassen
599 if ( nPrecision )
600 nLen = sal::static_int_cast<xub_StrLen>( nLen + ( nPrecision - nPrec ) );
601 else
602 nLen -= nPrec+1; // auch den . mit raus
603 }
604 if ( nLen > nFieldLen && !bTypeDefined )
605 nFieldLen = nLen;
606 if ( !bPrecDefined )
607 nPrecision = nPrec;
608 if ( nFieldLen == 0 )
609 nFieldLen = 1;
610 else if ( nFieldLen > 19 )
611 nFieldLen = 19; // dBaseIII Limit Feldlaenge numerisch: 19
612 if ( nPrecision && nFieldLen < nPrecision + 2 )
613 nFieldLen = nPrecision + 2; // 0. muss mit reinpassen
614 // 538 MUST: Sdb internal representation adds 2 to the field length!
615 // To give the user what he wants we must substract it here.
616 //! CAVEAT! There is no way to define a numeric field with a length
617 //! of 1 and no decimals!
618 if ( nFieldLen == 1 && nPrecision == 0 )
619 bSdbLenBad = sal_True;
620 nFieldLen = SvDbaseConverter::ConvertPrecisionToOdbc( nFieldLen, nPrecision );
621 bSdbLenAdjusted = sal_True;
622 }
623 if ( nFieldLen > 254 )
624 {
625 if ( nDbType == sdbc::DataType::VARCHAR )
626 { // zu lang fuer normales Textfeld => Memofeld
627 nDbType = sdbc::DataType::LONGVARCHAR;
628 nFieldLen = 10;
629 bHasMemo = sal_True;
630 }
631 else
632 nFieldLen = 254; // dumm gelaufen..
633 }
634
635 pColNames[nField] = aFieldName;
636 pColTypes[nField] = nDbType;
637 pColLengths[nField] = nFieldLen;
638 pColScales[nField] = nPrecision;
639
640 // undo change to field length, reflect reality
641 if ( bSdbLenAdjusted )
642 {
643 nFieldLen = SvDbaseConverter::ConvertPrecisionToDbase( nFieldLen, nPrecision );
644 if ( bSdbLenBad && nFieldLen == 1 )
645 nFieldLen = 2; // THIS is reality
646 }
647 if ( bUpdateTitles )
648 { // Angabe anpassen und ausgeben
649 String aOutString = aFieldName;
650 switch ( nDbType )
651 {
652 case sdbc::DataType::BIT :
653 aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" ));
654 break;
655 case sdbc::DataType::DATE :
656 aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" ));
657 break;
658 case sdbc::DataType::LONGVARCHAR :
659 aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" ));
660 break;
661 case sdbc::DataType::VARCHAR :
662 aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," ));
663 aOutString += String::CreateFromInt32( nFieldLen );
664 break;
665 case sdbc::DataType::DECIMAL :
666 aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," ));
667 aOutString += String::CreateFromInt32( nFieldLen );
668 aOutString += ',';
669 aOutString += String::CreateFromInt32( nPrecision );
670 break;
671 }
672 if ( !aOutString.EqualsIgnoreCaseAscii( aString ) )
673 {
674 pDoc->SetString( nCol, nFirstRow, nTab, aOutString );
675 rDocShell.PostPaint( nCol, nFirstRow, nTab, nCol, nFirstRow, nTab, PAINT_GRID );
676 }
677 }
678 ++nField;
679 }
680 }
681
682
lcl_getLongVarCharEditString(String & rString,const ScBaseCell * pCell,ScFieldEditEngine & rEditEngine)683 inline void lcl_getLongVarCharEditString( String& rString,
684 const ScBaseCell* pCell, ScFieldEditEngine& rEditEngine )
685 {
686 rEditEngine.SetText( *((const ScEditCell*)pCell)->GetData() );
687 rString = rEditEngine.GetText( LINEEND_CRLF );
688 }
689
lcl_getLongVarCharString(String & rString,ScBaseCell * pCell,ScDocument & rDocument,SCCOL nCol,SCROW nRow,SCTAB nTab,SvNumberFormatter & rNumFmt)690 inline void lcl_getLongVarCharString( String& rString, ScBaseCell* pCell,
691 ScDocument& rDocument, SCCOL nCol, SCROW nRow, SCTAB nTab,
692 SvNumberFormatter& rNumFmt )
693 {
694 sal_uInt32 nFormat;
695 Color* pColor;
696 rDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
697 ScCellFormat::GetString( pCell, nFormat, rString, &pColor, rNumFmt );
698 }
699
700
DBaseExport(const String & rFullFileName,CharSet eCharSet,sal_Bool & bHasMemo)701 sal_uLong ScDocShell::DBaseExport( const String& rFullFileName, CharSet eCharSet, sal_Bool& bHasMemo )
702 {
703 // remove the file so the dBase driver doesn't find an invalid file
704 INetURLObject aDeleteObj( rFullFileName, INET_PROT_FILE );
705 KillFile( aDeleteObj );
706
707 sal_uLong nErr = eERR_OK;
708 uno::Any aAny;
709
710 SCCOL nFirstCol, nLastCol;
711 SCROW nFirstRow, nLastRow;
712 SCTAB nTab = GetSaveTab();
713 aDocument.GetDataStart( nTab, nFirstCol, nFirstRow );
714 aDocument.GetCellArea( nTab, nLastCol, nLastRow );
715 if ( nFirstCol > nLastCol )
716 nFirstCol = nLastCol;
717 if ( nFirstRow > nLastRow )
718 nFirstRow = nLastRow;
719 ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ),
720 nLastRow - nFirstRow );
721 SvNumberFormatter* pNumFmt = aDocument.GetFormatTable();
722
723 sal_Bool bHasFieldNames = sal_True;
724 for ( SCCOL nDocCol = nFirstCol; nDocCol <= nLastCol && bHasFieldNames; nDocCol++ )
725 { // nur Strings in erster Zeile => sind Feldnamen
726 if ( !aDocument.HasStringData( nDocCol, nFirstRow, nTab ) )
727 bHasFieldNames = sal_False;
728 }
729
730 long nColCount = nLastCol - nFirstCol + 1;
731 uno::Sequence<rtl::OUString> aColNames( nColCount );
732 uno::Sequence<sal_Int32> aColTypes( nColCount );
733 uno::Sequence<sal_Int32> aColLengths( nColCount );
734 uno::Sequence<sal_Int32> aColScales( nColCount );
735
736 ScRange aDataRange( nFirstCol, nFirstRow, nTab, nLastCol, nLastRow, nTab );
737 lcl_GetColumnTypes( *this, aDataRange, bHasFieldNames,
738 aColNames.getArray(), aColTypes.getArray(),
739 aColLengths.getArray(), aColScales.getArray(),
740 bHasMemo, eCharSet );
741 // also needed for exception catch
742 SCROW nDocRow = 0;
743 ScFieldEditEngine aEditEngine( aDocument.GetEditPool() );
744 String aString;
745 String aTabName;
746
747 try
748 {
749 uno::Reference<sdbc::XDriverManager> xDrvMan;
750 uno::Reference<sdbc::XConnection> xConnection;
751 sal_uLong nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet);
752 if ( !xConnection.is() || !xDrvMan.is() )
753 return nRet;
754 ::utl::DisposableComponent aConnectionHelper(xConnection);
755
756 // get dBase driver
757 uno::Reference< sdbc::XDriverAccess> xAccess(xDrvMan,uno::UNO_QUERY);
758 uno::Reference< sdbcx::XDataDefinitionSupplier > xDDSup( xAccess->getDriverByURL( xConnection->getMetaData()->getURL() ), uno::UNO_QUERY );
759 if ( !xDDSup.is() )
760 return SCERR_EXPORT_CONNECT;
761
762 // create table
763 uno::Reference<sdbcx::XTablesSupplier> xTablesSupp =xDDSup->getDataDefinitionByConnection( xConnection );
764 DBG_ASSERT( xTablesSupp.is(), "can't get Data Definition" );
765 if (!xTablesSupp.is()) return SCERR_EXPORT_CONNECT;
766
767 uno::Reference<container::XNameAccess> xTables = xTablesSupp->getTables();
768 DBG_ASSERT( xTables.is(), "can't get Tables" );
769 if (!xTables.is()) return SCERR_EXPORT_CONNECT;
770
771 uno::Reference<sdbcx::XDataDescriptorFactory> xTablesFact( xTables, uno::UNO_QUERY );
772 DBG_ASSERT( xTablesFact.is(), "can't get tables factory" );
773 if (!xTablesFact.is()) return SCERR_EXPORT_CONNECT;
774
775 uno::Reference<sdbcx::XAppend> xTablesAppend( xTables, uno::UNO_QUERY );
776 DBG_ASSERT( xTablesAppend.is(), "can't get tables XAppend" );
777 if (!xTablesAppend.is()) return SCERR_EXPORT_CONNECT;
778
779 uno::Reference<beans::XPropertySet> xTableDesc = xTablesFact->createDataDescriptor();
780 DBG_ASSERT( xTableDesc.is(), "can't get table descriptor" );
781 if (!xTableDesc.is()) return SCERR_EXPORT_CONNECT;
782
783 aAny <<= rtl::OUString( aTabName );
784 xTableDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny );
785
786 // create columns
787
788 uno::Reference<sdbcx::XColumnsSupplier> xColumnsSupp( xTableDesc, uno::UNO_QUERY );
789 DBG_ASSERT( xColumnsSupp.is(), "can't get columns supplier" );
790 if (!xColumnsSupp.is()) return SCERR_EXPORT_CONNECT;
791
792 uno::Reference<container::XNameAccess> xColumns = xColumnsSupp->getColumns();
793 DBG_ASSERT( xColumns.is(), "can't get columns" );
794 if (!xColumns.is()) return SCERR_EXPORT_CONNECT;
795
796 uno::Reference<sdbcx::XDataDescriptorFactory> xColumnsFact( xColumns, uno::UNO_QUERY );
797 DBG_ASSERT( xColumnsFact.is(), "can't get columns factory" );
798 if (!xColumnsFact.is()) return SCERR_EXPORT_CONNECT;
799
800 uno::Reference<sdbcx::XAppend> xColumnsAppend( xColumns, uno::UNO_QUERY );
801 DBG_ASSERT( xColumnsAppend.is(), "can't get columns XAppend" );
802 if (!xColumnsAppend.is()) return SCERR_EXPORT_CONNECT;
803
804 const rtl::OUString* pColNames = aColNames.getConstArray();
805 const sal_Int32* pColTypes = aColTypes.getConstArray();
806 const sal_Int32* pColLengths = aColLengths.getConstArray();
807 const sal_Int32* pColScales = aColScales.getConstArray();
808 long nCol;
809
810 for (nCol=0; nCol<nColCount; nCol++)
811 {
812 uno::Reference<beans::XPropertySet> xColumnDesc = xColumnsFact->createDataDescriptor();
813 DBG_ASSERT( xColumnDesc.is(), "can't get column descriptor" );
814 if (!xColumnDesc.is()) return SCERR_EXPORT_CONNECT;
815
816 aAny <<= pColNames[nCol];
817 xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny );
818
819 aAny <<= pColTypes[nCol];
820 xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_TYPE), aAny );
821
822 aAny <<= pColLengths[nCol];
823 xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_PRECISION), aAny );
824
825 aAny <<= pColScales[nCol];
826 xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_SCALE), aAny );
827
828 xColumnsAppend->appendByDescriptor( xColumnDesc );
829 }
830
831 xTablesAppend->appendByDescriptor( xTableDesc );
832
833 // re-open connection
834 // xConnection = xDrvMan->getConnectionWithInfo( aConnUrl, aProps );
835 // DBG_ASSERT( xConnection.is(), "can't get Connection" );
836 // if (!xConnection.is()) return SCERR_EXPORT_CONNECT;
837
838 // get row set for writing
839 uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory();
840 uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance(
841 rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
842 uno::UNO_QUERY);
843 ::utl::DisposableComponent aRowSetHelper(xRowSet);
844 uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
845 DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
846 if (!xRowProp.is()) return SCERR_EXPORT_CONNECT;
847
848 aAny <<= xConnection;
849 xRowProp->setPropertyValue(
850 rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny );
851
852 aAny <<= (sal_Int32) sdb::CommandType::TABLE;
853 xRowProp->setPropertyValue(
854 rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
855
856 aAny <<= rtl::OUString( aTabName );
857 xRowProp->setPropertyValue(
858 rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
859
860 xRowSet->execute();
861
862 // write data rows
863
864 uno::Reference<sdbc::XResultSetUpdate> xResultUpdate( xRowSet, uno::UNO_QUERY );
865 DBG_ASSERT( xResultUpdate.is(), "can't get XResultSetUpdate" );
866 if (!xResultUpdate.is()) return SCERR_EXPORT_CONNECT;
867
868 uno::Reference<sdbc::XRowUpdate> xRowUpdate( xRowSet, uno::UNO_QUERY );
869 DBG_ASSERT( xRowUpdate.is(), "can't get XRowUpdate" );
870 if (!xRowUpdate.is()) return SCERR_EXPORT_CONNECT;
871
872 SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow );
873 double fVal;
874
875 for ( nDocRow = nFirstDataRow; nDocRow <= nLastRow; nDocRow++ )
876 {
877 xResultUpdate->moveToInsertRow();
878
879 for (nCol=0; nCol<nColCount; nCol++)
880 {
881 SCCOL nDocCol = sal::static_int_cast<SCCOL>( nFirstCol + nCol );
882
883 switch (pColTypes[nCol])
884 {
885 case sdbc::DataType::LONGVARCHAR:
886 {
887 ScBaseCell* pCell;
888 aDocument.GetCell( nDocCol, nDocRow, nTab, pCell );
889 if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
890 {
891 if ( pCell->GetCellType() == CELLTYPE_EDIT )
892 { // #60761# Paragraphs erhalten
893 lcl_getLongVarCharEditString( aString,
894 pCell, aEditEngine);
895 }
896 else
897 {
898 lcl_getLongVarCharString( aString, pCell,
899 aDocument, nDocCol, nDocRow, nTab,
900 *pNumFmt);
901 }
902 xRowUpdate->updateString( nCol+1, aString );
903 }
904 else
905 xRowUpdate->updateNull( nCol+1 );
906 }
907 break;
908
909 case sdbc::DataType::VARCHAR:
910 aDocument.GetString( nDocCol, nDocRow, nTab, aString );
911 xRowUpdate->updateString( nCol+1, aString );
912 if ( nErr == eERR_OK && pColLengths[nCol] < aString.Len() )
913 nErr = SCWARN_EXPORT_DATALOST;
914 break;
915
916 case sdbc::DataType::DATE:
917 {
918 aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
919 // #39274# zwischen 0 Wert und 0 kein Wert unterscheiden
920 sal_Bool bIsNull = (fVal == 0.0);
921 if ( bIsNull )
922 bIsNull = !aDocument.HasValueData( nDocCol, nDocRow, nTab );
923 if ( bIsNull )
924 {
925 xRowUpdate->updateNull( nCol+1 );
926 if ( nErr == eERR_OK &&
927 aDocument.HasStringData( nDocCol, nDocRow, nTab ) )
928 nErr = SCWARN_EXPORT_DATALOST;
929 }
930 else
931 {
932 Date aDate = *(pNumFmt->GetNullDate()); // tools date
933 aDate += (long)fVal; //! approxfloor?
934 util::Date aUnoDate( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() );
935 xRowUpdate->updateDate( nCol+1, aUnoDate );
936 }
937 }
938 break;
939
940 case sdbc::DataType::DECIMAL:
941 case sdbc::DataType::BIT:
942 aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
943 if ( fVal == 0.0 && nErr == eERR_OK &&
944 aDocument.HasStringData( nDocCol, nDocRow, nTab ) )
945 nErr = SCWARN_EXPORT_DATALOST;
946 if ( pColTypes[nCol] == sdbc::DataType::BIT )
947 xRowUpdate->updateBoolean( nCol+1, ( fVal != 0.0 ) );
948 else
949 xRowUpdate->updateDouble( nCol+1, fVal );
950 break;
951
952 default:
953 DBG_ERROR( "ScDocShell::DBaseExport: unknown FieldType" );
954 if ( nErr == eERR_OK )
955 nErr = SCWARN_EXPORT_DATALOST;
956 aDocument.GetValue( nDocCol, nDocRow, nTab, fVal );
957 xRowUpdate->updateDouble( nCol+1, fVal );
958 }
959 }
960
961 xResultUpdate->insertRow();
962
963 //! error handling and recovery of old
964 //! ScDocShell::SbaSdbExport is still missing!
965
966 if ( !aProgress.SetStateOnPercent( nDocRow - nFirstRow ) )
967 { // UserBreak
968 nErr = SCERR_EXPORT_DATA;
969 break;
970 }
971 }
972
973 comphelper::disposeComponent( xRowSet );
974 comphelper::disposeComponent( xConnection );
975 }
976 catch ( sdbc::SQLException& aException )
977 {
978 sal_Int32 nError = aException.ErrorCode;
979 #if OSL_DEBUG_LEVEL > 1
980 fprintf( stderr, "ScDocShell::DBaseExport: SQLException ErrorCode: %d, SQLState: %s, Message: %s\n",
981 (int)nError, OUStringToOString( aException.SQLState,
982 RTL_TEXTENCODING_UTF8).getStr(), OUStringToOString(
983 aException.Message, RTL_TEXTENCODING_UTF8).getStr());
984 #endif
985 if (nError == 22018 || nError == 22001)
986 {
987 // SQL error 22018: Character not in target encoding.
988 // SQL error 22001: String length exceeds field width (after encoding).
989 bool bEncErr = (nError == 22018);
990 bool bIsOctetTextEncoding = rtl_isOctetTextEncoding( eCharSet);
991 DBG_ASSERT( !bEncErr || bIsOctetTextEncoding, "ScDocShell::DBaseExport: encoding error and not an octect textencoding");
992 SCCOL nDocCol = nFirstCol;
993 const sal_Int32* pColTypes = aColTypes.getConstArray();
994 const sal_Int32* pColLengths = aColLengths.getConstArray();
995 ScHorizontalCellIterator aIter( &aDocument, nTab, nFirstCol,
996 nDocRow, nLastCol, nDocRow);
997 ScBaseCell* pCell = NULL;
998 bool bTest = true;
999 while (bTest && ((pCell = aIter.GetNext( nDocCol, nDocRow)) != NULL))
1000 {
1001 SCCOL nCol = nDocCol - nFirstCol;
1002 switch (pColTypes[nCol])
1003 {
1004 case sdbc::DataType::LONGVARCHAR:
1005 {
1006 if ( pCell->GetCellType() != CELLTYPE_NOTE )
1007 {
1008 if ( pCell->GetCellType() == CELLTYPE_EDIT )
1009 lcl_getLongVarCharEditString( aString,
1010 pCell, aEditEngine);
1011 else
1012 lcl_getLongVarCharString( aString,
1013 pCell, aDocument, nDocCol,
1014 nDocRow, nTab, *pNumFmt);
1015 }
1016 }
1017 break;
1018
1019 case sdbc::DataType::VARCHAR:
1020 aDocument.GetString( nDocCol, nDocRow, nTab, aString);
1021 break;
1022
1023 // NOTE: length of DECIMAL fields doesn't need to be
1024 // checked here, the database driver adjusts the field
1025 // width accordingly.
1026
1027 default:
1028 bTest = false;
1029 }
1030 if (bTest)
1031 {
1032 sal_Int32 nLen;
1033 if (bIsOctetTextEncoding)
1034 {
1035 rtl::OUString aOUString( aString);
1036 rtl::OString aOString;
1037 if (!aOUString.convertToString( &aOString, eCharSet,
1038 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1039 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
1040 {
1041 bTest = false;
1042 bEncErr = true;
1043 }
1044 nLen = aOString.getLength();
1045 #if OSL_DEBUG_LEVEL > 1
1046 if (!bTest)
1047 fprintf( stderr, "ScDocShell::DBaseExport encoding error, string with default replacements: ``%s''\n",
1048 OUStringToOString( aOUString, eCharSet).getStr());
1049 #endif
1050 }
1051 else
1052 nLen = aString.Len() * sizeof(sal_Unicode);
1053 if (!bEncErr &&
1054 pColTypes[nCol] != sdbc::DataType::LONGVARCHAR &&
1055 pColLengths[nCol] < nLen)
1056 {
1057 bTest = false;
1058 #if OSL_DEBUG_LEVEL > 1
1059 fprintf( stderr, "ScDocShell::DBaseExport: field width: %d, encoded length: %d\n",
1060 (int)pColLengths[nCol], (int)nLen);
1061 #endif
1062 }
1063 }
1064 else
1065 bTest = true;
1066 }
1067 String sPosition( ScAddress( nDocCol, nDocRow, nTab).GetColRowString());
1068 String sEncoding( SvxTextEncodingTable().GetTextString( eCharSet));
1069 nErr = *new TwoStringErrorInfo( (bEncErr ? SCERR_EXPORT_ENCODING :
1070 SCERR_EXPORT_FIELDWIDTH), sPosition, sEncoding,
1071 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR);
1072 }
1073 else if ( aException.Message.getLength() )
1074 nErr = *new StringErrorInfo( (SCERR_EXPORT_SQLEXCEPTION), aException.Message, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR);
1075 else
1076 nErr = SCERR_EXPORT_DATA;
1077 }
1078 catch ( uno::Exception& )
1079 {
1080 DBG_ERROR("Unexpected exception in database");
1081 nErr = ERRCODE_IO_GENERAL;
1082 }
1083
1084 return nErr;
1085 }
1086
1087
1088