phpWeaver.com
 
     
Delphi/Kylix artikel
 
 
Home     
Kylix     
Links en boeken     
Errata     
Nieuws     
 
 
OLE Automation: van Delphi naar Excel

 

Vanuit Delphi een MS Excel spreadsheet openen en vullen met gegevens is een beetje een ander verhaal dan hetzelfde doen, maar dan met MS Word. En hoewel er verschillen bestaan, is het basisprincipe toch weer hetzelfde.

 

Wat essentieel anders is in Excel is de structuur van een Excel bestand. Bestaat een Word bestand gewoon uit één uitgerekte ‘lap A4 papier’ waar je met gemak en bijna ongezien alles maar op kunt neer dumpen; in Excel moet je ‘prikken’.

In de documentatie die je in de online help van Excel vindt kun je lezen dat een spreadsheet applicatie drie hoofdobjecten heeft die je met een CreateOleObject van buiten Excel kunt benaderen:

CreateOleObject(‘Excel.Application’);
CreateOleObject(‘Excel.Sheet’);
CreateOleObject(‘Excel.Chart’);

Er is daarbij altijd sprake van een hiërarchie, met aan de top iets wat genoemd wordt Application. Met daaronder een Workbooks object. Met daaronder weer Worksheets en Charts.
Met mijn vertaling erbij:

1) Application (MS Excel)
            A) Workbooks (‘map’)
                        I) Worksheets (‘spreadsheet bladen’)
                        II) Charts (‘grafiek bladen’)                      

Het punt is dat u deze hiërarchie bij het exporteren van gegeven naar Excel in de gaten moet houden, omdat dit ook de volgorde is waarin u de objecten benaderd. Weliswaar een beetje een glibberige structuur, maar soi.

Workbooks objecten ‘peurt’ u uit het Application object. Worksheets en Charts objecten ontleend u weer uit het Workbooks object. (Zo is het leven).

Dit is ook precies de manier waarop ik de code in het volgende voorbeeld heb opgebouwd. De broncode ervan: FictionNet8 vindt u hier (FictionNet8.zip) en is een complete vervanging van de broncode FictionNet8 uit Hoofdstuk 11 van Handboek Delphi/Kylix.
Maar omdat het een knip-en-plak 'dingetje' is, kunt u natuurlijk ook gewoon onderstaande broncode in een onClick Event in de bestaande code neerzetten.

Voortbouwend op het ‘Export naar Word” voorbeeld heb ik in de Catalogus_U unit een extra knop neergezet met als titel ‘Naar Excel’:

 

Catalogus_U met de knop Naar Excel

 

De onClick Event code van deze knop ziet er als volgt uit (schrik niet, ’t meeste is commentaar):

 


procedure TCatalogus.BtNaarExcelClick(Sender: TObject);
const
{ XlSheetType }
  xlChart = -4109;
  xlDialogSheet = -4116;
  xlExcel4IntlMacroSheet = 4;
  xlExcel4MacroSheet = 3;
  xlWorksheet = -4167;

{ XlWBATemplate }
  xlWBATChart = -4109;
  xlWBATExcel4IntlMacroSheet = 4;
  xlWBATExcel4MacroSheet = 3;
  xlWBATWorksheet = -4167;
var
  XLApp: Variant;
  i, j: Integer;
  Sheets: Variant;
begin
  XLApp := CreateOleObject('Excel.Application');
  XLApp.Visible := True;

  {Let op: bij OLE worden de verschillende onderdelen van een Excel document
  (Workbook (map), Worksheet (spreadsheetblad) en Chart (grafiekblad)
  altijd geopend in de volgorde van je code!
  Zet je de regel   XLApp.Workbooks.Add(xlWBatChart);
  boven de regel    XLApp.Workbooks.Add(xlWBatWorkSheet);
  dan wordt Excel dus eerst geopend met een grafiekwerkblad op je scherm
  en niet met een spreadsheetblad.
  }

  //1. Als je alleen deze regel laat staan,
  //dan wordt Excel geopend met een map met 3 lege Worksheets (spreadsheet bladen)
  //In Excel is dat de standaard als je 'm opstart.
  //XLApp.Workbooks.Add;

  //2. Voeg ruimte toe voor één Worksheet (spreadsheet blad)
  //en geeft die meteen een naam
  XLApp.Workbooks.Add(xlWBatWorkSheet);
  XLApp.Workbooks[1].WorkSheets[1].Name := 'Catalogus Games';

  //3. Voeg ruimte toe voor één Chart (grafiek-werkblad).
  //XLApp.Workbooks.Add(xlWBatChart);

  //4. Hier wordt een tweede Workbook (map) geopend
  //XLApp.Workbooks[2].Sheets.Add(,,1,xlWorkSheet);

  //5. ... en hier een tweede grafiekblad
  //XLApp.Workbooks[2].Sheets.Add(,,1,xlChart);

 

  {En dan nu de data-invoer in een spreadsheet.
  Zorg eerst dat de regels onder 1., 3., 4. en 5. hierboven zijn uitgecommentarieerd,
  zodat je Excel opstart met maar één leeg spreadsheet blad!}

  Sheets := XLApp.Workbooks[1].WorkSheets['Catalogus Games'];
  //Voer in kolom A tien integerwaarden in en bereken het totaaltje in cel A11
  for i := 1 to 10 do
    Sheets.Cells[i,1] := i;

  Sheets.Cells[i,1] := '=Sum(A1:A10';

 

  //Voer nu in kolom B alle titels in van de games uit de database
  ADOTableGames.First;
  i:=1;
  while not ADOTableGames.EOF do
  begin
    Sheets.Cells[i,2] := ADOTableGames.FieldByName('Titel').asstring;
    i:=i+1;
    ADOTableGames.Next;
  end;

  {Hoe je de overige databasegegevens naar Excel kunt overhalen
  zal nu wel duidelijk zijn.
  Veel plezier!}
end;

 


 

Bespreking van de code

Zoals je ziet start de code ongeveer, zoals die ook in het MS Word voorbeeld begon:

  XLApp := CreateOleObject('Excel.Application');
  XLApp.Visible := True;

In tegenstelling tot wat je misschien denkt maakt daarbij maakt de regel

  XLApp.Visible := True;

de Excel applicatie NIET zichtbaar.

Excel wordt pas zichtbaar als je een Workbook (map) aanmaakt:

XLApp.Workbooks.Add;

Het volgende riedeltje code is dus genoeg om vanuit Delphi Excel op te starten met (standaard) 3 lege spreadsheet bladen:

  XLApp := CreateOleObject('Excel.Application');
  XLApp.Visible := True;
  XLApp.Workbooks.Add;

 

Om wat te experimenteren met het openen van Workbooks (mappen), Worksheets (spreadsheet bladen) en Charts (grafiek bladen) heb ik in de code onder de nummers 1., 2., 3., 4. en 5. de coderegels uitgecommentarieerd. Als u de // weghaalt kunt u uitproberen wat het effect van verschillende combinaties oplevert.

Zover over de structuur van Excel.
Nu de data, want daar ging het om.

U wilt data vanuit Delphi (of vanuit een database, via Delphi) laten instromen in een Excel spreadsheet.

Dit wordt in het tweede gedeelte van de code afgehandeld.

Eérst door een paar integer waarden in kolom A van een spreadsheet te laten instromen (en en passant daarvan even het totaaltje te laten berekenen).
Dan door in kolom B alle Game-titels uit de FictionNet database te laten instromen.

Als u de code leest, zal het duidelijk zijn:
Met Sheets.Cells[i,1] bereikt u een individuele cel in de spreadsheet. Het werkt precies zoals u verwacht, behalve dat in Excel de Rij éérst komt en de Kolom pas daarna.

En hoe u de overige databasegegevens naar Excel kunt overhalen zal nu wel duidelijk zijn. Vergelijk met wat u naar Word gedaan hebt en u bent er.

Veel plezier.

 

 pw

 


PS: Voor nog veel meer informatie over het exporteren van gegevens naar Office pakketten kunt u terecht op de site van:

delphi.about.com,
met op dezelfde site een specifiek artikel gericht op export uit databases
en op www.delphipages.com

 
Dringende vragen? Suggesties & reacties? Email.
 
         
Untitled Document
   
© cfwebforge.com