Home | Chi sono | Contattami
 

Progr. lineare

Delphi
 
Componenti
  Database
 
Miei articoli

Windows

Miei articoli 

 

Esportare una DBGrid in Excel senza OLE


In questo articolo viene presentata una procedura per esportare il contenuto di un controllo TDBGrid in un foglio Excel senza utilizzare la tecnologia OLE; l'obiettivo viene raggiunto tramite ADO (ADOX per essere più precisi). Il tutto nacque tempo fà (doveva essere marzo 2002 se non ricordo male) ed il contesto di lavoro faceva riferimento ad OpenOffice; devo essere sincero, non ho più esaminato OpenOffice da quella volta (ehh si... ne è passato di tempo) ma in quei tempi remoti il risultato dell'esportazione passando per OLE non piaceva proprio ad OpenOffice. Ed allora fui costretto a trovare una soluzione che fosse più gradita a Mr. OpenOffice. Bene, abbiamo già detto parecchie cose inutili, è ora di passare ai fatti.

1. ADO (basta la parola)

Come prima cosa ho scoperto che con ADO è possibile trattare un file Excel proprio come un database: il file Excel è il database e tutti i fogli all’ interno sono le tabelle. Poi, dato che ero in ballo, volevo anche una soluzione compatibile con tutti i dataset e poi volevo esportare solo i dati presenti nella DBGrid e non tutto il dataset; sono così pervenuto alla seguente soluzione che uso ormai quotidianamente.

1.1 Cominciamo

Prima di tutto bisogna importare la type library di ADOX (si ADOX e non ADO in quanto non solo dobbiamo scrivere i dati ma prima di tutto dobbiamo creare il file Excel con il relative foglio e quindi ci viene in aiuto ADOX che fornisce gli strumenti per la creazione di database, tabelle, campi, etc…) che verrà usata per creare il file Excel e la sua struttura interna.

  1. Project->Import Type Library
  2. Seleziona "Microsoft ADO Ext. for DDL and Security"
  3. "Generate component wrapper" in basso
  4. Rinomina i nomi delle classi (TTable, TColumn, TIndex, TKey, TGroup, TUser, TCatalog) in (TXTable, TXColumn, TXIndex, TXKey, TXGroup, TXUser, TXCatalog) per evitare conflitti con il componente TTable già presente
  5. Seleziona il nome della cartella in cui salvare la Unit di import e premi "Create Unit"

Verrà creato un file di nome ADOX_TLB. A questo punto non resta che includere ADOX_TLB nella direttiva "uses" all’ interno del file in cui vuoi usare le funzionalità offerte da ADOX.

Questo è tutto. Non resta altro da fare che analizzare l’ implementazione
 

2. Implementazione

unit DBGridExportToExcel; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls, DB, IniFiles, Buttons, dbgrids, ADOX_TLB, ADODB; type TScrollEvents = class BeforeScroll_Event: TDataSetNotifyEvent; AfterScroll_Event: TDataSetNotifyEvent; AutoCalcFields_Property: Boolean; end; procedure DisableDependencies(DataSet: TDataSet; var ScrollEvents: TScrollEvents); procedure EnableDependencies(DataSet: TDataSet; ScrollEvents: TScrollEvents); procedure DBGridToExcelADO(DBGrid: TDBGrid; FileName: string; SheetName: string); implementation //Di seguito ci sono 2 procedure di supporto che ho creato per velocizzare //l’ esportazione in caso di notevole quantità di record. //Viene eseguita una chiamata alla procedura “DisableControls” (che, per chi non lo sapesse, //disabilita l’ aggiornamento dei controlli collegati ad un dataset, ad esempio griglie, //edit, etc…, rendendo molto più rapido lo scanning), poi disabilito personalmente //gli eventi “BeforeScroll” e “AfterScroll” e la proprietà “AutoCalcFields” procedure DisableDependencies(DataSet: TDataSet; var ScrollEvents: TScrollEvents); begin with DataSet do begin DisableControls; ScrollEvents := TScrollEvents.Create(); with ScrollEvents do begin BeforeScroll_Event := BeforeScroll; AfterScroll_Event := AfterScroll; AutoCalcFields_Property := AutoCalcFields; BeforeScroll := nil; AfterScroll := nil; AutoCalcFields := False; end; end; end; //Riporto tutto alla normalità procedure EnableDependencies(DataSet: TDataSet; ScrollEvents: TScrollEvents); begin with DataSet do begin EnableControls; with ScrollEvents do begin BeforeScroll := BeforeScroll_Event; AfterScroll := AfterScroll_Event; AutoCalcFields := AutoCalcFields_Property; end; end; end; //E questa finalmente è la procedura chef a il duro lavoro procedure DBGridToExcelADO(DBGrid: TDBGrid; FileName: string; SheetName: string); var cat: _Catalog; tbl: _Table; col: _Column; i: integer; ADOConnection: TADOConnection; ADOQuery: TADOQuery; ScrollEvents: TScrollEvents; SavePlace: TBookmark; begin // //Creazione del file Excel (database) cat := CoCatalog.Create; cat._Set_ActiveConnection('Provider=Microsoft.Jet.OLEDB.4.0; Data Source=' + FileName + ';Extended Properties=Excel 8.0'); //Creazione del foglio di lavoro (tabella) tbl := CoTable.Create; tbl.Set_Name(SheetName); //Creazione colonne (campi) DBGrid.DataSource.DataSet.First; with DBGrid.Columns do begin for i := 0 to Count - 1 do if Items[i].Visible then begin col := nil; col := CoColumn.Create; with col do begin Set_Name(Items[i].Title.Caption); Set_Type_(adVarWChar); end; //aggiungi una colonna alla tabella tbl.Columns.Append(col, adVarWChar, 20); end; end; //aggiungi la tabella al database cat.Tables.Append(tbl); col := nil; tbl := nil; cat := nil; //esportazione ADOConnection := TADOConnection.Create(nil); ADOConnection.LoginPrompt := False; ADOConnection.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0; Data Source=' + FileName + ';Extended Properties=Excel 8.0'; ADOQuery := TADOQuery.Create(nil); ADOQuery.Connection := ADOConnection; ADOQuery.SQL.Text := 'Select * from [' + SheetName + '$]'; ADOQuery.Open; DisableDependencies(DBGrid.DataSource.DataSet, ScrollEvents); SavePlace := DBGrid.DataSource.DataSet.GetBookmark; try with DBGrid.DataSource.DataSet do begin First; while not Eof do begin ADOQuery.Append; with DBGrid.Columns do begin ADOQuery.Edit; for i := 0 to Count - 1 do if Items[i].Visible then begin ADOQuery.FieldByName(Items[i].Title.Caption).AsString := FieldByName(Items[i].FieldName).AsString; end; ADOQuery.Post; end; Next; end; end; finally DBGrid.DataSource.DataSet.GotoBookmark(SavePlace); DBGrid.DataSource.DataSet.FreeBookmark(SavePlace); EnableDependencies(DBGrid.DataSource.DataSet, ScrollEvents); ADOQuery.Close; ADOConnection.Close; ADOQuery.Free; ADOConnection.Free; end; end; end.

 

 

 

 

 

 



 

 

 
 
Your Ad Here