Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Excel-Funktion im Hintergrund ablaufen lassen (https://www.delphipraxis.net/144584-excel-funktion-im-hintergrund-ablaufen-lassen.html)

Delphi-Narr 11. Dez 2009 13:13


Excel-Funktion im Hintergrund ablaufen lassen
 
Hallo,
ich habe ein Programm geschrieben, welches eigentlich aus nur 4 Elementen besteht:
1.: Datumsauswahlfeld
2.: Auswahlfeld mit Währungen
3.: Eingabefeld für Betrag
4.: Button "OK"

Es rechnet den Betrag, den man in das Eingabefeld (3) eingegeben hat, von der Währung aus (2) in Euro um und gibt ihn aus.
Das Datum, welches man ausgewählt hat, wird in die Berechnung mit einbezogen, da der zum angegebenen Datum aktuelle Kurs benutzt wird.
Klappt bisher wunderbar...
Jetzt möchte ich aber gerne noch eine "Updatefunktion" haben. Vom Prinzip her ist es nicht schwer: Ich lade die Datei runter und ersetze die alte.
Nur arbeitet mein Programm mit .txt Dateien, nicht mir XML. Diese XML Dateien müssen vor der Verwendung erst noch mit Excel in eine Tabelle umgewandelt werden, dann müssen die ersten beiden Spalten komplett gelöscht werden und das ganze muss als Textdatei gespeichert werden, die durch Tabs getrennt ist (statt neuer Spalten).

Ich würd das ganze ja immer von Hand machen, doch da dieses Programm auch von anderen benutzt werden soll, die das nicht unbedingt können, bräuchte ich da Hilfe. Kann man diese Befehle irgendwie an Excel senden oder das in Delphi selbst machen? Die weiteren Formatierungen bekommen ich dann selber hin...

Hoffe auf eure Hilfe!
Liebe Grüße!

mkinzler 11. Dez 2009 13:17

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Delphi-Referenz durchsuchenOLE-Automation
Warum stellst du das Programm nicht einfach auf XML um?

p80286 11. Dez 2009 13:45

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
In der XML-Datei liegen die Daten doch in ungefähr folgender Form vor:
XML-Code:
<Satz id=xxx1>
...
<datum>20090101</datum>
<kurs>2.34</kurs>
...
</Satz>
<Satz id=xxx2>
...
<datum>20090102</datum>
<kurs>2.30</kurs>
...
</satz>
Da ist es doch beinahe weniger aufwendig hier Daten auszulesen als in einer CSV-Datei?

Warum da den Umweg über Excel?
Und es soll vorkommen, das die verschiedenen Excel-Versionen zueinander leicht inkompatibel sind, da ist Ärger durch die Hintertür eigentlich vorprogrammiert.

Gruß
K-H

sx2008 11. Dez 2009 13:46

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Zitat:

Zitat von Delphi-Narr
Jetzt möchte ich aber gerne noch eine "Updatefunktion" haben.

Hört sich so an, als ob du die Umrechnungsfaktoren für die Währungen herunterladen möchtest.
Du brauchst dazu übrigens keinen eigenen Server, denn die Europäische Zentralbank bietet die täglichen Wechselkurse als download an.
http://www.ecb.int/stats/exchange/eu.../index.en.html
Excel ist ebenfalls überflüssig, denn die XML-Dateien lassen sich doch prima parsen.

Delphi-Narr 11. Dez 2009 13:51

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Also ich hab die Dateien schon von einer Bank (weiß nicht mehr genau welche).
Ich mach das auch gerne mit XML, doch wie lade ich eine XML-Datei in Delphi rein?

Edit:

Das mit den Makros interessiert mich jetzt schon... Also hier ist er:

Sub Makro1()
'
' Makro1 Makro
' Makro
'

'
ChDir "C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Dat afiles"
Workbooks.OpenXML Filename:= _
"C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Dat afiles\eurofxref-hist.xml" _
, LoadOption:=xlXmlLoadImportToList
Columns("A:B").Select
Selection.Delete Shift:=xlToLeft
ActiveWorkbook.SaveAs Filename:= _
"C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Dat afiles\Mappe2.txt" _
, FileFormat:=xlText, CreateBackup:=False
End Sub

Wie muss ich den jetzt in Delphi einbinden? Also ich habe bisher:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Excel : Variant;
begin
  Excel := CreateOleObject('Excel.Application');
Ist jetzt ja nicht so ein Monsterquellcode, der würde doch bestimmt auch bei Excel 2003 funktionieren...

Delphi-Narr 11. Dez 2009 16:32

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Keiner weiß was?
Hier ist meine Variante, klappt nur leider nicht...

Delphi-Quellcode:
 
  excel.Application.SheetsInNewWorkBook := 1;
  Excel.Workbooks.Add;
  //Der Befehl hier existiert in Excel angeblich nicht:
    Excel.ChDir('C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Datafiles');
    Excel.Workbooks.OpenXML;
    Excel.Filename:='C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Datafiles\eurofxref-hist.xml';
    Excel.LoadOption:=Excel.xlXmlLoadImportToList;
    Excel.Columns('A:B').Select;
    Excel.Selection.Delete;
    Excel.Shift:=Excel.xlToLeft;
    Excel.ActiveWorkbook.SaveAs;
    Excel.Filename:='C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Datafiles\Newdata.txt';
    Excel.FileFormat:=Excel.xlText;
    Excel.CreateBackup:=False;

Komplett also so:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Excel : Variant;
begin
  Excel := CreateOleObject('Excel.Application');
  excel.Application.SheetsInNewWorkBook := 1;
  Excel.Workbooks.Add;
    Excel.ChDir('C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Datafiles');
    Excel.Workbooks.OpenXML;
    Excel.Filename:='C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Datafiles\eurofxref-hist.xml';
        Excel.LoadOption:=Excel.xlXmlLoadImportToList;
    Excel.Columns('A:B').Select;
    Excel.Selection.Delete;
    Excel.Shift:=Excel.xlToLeft;
    Excel.ActiveWorkbook.SaveAs;
    Excel.Filename:='C:\Program Files\Borland\Delphi5\Projects\Währungsrechner\Datafiles\Newdata.txt';
    Excel.FileFormat:=Excel.xlText;
    Excel.CreateBackup:=False;
end;
Wenn ich das CHDir weglasse, da es ja eigentlich nicht gebraucht wird, da es nur im Dialog ausgewählt wurde, Wird die Zeile darauf markiert und es kommt die Meldung: Ungültige Parameteranzahl

Hab das noch nie gemacht, wenn mir also einer sagen kann, wie man das macht, dann kann ich das sicher auf weitere Makros übertragen...

[edit=mkinzler]Code-Tag durch Delphi-Tag ersetzt Mfg, mkinzler[/edit]

p80286 11. Dez 2009 16:34

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Ich hab es mal eben zusammengeschustert:
Delphi-Quellcode:
  excel.visible:=true; { visible nur für test-zwecke }
  excel.workbooks.Open(Filename:='c:\temp\testdatei0.xml'); //,LoadOption:=xlXmlLoadImportToList);
  excel.activeworkbook.sheets[1].activate; { 1. Worksheet -- wahrscheinlich nicht notwendig}
  excel.activeworkbook.sheets[1].columns[1].delete;
  excel.activeworkbook.sheets[1].columns[1].delete;
  excel.ActiveWorkbook.SaveAs(Filename:='c:\temp\testdatei_stripped.txt', FileFormat:=$FFFFEFC2, CreateBackup:=False);
  excel.ActiveWorkbook.Close;
  excel.quit;
Aber leider habe ich keine Möglichkeit gefunden die Nachfrage beim Speichern zu umgehen.

Aber wenn Du schon kein originäres XML lesen willst, und Du schon Excel offen hast, warum dann nicht gleich im "Original" lesen?

Delphi-Quellcode:
{---- Auslesen von Excel sheets mit StartSpalte/StartZeile bis Endspalte/EndZeile ----}
  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 }
      ll.Add(zelle);      { Wert ausgeben }
Bei einigen Sheets könnten Excel und der User unterschiedlicher Meinung sein welche Zellen genutzt werden!

Gruß
K-H

Nachtrag:
xlToLeft u.ä. sind Konstanten die delphi nicht kennt. Die muß man sich selbst heraus suchen.
z.B. FileFormat:=$FFFFEFC2 = FileFormat:=xlText

2.Nachtrag:
Delphi-Quellcode:
ll.Add(zelle);      { Wert ausgeben }
Da ist ll ein Tlist oder TSringlist oder irgend so etwas....

Delphi-Narr 11. Dez 2009 16:57

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Erstmal danke für die Mühe! Also Excel geht auf, wird sichtbar und lädt die Liste. Da die LoadOption nicht erkannt wird, musste ich die zu löschenden Spalten etwas ändern, da sie anders geladen wurden. Soweit aber kein Problem.
Jetzt soll Excel nur noch wieder geschlossen werden. Die Arbeitsmappe selber schließt sich, das Programm jedoch nicht.

Ansonsten ist es perfekt, danke!

Zu 2:
Ich hab Excel nicht offen und es soll auch nicht geöffnet sein. Ich will es praktisch nur zum umkodieren benutzen - fast ohne dass der Nutzer es mitkriegt. Die Voraussetzung für das Update ist natürlich Excel...
Das haben die dafür vorgesehenen Nutzer aber.

p80286 11. Dez 2009 17:10

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Zitat:

Zitat von Delphi-Narr
Zu 2:
Ich hab Excel nicht offen und es soll auch nicht geöffnet sein. Ich will es praktisch nur zum umkodieren benutzen - fast ohne dass der Nutzer es mitkriegt. Die Voraussetzung für das Update ist natürlich Excel...
Das haben die dafür vorgesehenen Nutzer aber.

"offen" muß ja nicht sein, das visible kann man ja rausschmeißen.
Was ich meinte, wenn Du Excel bemühst um die beiden ersten Spalten zu löschen, dann kannst Du auch gleich die Spalte 3 und 4 und .... auslesen. Und da keine Datei gespeichert wird, bekommt der Benutzer noch weniger mit.

Gruß
K-H

(und ich bin immer noch der Meinung XML direkt zu lesen ist einfacher..)

Delphi-Narr 11. Dez 2009 18:19

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Ich versteh schon, was du meinst, nur brauch es immer, bis Excel geöffnet ist und bis ein Befehl ausgeführt ist - dann würde erstens eine längere Wartezeit entstehen und wenn der User gleichzeitig mit Excel arbeiten will, dann sieht er auf einmal eine für ihn völlig sinnlose Tabelle.

Es gibt noch ein Problem:

Bevor die Datei codiert werden kann, muss ich die ja erst runterladen.

Also:
uses URLMon;


URLDownloadToFile(nil, PChar('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml'),PChar('C:\Programme\Währungsrechner\Dat afiles\eurofxref-hist.xml'),0,nil);

Die Datei ist vorhanden und wird täglich aktualisiert.
Ich hab das ganze in einen Try - Except - Block gesetzt, angeblich wurde die Datei runtergeladen...
Nur ist später keine Datei vorhanden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:43 Uhr.
Seite 1 von 3  1 23      

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