Hi

Randy Portnoff-2 wrote:
> 
> The OLE interface to Excel (ie. HBOLE) is extremely slow and
> memory-intensive.
> 
> Is there an alternative to HBOLE (eg. third party product) that is 
> more efficient for creating XLS files?
> 

I do it like this:

1) Build a .csv file as below ( you can modify it to use dbf instead of
array )
2) Submit the resulting file to Excel and then saveas .xls file.

//----------------------------------------------------------------------//
Function Array2Excel( aData, cFileName, aAttr, lHeader, lOpenExcel )
   Local i, j, nRow := 1
   Local oApp, oWB, oAS, nRows, cType
   Local cServer := 'Excel.Application'
   Local nColumns

   DEFAULT aAttr      TO {}
   DEFAULT lHeader    TO .F.
   DEFAULT lOpenExcel TO .T.

   if empty( aAttr )
      lHeader := .f.
   endif

   if !Array2Csv( aData, cFileName, aAttr )
      Return nil
   endif

   nColumns := len( aData[ 1 ] )
   nRows    := len( aData )

   TRY
      oApp := CreateObject( cServer )
   CATCH
      Return nil
   END

   oApp:Visible       := .f.
   oApp:DisplayAlerts := .f.
   oApp:Workbooks:Close()

   oWB := oApp:Workbooks:Open( cFileName )
   oAs := oWB:ActiveSheet()

   for j := 1 to nColumns
      cType := valtype( aData[ 1,j ] )

      oAs:columns( j ):NumberFormat( if( cType == 'C', '@', if( cType ==
'N', '???.??', ;
                                     if( cType == 'D', 'mm/dd/yyyy', '@' ) )
) )
   next

   // Columns be made visible properly
   for j := 1 to nColumns
      oAs:columns( j ):Autofit()
      oAs:Cells( 1,j ):font:bold := .t.
      oAs:Cells( 1,j ):font:color := RGB( 27,79,216 )
   next

   if !( lOpenExcel )
      oWB:Close( 'SaveChanges',.f. )
      oAS := nil
      oWB := nil
      oApp:Quit()
      oApp := nil

   else
      oApp:Visible := .t.

   endif

   Return nil
//----------------------------------------------------------------------//
Function Array2CSV( aArray, cCsvFile, aAttr )
   Local i, s
   Local nRows := len( aArray )
   Local nCols := len( aArray[ 1 ] )
   Local aTyp  := array( nCols )
   Local aCsv  := {}

   aeval( aArray[ 1 ], {|e,i| aTyp[ i ] := valtype( e ) } )

   for i := 1 TO nRows
      s := ''
      aeval( aArray[ i ], {|e, j| s += X2Csv( e, aTyp[ j ] ) + if( j ==
nCols, '', ',' ) } )
      aadd( aCsv, s )
   next

   s := ''
   aeval( aAttr, {|e_, i| s += e_[ 2 ]+',' } )
   s += CRLF
   aeval( aCsv, {|e| s += e + CRLF } )
   memowrit( cCsvFile, s )

   Return file( cCsvFile )
//----------------------------------------------------------------------//
Static Function X2Csv( x, cTyp )
   Local xVar := ''

   do case
   case cTyp == 'C'
      if at( '"', x ) > 0 .OR. at( ',', x ) > 0
         xVar := '"' + strtran( x, '"', '""' ) + '"'
      elseif IsDigit( left( x,1 ) )
         return '="'+ x +'"'
      else
         return x
      endif
   case cTyp == 'N'
      xVar := ltrim( str( x ) )
   case cTyp == 'D'
      xVar := dtoc( x )
   case cTyp == 'L'
      xVar := if( x, 'Yes','No' )
   endcase

   Return xVar
//----------------------------------------------------------------------//

If this code had been useful to you then please tell on this list.

Regards
Pritpal Bedi

-- 
View this message in context: 
http://www.nabble.com/GTWVG-%2B-MS-SDK-7.0a-%28MSVS-2010-Beta%29-errors-tp23895517p23896457.html
Sent from the Harbour - Dev mailing list archive at Nabble.com.

_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to