Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Excel Automation (https://www.delphipraxis.net/165062-excel-automation.html)

Cogito 13. Dez 2011 12:40

Excel Automation
 
Hallo zusammen,

ich müsste von Delphi aus Excel Spreadsheets auslesen, also nicht jeden Wert, sondern zu bestimmten Zellen springen usw...
Ich weiß das dieses Thema schon öfter behandelt wurde, aber nach Benutzung der Suchfunktion klicke ich bereits auf der 10.ten Seite rum und finde keine Einführung oder Grundlagen, wie ich Excel ansteuern kann. Was ich bräuchte wäre vielleicht eine Rumpfapplikation wo ich sehen kann, wie man auf Excel zugreift. Kennt einer so etwas?

Bernhard Geyer 13. Dez 2011 12:50

AW: Excel Automation
 
Wie wäre es mit einem Tutorial?

Cogito 13. Dez 2011 13:23

AW: Excel Automation
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1141146)
Wie wäre es mit einem Tutorial?

Hmm.., das scheint fehlerhaft zu sein.
Auf der 2. Seite beim Thema "Daten an Excel übergeben" muckt der Compiler bei folgender Anweisung...

Code:
ExcelWorksheet.ConnectTo([B]ExcelWorkbook[/B].Sheets.Item[1] as ExcelWorkSheet);
mit der Fehlermeldung ..."Operator ist auf diesen Operandentyp nicht anwendbar!" Ausserdem steht im Tutorial ExcelWorkbook1 (siehe Fettdruck), was ja wohl auch falsch ist.
Kann mir jemand weiterhelfen oder hat einer noch einen anderen Vorschlag ?

p80286 13. Dez 2011 14:23

AW: Excel Automation
 
Vielleicht hilft Dir das weiter:
(ist alles anderes als optimal aber lauffähig)
Delphi-Quellcode:
(* Liest Exceldatei *)
function LIESEXCEL(const datei:string;const sheet:integer;
                   var startzeile,endzeile,startspalte,endspalte:integer;
                   const fontinfo:boolean=false;
                   const colorinfo:boolean=false):tstringlist;
const
  DELIMMITERLINE='........';
var
  maxZeil,
  maxSpal : integer;
  ll     : tstringlist;
  i,j    : integer;
  excel  : variant;
  zelle  : ansistring; {!! shortstring=Begrenzung ; kann auch ansistring sein!}
begin
  ll:=tstringlist.Create;
  maxZeil:=0;
  maxSpal:=0;
  try
    excel:=createoleobject('EXCEL.APPLICATION');
  except
    showmessage('Excel kann nicht gestartet werden!');
    exit;
  end;
  excel.visible:=true; { visible nur für test-zwecke }
  excel.workbooks.Open(Filename:=datei);
  excel.activeworkbook.sheets[sheet].activate; { 1. Worksheet}
 
  {-- Excel zählt von 1..x }
  maxZeil:=excel.activesheet.usedrange.rows.count;
  maxSpal:=excel.activesheet.usedrange.columns.count;
  if StartZeile=0 then Startzeile:=1;
  if StartSpalte=0 then StartSpalte:=1;
  {---------------------}
  if endZeile>maxzeil then endZeile:=maxZeil;
  if endSpalte>maxspal then endSpalte:=maxSpal;
  for i:=startZeile to endZeile do begin
    for j:=startSpalte to endSpalte do begin
      zelle:=excel.activesheet.cells[i,j];  { Lese Wert }
      excel.activesheet.cells[i+1,j+1].select;
      if fontinfo then
        zelle:=zelle+'|'+excel.selection.font.name;
        if excel.activesheet.cells[i+1,j+1].font.Strikethrough=True then Zelle:=zelle+'(gestrichen)';
      if colorinfo then
        zelle:=zelle+'Farbe:'+inttostr(excel.activesheet.cells[i+1,j+1].font.colorindex);
      ll.Add(zelle);
    end;
    ll.add(DELIMITERLINE);
  end;
  excel.ActiveWorkbook.Close;
  excel.quit;
  result:=ll;
end;
Gruß
K-H

FrankJ28 13. Dez 2011 14:52

AW: Excel Automation
 
Hallo,
Zitat aus dem Tutorial (was eigentlich wirklich einfach und verständlich geschrieben ist)
Nicht vergessen: Wer keine Komponenten hat muss die Variablen deklarieren und erzeugen (ExcelWorkbook:TExcelWorkbook; ExcelWorkSheet:TExcelWorksheet).
Also: Entweder Komponente auf dein Form ziehen, oder halt selbst "createn"
Ciao
Frank

Cogito 13. Dez 2011 15:00

AW: Excel Automation
 
Zitat:

Zitat von FrankJ28 (Beitrag 1141193)
Hallo,
Zitat aus dem Tutorial (was eigentlich wirklich einfach und verständlich geschrieben ist)
Nicht vergessen: Wer keine Komponenten hat muss die Variablen deklarieren und erzeugen (ExcelWorkbook:TExcelWorkbook; ExcelWorkSheet:TExcelWorksheet).
Also: Entweder Komponente auf dein Form ziehen, oder halt selbst "createn"
Ciao
Frank

Natürlich habe ich die Komponenten auf die Form gezogen...

Cogito 13. Dez 2011 15:14

AW: Excel Automation
 
Zitat:

Zitat von p80286 (Beitrag 1141184)
Vielleicht hilft Dir das weiter:
(ist alles anderes als optimal aber lauffähig)
Delphi-Quellcode:
(* Liest Exceldatei *)
function LIESEXCEL(const datei:string;const sheet:integer;
                   var startzeile,endzeile,startspalte,endspalte:integer;
                   const fontinfo:boolean=false;
                   const colorinfo:boolean=false):tstringlist;
const
  DELIMMITERLINE='........';
var
  maxZeil,
  maxSpal : integer;
  ll     : tstringlist;
  i,j    : integer;
  excel  : variant;
  zelle  : ansistring; {!! shortstring=Begrenzung ; kann auch ansistring sein!}
begin
  ll:=tstringlist.Create;
  maxZeil:=0;
  maxSpal:=0;
  try
    excel:=createoleobject('EXCEL.APPLICATION');
  except
    showmessage('Excel kann nicht gestartet werden!');
    exit;
  end;
  excel.visible:=true; { visible nur für test-zwecke }
  excel.workbooks.Open(Filename:=datei);
  excel.activeworkbook.sheets[sheet].activate; { 1. Worksheet}
 
  {-- Excel zählt von 1..x }
  maxZeil:=excel.activesheet.usedrange.rows.count;
  maxSpal:=excel.activesheet.usedrange.columns.count;
  if StartZeile=0 then Startzeile:=1;
  if StartSpalte=0 then StartSpalte:=1;
  {---------------------}
  if endZeile>maxzeil then endZeile:=maxZeil;
  if endSpalte>maxspal then endSpalte:=maxSpal;
  for i:=startZeile to endZeile do begin
    for j:=startSpalte to endSpalte do begin
      zelle:=excel.activesheet.cells[i,j];  { Lese Wert }
      excel.activesheet.cells[i+1,j+1].select;
      if fontinfo then
        zelle:=zelle+'|'+excel.selection.font.name;
        if excel.activesheet.cells[i+1,j+1].font.Strikethrough=True then Zelle:=zelle+'(gestrichen)';
      if colorinfo then
        zelle:=zelle+'Farbe:'+inttostr(excel.activesheet.cells[i+1,j+1].font.colorindex);
      ll.Add(zelle);
    end;
    ll.add(DELIMITERLINE);
  end;
  excel.ActiveWorkbook.Close;
  excel.quit;
  result:=ll;
end;
Gruß
K-H

Das sieht schon deutlich besser aus.
Eine kleine Sache wäre da noch:
Bei deinem Beispiel fragt Excel am Schluss immer ob die Datei gespeichert werden soll. Kann ich diese Meldung irgendwie unterdrücken?

FrankJ28 13. Dez 2011 15:27

AW: Excel Automation
 
Jo, selbst speichern.

Excel.ActiveWorkbook.SaveAs(Dateiname);

oder
Excel.ActiveWorkbook.Save;

wenn der alte Name beibehalten bleinen soll.
Ciao
Frank

Cogito 13. Dez 2011 15:54

AW: Excel Automation
 
Das ist aber eigentlich nicht so fein... falls die Excel Sheets beispielsweise in einem Verzeichnis mit ungenügenden Schreibrechten liegen, kracht's jedesmal. Gibt's denn keine Möglichkeit die Anzeige des Dialogs zu unterdrücken ? Ich lese aus den Sheets ja nur aus.

Lemmy 13. Dez 2011 16:06

AW: Excel Automation
 
Hi,

Zitat:

Zitat von Cogito (Beitrag 1141165)
mit der Fehlermeldung ..."Operator ist auf diesen Operandentyp nicht anwendbar!" Ausserdem steht im Tutorial ExcelWorkbook1 (siehe Fettdruck), was ja wohl auch falsch ist.
Kann mir jemand weiterhelfen oder hat einer noch einen anderen Vorschlag ?

warum falsch? Was soll dann da stehen? Das Tutorial habe ich mit MSOffice 2000 geschrieben - keinen PLan ob das aktuell auch mit der 2007er oder 2010er läuft - habe ich leider nicht. Wenn Du die Komponenten hast, dann sollte es ein leichtes sein, den Fehler zu finden - habe ich nichts gegen einen Hinweis, dann würde ich das Tutorial aktualisieren...

Grüße

Cogito 13. Dez 2011 16:17

AW: Excel Automation
 
Zitat:

Zitat von Lemmy (Beitrag 1141216)
Hi,

Zitat:

Zitat von Cogito (Beitrag 1141165)
mit der Fehlermeldung ..."Operator ist auf diesen Operandentyp nicht anwendbar!" Ausserdem steht im Tutorial ExcelWorkbook1 (siehe Fettdruck), was ja wohl auch falsch ist.
Kann mir jemand weiterhelfen oder hat einer noch einen anderen Vorschlag ?

warum falsch? Was soll dann da stehen? Das Tutorial habe ich mit MSOffice 2000 geschrieben - keinen PLan ob das aktuell auch mit der 2007er oder 2010er läuft - habe ich leider nicht. Wenn Du die Komponenten hast, dann sollte es ein leichtes sein, den Fehler zu finden - habe ich nichts gegen einen Hinweis, dann würde ich das Tutorial aktualisieren...

Grüße

Ich habe ja oben die fehlerhafte Zeile und die Fehlermeldung aufgelistet. Ich benutze Delphi 2010 und auf meinem Rechner ist Office 2010 installiert.

p80286 13. Dez 2011 16:18

AW: Excel Automation
 
Zitat:

Zitat von Cogito (Beitrag 1141213)
Das ist aber eigentlich nicht so fein... falls die Excel Sheets beispielsweise in einem Verzeichnis mit ungenügenden Schreibrechten liegen, kracht's jedesmal. Gibt's denn keine Möglichkeit die Anzeige des Dialogs zu unterdrücken ? Ich lese aus den Sheets ja nur aus.

Sowohl Word als auch Excel haben eine sehr eigene Auffassung von "Änderungen" darum quitiere ich beide immer mit "nicht speichern" wenn es keine Datenänderung gibt.
Ich habe leider kein Excel zur Hand, aber es müßte einen Parameter "NoSave" oder so ähnlich geben. Schau doch mal in die VBA-Hilfe, da solltest Du eigentlich alles notwendige finden.

Gruß
K-H

Edith:
@Lemmy
Es sieht wirklich nach einem Tippfehler aus:
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var sValue, filename: String;
begin
  filename:=ExtractFilePath(ParamStr(0))+'Mappe1.xls';
  ExcelWorkbook.ConnectTo(ExcelApplication.Workbooks.Open(filename,
    emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam,
    emptyParam, emptyParam, emptyParam, emptyParam, emptyParam,
    emptyParam, flcid));
  ExcelWorksheet.ConnectTo(ExcelWorkbook1.Sheets.Item[1] as
    ExcelWorkSheet);
  sValue:=ExcelWorksheet.Range['B1','B1'].Value;
  MessageDlg(sValue, mtInformation, [mbOK], 0);
end;
Edith2:
Hier kann man sich den richtigen Paramer raussuchen:
http://www.ozgrid.com/VBA/prevent-save-prompt.htm

FrankJ28 13. Dez 2011 16:32

AW: Excel Automation
 
Hallo,
saveas in einem temporären Verzeichnis (User, sollte da ja Schreibrechte haben) und dann die Datei löschen.
Sobald das Sheet mehr als nur ein einfacher Datensammler ist (eingebettete Funktionen etc.), ist immer gleich eine Änderung vorhanden.
Ciao
Frank

Cogito 13. Dez 2011 16:41

AW: Excel Automation
 
Zitat:

Zitat von p80286 (Beitrag 1141219)
Zitat:

Zitat von Cogito (Beitrag 1141213)
Das ist aber eigentlich nicht so fein... falls die Excel Sheets beispielsweise in einem Verzeichnis mit ungenügenden Schreibrechten liegen, kracht's jedesmal. Gibt's denn keine Möglichkeit die Anzeige des Dialogs zu unterdrücken ? Ich lese aus den Sheets ja nur aus.

Sowohl Word als auch Excel haben eine sehr eigene Auffassung von "Änderungen" darum quitiere ich beide immer mit "nicht speichern" wenn es keine Datenänderung gibt.
Ich habe leider kein Excel zur Hand, aber es müßte einen Parameter "NoSave" oder so ähnlich geben. Schau doch mal in die VBA-Hilfe, da solltest Du eigentlich alles notwendige finden.

Ja stimmt, man braucht lediglich Close(0) aufzurufen und die Zwischenfrage entfällt.
Vielen Dank !

ASM 13. Dez 2011 17:29

AW: Excel Automation
 
Zitat:

Zitat von p80286 (Beitrag 1141219)
Ich habe leider kein Excel zur Hand, aber es müßte einen Parameter "NoSave" oder so ähnlich geben.

Korrekt heißen die dafür benötigten, als OleVariant-Parameter zu übergebenden Konstanten:
Code:
Const
  wdDoNotSaveChanges = 0;
  wdSaveChanges = -1;
  wdPromptToSaveChanges = -2;
Sehr gut geht es aber auch so (MSExel ist die als 'Excel.Application' eröffnete OleVariant):
Code:
procedure CloseExcel(SaveChanges: Boolean=true);
begin
  if VarIsEmpty(MSExcel) = false then
  begin
    // speichert, wenn SaveChanges = TRUE;
    // speichert nicht (ohne Rückfrage), wenn SaveChanges = FALSE
    MSExcel.DisplayAlerts:= SaveChanges;
    MSExcel.quit;
    MSExcel:= Unassigned;
  end;

Chemiker 14. Dez 2011 13:54

AW: Excel Automation
 
Hallo,

Delphi-Quellcode:
if VarIsEmpty(MSExcel) = false then
nicht auf TRUE oder FALSE prüfen, dass kann zu Probleme führen.
besser:
Delphi-Quellcode:
if not (VarIsEmpty(MSExcel) then

DisplayAlerts wird auf TRUE oder FALSE gestellt, mit SaveChanges hat das nichts zu tun.

Excel schließen ohne nachfragen:
Delphi-Quellcode:
excel.ActiveWorkBook.Saved:= TRUE;
excel.Workbooks.Close;
excel.Quit;
excel:= Unassigned;
Bis bald Chemiker

Bernhard Geyer 14. Dez 2011 14:00

AW: Excel Automation
 
Zitat:

Zitat von Chemiker (Beitrag 1141345)
Hallo,

Delphi-Quellcode:
if VarIsEmpty(MSExcel) = false then
nicht auf TRUE oder FALSE prüfen, dass kann zu Probleme führen.

Kannst du ein beispiel liefern wie man dieses Problem in Delphi herstellen kann.
In C/C++ ist klar. Da wird ja in jeder Bibliothek mindestens 10* TRUE und FALSE neu wenn du pech hast mit FALSE=0; TRUE=1 neu definiert.

Zitat:

Zitat von Chemiker (Beitrag 1141345)
Excel schließen ohne nachfragen:
Delphi-Quellcode:
excel.ActiveWorkBook.Saved:= TRUE;
excel.Workbooks.Close;
excel.Quit;
excel:= Unassigned;
Bis bald Chemiker

wenn man mit Variants arbeitet kann man ein Exceldatei mittels
Delphi-Quellcode:
FWorkBook.Close(SaveChanges:=False);
schließen und die Rückfrage vermeiden.

p80286 14. Dez 2011 22:08

AW: Excel Automation
 
Hallo Bernhard,

mach doch mal

Delphi-Quellcode:
if boolean(4) then showmessage('4 ist true');
if boolean(4)=true then showmessage(inttostr(integer(true)) ist gleich 4');
Gruß
K-H

Chemiker 15. Dez 2011 09:36

AW: Excel Automation
 
Hallo,

Zitat:

Kannst du ein beispiel liefern wie man dieses Problem in Delphi herstellen kann.
In C/C++ ist klar. Da wird ja in jeder Bibliothek mindestens 10* TRUE und FALSE neu wenn du pech hast mit FALSE=0; TRUE=1 neu definiert.
http://www.delphi-treff.de/tutorials...faengerfehler/

Bis bald Chemiker

Bernhard Geyer 15. Dez 2011 09:40

AW: Excel Automation
 
Zitat:

Zitat von p80286 (Beitrag 1141455)
Hallo Bernhard,

mach doch mal

Delphi-Quellcode:
if boolean(4) then showmessage('4 ist true');
if boolean(4)=true then showmessage(inttostr(integer(true)) ist gleich 4');
Gruß
K-H

Autsch. An diese harten Casts auf ungültige Enumwerte hatte ich gar nicht mehr gedacht.
Aber wer macht auch solche fehleranfälligen Konstrukte. :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz