Delphi-PRAXiS
Seite 2 von 3     12 3      

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 20:31

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Ok, das Ganze liegt an Schreibrechten... Zu anderen Verzeichnissen kann ich laden. Kann ich das irgendwie abstellen?

sx2008 11. Dez 2009 20:36

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Liste der Anhänge anzeigen (Anzahl: 2)
"Delphi-Narr", du machst deinem Namen alle Ehre!
Mein Rat war doch kein Excel zu benützen.
Die Anwendung im Anhang zeigt wie einfach man die Umrechnungskurse ohne Excel einlesen kann.

Delphi-Narr 11. Dez 2009 21:34

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Das "Narr" bezieht sich eigentlich nicht auf "ein Narr sein"->nichts können sondern "vernarrt"->mögen...

Naja,
Dieses Programm benutzt nur die täglichen Daten.
Ich habe mal versucht, die gesamte Datenbank seit 1999 reinzuladen, er lädt nur die ersten beiden Daten. Außerdem fehlt das Datum und mir fehlt die MSXML2_TLB.pas

Ich hatte bisher noch keine Erfahrungen mit XML und auch keine Ahnung von ihm im Zusammenhang mit Delphi.
Ich würde mir das ganze gerne erklären lassen :D
Da ich Delphi nur in der Schule lerne, ist das, was ich hier mache eigentlich "über meinen Fähigkeiten", also kann ich sowas nicht wissen. Natürlich habe ich schon gegooglet nach XML in Delphi etc. und auch nach der MSXML2_TLB.pas, doch die gefundene Datei hat sich hinterher als HTML-Datei entpuppt und zu XML hab ich nur Beschreibungen ab Delphi 7 gefunden.

Wenn du mir das ganze erklären könntest und die MSXML2_TLB.pas anhängen könntest (sofern erlaubt), wäre ich dir sehr dankbar!
Ich weiß, ich bin manchmal ein bisschen umständlich, liegt aber dadran, dass ich das ganze erst seit August lerne...

Liebe Grüße

sx2008 11. Dez 2009 22:00

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Die Datei MSXML2_TLB lässt man sich am Besten von Delphi erzeugen.
Je nach Delphi Version unterscheiden sich die Schritte etwas.
* Projekt schliesen
* im Menü entweder (D5-D7)Projekt->Typbibliothek importieren oder (D2007)Komponente->Komponente importieren... wählen.
* man bekommt eine sehr umfangreiche Liste von Typbiliotheken auf dem Rechner
* daraus "Microsoft XML, v4.0" auswählen
* keinen Komponentenwrapper erzeugen lassen
* das Defaultverzeichnis ...\Imports nicht ändern
* Unit anlegen
=> es wird MSXML2_TLB.pas in dem Imports-Verzeichnis erzeugt.

Delphi-Narr 11. Dez 2009 22:42

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Ah, vielen Dank!
Ich arbeite mich dann mal in XML ein...

Gute Nacht allerseits

xZise 13. Dez 2009 11:47

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Alternativ kann ich himXML empfehlen.

MfG
Fabian

Delphi-Narr 13. Dez 2009 20:10

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Delphi-Quellcode:
procedure TForm1.UpdateFromXML(const data: string; dataIsFile:Boolean);
var
   document : IXMLDOMDocument2;
   node, node2 : IXMLDOMNode;
   ElementCube : IXMLDOMElement;
   i : Integer;
   currency : string;
   rate : Double;
begin
   document := CoDOMDocument40.Create;

   if dataIsFile then
      document.load(data)
   else
      document.loadXML(data);

//   CheckDocumentError(document);


   node2 := document.documentElement;
   node := node2.lastChild;
//   node := document.documentElement.selectSingleNode('//Cube');
   node := node.firstChild;

   // Schleife über alle vorhandenen Währungen
   for i := 0 to node.childNodes.length-1 do
   begin
      ElementCube := node.childnodes.item[i] as IXMLDOMElement;
      currency := ElementCube.getAttribute('currency');
      rate    := ElementCube.getAttribute('rate');
      UpdateCurrency(currency, rate);
   end;

end;

Dies ist ja dein Code, data muss also der Dateipfad+Name sein. Also praktisch Ordner/dateiname.xml

So, ich hab das auch mal gemacht. Bei mir kommt allerdings eine Zugriffsverletzung:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
node:IXMLDOMNode;
Element:IXMLDOMELEMENT;
begin
     XMLDokument:=CoDOMDocument40.Create;
     XMLDokument.loadXML('datafiles/euroxref-hist.xml');
     node := XMLdokument.documentElement.selectSingleNode('//Cube');
     Element:=node.childnodes.item[1] as IXMLDOMElement;
end;
variable i ist für spätere Schleife(n)...

Wenn ich dann auf besagten Button klicke, wird die 3. Zeile nach Begin (node := ...) markiert und die Zugriffsverletzungsnachricht

Modul 00442242 Adresse 00000000

erscheint. Ich seh den Unterschied nicht genau... Ok, habe andere Bezeichnungen aber sonst müsste alles gleich sein, oder?
Habe das Tutorial hier mal gelesen, aber ist ja etwas anders aufgebaut, also hab ich da so meine Probleme mit. Ich kann auch nicht dort kopieren, was dort steht, weil mir wieder mal zwei .pas Dateien fehlen...

sx2008 14. Dez 2009 10:47

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Zitat:

Zitat von Delphi-Narr
... data muss also der Dateipfad+Name sein. Also praktisch Ordner/dateiname.xml

Das hast du falsch verstanden - LoadXML() nimmt einen XML-String entgegen.
Load() holt die Daten aus einer Datei oder URL.
Nach dem Laden muss überprüft werden, ob XMLdokument.documentElement = NIL ist.
Falls ja, ist beim Laden ein Fehler aufgetreten.
Bei deinem Code liegt das daran, dass du fälschlicherweise LoadXML() statt Load() verwendet.

Delphi-Narr 14. Dez 2009 19:48

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Achso, ok. Jetzt habe ich die Datei eurofxref-hist.xml

Die ist so aufgebaut:
XML-Code:
<?xml version="1.0" encoding="UTF-8" ?>
- <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
  <gesmes:subject>Reference rates</gesmes:subject>
- <gesmes:Sender>
  <gesmes:name>European Central Bank</gesmes:name>
  </gesmes:Sender>
- <Cube>
- <Cube time="2009-12-10">
  <Cube currency="USD" rate="1.473" />
  <Cube currency="JPY" rate="130.03" />
  <Cube currency="BGN" rate="1.9558" />
  <Cube currency="CZK" rate="25.705" />
  <Cube currency="DKK" rate="7.4417" />
  <Cube currency="EEK" rate="15.6466" />
  <Cube currency="GBP" rate="0.9043" />
  <Cube currency="HUF" rate="272.05" />
  <Cube currency="LTL" rate="3.4528" />
  <Cube currency="LVL" rate="0.7072" />
  <Cube currency="PLN" rate="4.1405" />
  <Cube currency="RON" rate="4.2382" />
  <Cube currency="SEK" rate="10.4367" />
  <Cube currency="CHF" rate="1.5113" />
  <Cube currency="NOK" rate="8.4355" />
  <Cube currency="HRK" rate="7.2668" />
  <Cube currency="RUB" rate="44.8505" />
  <Cube currency="TRY" rate="2.202" />
  <Cube currency="AUD" rate="1.6074" />
  <Cube currency="BRL" rate="2.5904" />
  <Cube currency="CAD" rate="1.5472" />
  <Cube currency="CNY" rate="10.0556" />
  <Cube currency="HKD" rate="11.4168" />
  <Cube currency="IDR" rate="13905.61" />
  <Cube currency="INR" rate="68.7" />
  <Cube currency="KRW" rate="1716.4" />
  <Cube currency="MXN" rate="19.0312" />
  <Cube currency="MYR" rate="5.0045" />
  <Cube currency="NZD" rate="2.0236" />
  <Cube currency="PHP" rate="68.075" />
  <Cube currency="SGD" rate="2.0473" />
  <Cube currency="THB" rate="48.793" />
  <Cube currency="ZAR" rate="11.0565" />
  </Cube>
- <Cube time="2009-12-09">
  <Cube currency="USD" rate="1.4768" />
  <Cube currency="JPY" rate="129.91" />
  <Cube currency="BGN" rate="1.9558" />
  <Cube currency="CZK" rate="25.749" />
  <Cube currency="DKK" rate="7.4416" />
  ...
  </Cube>
</cube>
Nicht zu jedem Datum ist jede Währung vorhanden. Im Optimalfall sollten es (Stand wie oben) 2802 Einträge sein. 20 Währungen aus dem ersten Cube sind in dieser Zahl vorhanden. Ich habe auch nicht nachgeprüft, ob bei älteren Daten andere Währungen sind. Ist auch ersteinmal unwichtig.
Also zur Auswahl stehen die aufgelisteten Währungen.
Erst muss also das Datum gesucht werden.
Hatte das bisher so, dass alle Daten durchsucht werden, solange das Datum2 (das aus der Datei) > ist als das aus der Datumsauswahl.
Dann wird die Variable i auf die Stelle gesetzt, ab wo der Kurs des eingegebenen Datums gilt.


Also

Eingabe: 27.10.2009


Datei:

0 -> 12.12.2009
1 -> 11.12.2009
2 -> 30.11.2009
3 -> 15.11.2009
4 -> 28.10.2009
5 -> 26.10.2009

als i erhalte ich also 5.

Jetzt müssen alle Unterpunkte von Cube[i] durchsucht werden, bis der Wert von currency gleich die angegebene Währung ist und dann muss die Variable Kurs auf den Wert vom Attribut "rate" gesetzt werden. Wenn die Währung nicht existiert, soll der Anwender dies mitgeteilt bekommen.

Könnte sich jemand die Zeit nehmen, mir mal zu erklären, wie ich das jetzt realisieren kann?
Liebe Grüße!

Delphi-Narr 15. Dez 2009 15:53

Re: Excel-Funktion im Hintergrund ablaufen lassen
 
Also ich habe es jetzt so versucht:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
node:IXMLDOMNode;
Element:IXMLDOMELEMENT;
begin
     XMLDokument:=CoDOMDocument40.Create;
     XMLDokument.loadXML('datafiles/xref-hist.xml');
     node := XMLdokument.documentElement.lastChild;
     node:=node.firstChild;
     Element:=node.childnodes.item[1] as IXMLDOMElement;
     ...
end;
Ich erhalte jedoch immer eine Zugriffsverletzung bei Adresse 00000000 und die Zeile node := XMLdokument... wird markiert. Ich versteh leider nicht, was ich falsch mache... Den Text aus manchen Nodes kann ich anzeigen lassen, aber ich brauche ja die Attribute. Und an die komm ich nicht ran.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:02 Uhr.
Seite 2 von 3     12 3      

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