Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Fremdes Datenformat einfach lesen in Delphi (https://www.delphipraxis.net/69489-fremdes-datenformat-einfach-lesen-delphi.html)

Berserker 15. Mai 2006 23:51

Datenbank: APDATA • Version: ... • Zugriff über: muss entwickelt werden

Fremdes Datenformat einfach lesen in Delphi
 
Hallo.

Es geht um folgendes, Ich möchte ein Datenformat von einem Lieferanten in Delphi einlesen um es weiter zu verarbeiten.

Jedoch ist das echt komplex. Eine Dokumentation habe ich auch dafür. Gibt es Beispiele wie man solche Formate in Delphi einlesen kann?

MfG, Ronny

Mackhack 16. Mai 2006 00:19

Re: Fremdes Datenformat einfach lesen in Delphi
 
Hi,

schreib n Parser. Nimm die Daten auseinander und lese sie in deine eigene Datenbank ein. So wuerd ich es machen!

Vlt. hilft dir ja Delphi-Referenz durchsuchenDelimiter das ist das Trennzeichen zwischen jedem Feld das du pro Datensatz in deiner uebergebenen (exportierten) Datei hast!

Hansa 16. Mai 2006 00:38

Re: Fremdes Datenformat einfach lesen in Delphi
 
Hoffentlich glaubst Du nicht, daß es für sowas etwas komplett fertiges gibt. Da ist echte Handarbeit gefragt. Jo Parser. immer solche komischen Wörter Oh je, wenn das nicht als Textdatei vorliegt sondern codiert (integer, real usw.), dann gute Nacht. 8) Ansonsten zeilenweise einlesen und die Zeilen zerpflücken in appetitliche Felder für eigene DB. Und dann eben so :

Delphi-Quellcode:
DS.Insert;
// alle Felder zuweisen :
DS.FieldByName ('NAME').As<integer, Float usw.> := copy (zeile (523,50));
DS.Post;
Alternative : lange nach passender Komponente suchen, die eventuell geht.

P.S.: Was ist Apdata ?

Oxmyx 16. Mai 2006 00:58

Re: Fremdes Datenformat einfach lesen in Delphi
 
Wenn du schon eine Dokumentation über das Format hast, was ist dann genau dein Problem, die Daten einzulesen? Ich nehme mal an, dass es sich um eine binäre Datei handelt, keine Textdatei. Dann steht doch in der Dokumentation genau drin, wie du die Daten zu interpretieren hast.
Also beschreibe mal genauer, was am Einlesen der Daten nicht funktioniert.

jim_raynor 16. Mai 2006 04:49

Re: Fremdes Datenformat einfach lesen in Delphi
 
Zum Beispiel kannst du mit TFileStream wunderbar eine Datei Byteweise einlesen.

r2c2 16. Mai 2006 07:23

Re: Fremdes Datenformat einfach lesen in Delphi
 
Zitat:

Zitat von jim_raynor
Zum Beispiel kannst du mit TFileStream wunderbar eine Datei Byteweise einlesen.

Muss nicht mal Byteweise sein...

Wenn du das Format kennst und es sich um ein konstantes Binärformat handelt, sollte das einfach per record gehen(bisher noch nie gemacht; nur davon gelesen):
Delphi-Quellcode:
TDaten = record // oder packed record --> siehe Dokumentation
  // hier die Daten in der Reihenfolge, in der sie in der Dokumentation stehen
end;

procedure LoadFromFile(AFileName: string);
begin
  // per Stream in record lesen...
end;
Je nachdem, wie kompliziert das Format ist, könnte es sein, dass du
a) Variante records brauchst
b) an den Einstellungen was ändern musst(Byte-Align oder sowas)
c) doch Byteweise lesen musst, weil die Datensätze unterschiedlich lang sind und du auch nicht variante records nehmen kannst
d) doch n Parser schreiben musst, weil es Textdateien sind

mfg

Christian

jim_raynor 16. Mai 2006 07:38

Re: Fremdes Datenformat einfach lesen in Delphi
 
Zitat:

Zitat von r2c2
a) Variante records brauchst

Es gibt die Möglich mit "file of" zu arbeiten. Stichworte sind da Hier im Forum suchenAssign, Hier im Forum suchenRewrite, Hier im Forum suchenWrite. Allerdings funktioniert das nicht mit varianten Records, sondern nur mit festen. Zudem dürfen keine AnsiStrings (Shortstrings ala String[20] sind erlaubt) und keine dynamischen Arrays verwendet werden. Aber wie schon gesagt, hängt es stark vom Dateiformat ab, welche Variante denn nun am optimalsten ist.

Hansa 16. Mai 2006 07:41

Re: Fremdes Datenformat einfach lesen in Delphi
 
Zitat:

Zitat von Oxmyx
..Ich nehme mal an, dass es sich um eine binäre Datei handelt, keine Textdatei. Dann steht doch in der Dokumentation genau drin, wie du die Daten zu interpretieren hast...

Binärdatei für Import/Exportzwecke wäre zumindest sehr ungewöhnlich. Denn was ist ein integer ? 8 bit oder 16 Bit ? Hat Delphi überhaupt einen mit dem Erstellungsprogramm der Daten 1:1 kompatiblen Datentyp ? Wie ist ein Aufzählungstyp in Cobol etc. aufgebaut ? Arrays, Records, Sets ?? Selbst wenn es ein Delphi-Programm wäre, welches die Daten gespeichert hat : ist vielleicht Compilerschalter (*$Xy+*) gesetzt ? Wer bietet mehr ? :mrgreen: Allerdings gibt es auf jeden Fall Mittel und Wege die Daten zu kriegen, eventuell so, wie es mir schon mal passiert war : einziges Speichermedium zum Datenaustausch : 8 Zoll Disketten (kein Witz !), unbekanntes Betriebssystem, keinerlei Daten-Dokumentation. Unser Glück war, daß ein serieller Drucker angeschlossen war. Auch ohne jede Information darüber. Typ noch nie von gehört. :wall: Dieser wurde kurzerhand gegen einen PC ausgetauscht. Dann mußte die Baudrate noch durch bloßes testen herausgefunden werden. Alleine die serielle Datenübertragung dauerte Tage. Allerdings fältt mir doch noch ein Tool ein, was so was ähnliches etwas vereinfacht : "Monarch". --> Google. Sogar wenn eine Textdatei vorliegt, wovon ich nach wie vor ausgehe : Selbst dann dürfte StringReplace gefordert sein. Achtung vor CSV und Umlauten ! Tausender-Trennzeichen oder Decimalseparator.

Mavarik 16. Mai 2006 07:46

Re: Fremdes Datenformat einfach lesen in Delphi
 
Zitat:

Zitat von Berserker
Hallo.

Es geht um folgendes, Ich möchte ein Datenformat von einem Lieferanten in Delphi einlesen um es weiter zu verarbeiten.

Vielleicht postest Du mal ein Stück der Datei...

Frank

Berserker 16. Mai 2006 08:46

Re: Fremdes Datenformat einfach lesen in Delphi
 
Also es handelt sich bei der Datei um ein reines Textfile.

Ich würde es gerne hiermit versuchen.
Jedoch weis ich nicht ob dies auch mit Textdateien möglich ist.

Delphi-Quellcode:
TDaten = record // oder packed record --> siehe Dokumentation
  // hier die Daten in der Reihenfolge, in der sie in der Dokumentation stehen
end;

procedure LoadFromFile(AFileName: string);
begin
  // per Stream in record lesen...
end;
Hier ein kleiner Auszug aus dem File:

Delphi-Quellcode:
00K
01ADR_APO
02UPD
0320060515
0420060501
05ABDATA DATEN-SERVICE
06Adressen
071001
0815
00F
0101
02Key_ADR
031
040
05V
065
07NU1
00F
0102
02Firmenname
030
040
05V
0640
07AN1
MfG, Ronny

Robert Marquardt 16. Mai 2006 08:59

Re: Fremdes Datenformat einfach lesen in Delphi
 
Na das laedt man am besten erst mal in eine TStringList und zaehlt die Datensaetze durch.
Ich vermute mal das das die zwei Ziffern am Zeilenanfang Zeilenangaben/Elementangaben sind und das ein Uebergang auf einen neuen Datensatz durch eine kleinere Nummer angezeigt wird.
Vermutlich impliziert die Nummer auch eine Typangabe fuer den Inhalt. Man kann also ein passendes Record definieren und nun ein "array of" dieses Records mit SetLength alloziieren. Vermutlich ist die Dokumentation mehr oder minder die Definition eines solchen Records.
Nun klappert man die TStringList nochmal ab und uebertraegt die Daten in die Records. Da braucht man noch die Dokumentation die sagt ob Zeilen fehlen duerfen und was dann der Defaultwert ist.

raiguen 16. Mai 2006 10:27

Re: Fremdes Datenformat einfach lesen in Delphi
 
Moin :-)
Warum so kompliziert :roll: Da es sich um ein reines Textfile handelt, kann man es doch so machen:
Delphi-Quellcode:
procedure Auslesen;
var S: String;
    F: TextFile;
begin
   Assign(F, Pfad_und_Name_der_Textdatei);
   Reset(F);
   while not Eof(F) do
     begin
       Readln(F, S);
       {hier weitere MAssnahmnen um den String anhand der Doku zu zerlegen und entsprechend neu abzuspeichern}
   end;
   CloseFile(F);
end;
APDATA dürfte ein 'spezielles' Datenformat für Apotheken (Rote Liste für Medikamente etc) sein :gruebel:

Robert Marquardt 16. Mai 2006 10:50

Re: Fremdes Datenformat einfach lesen in Delphi
 
Das ist ein ineffizienter Weg. Man muss dazu ja dauernd neue Datensaetze alloziieren.

himitsu 16. Mai 2006 11:16

Re: Fremdes Datenformat einfach lesen in Delphi
 
Man könnte ja auch erstmal die Datensätze zählen, Speicher allocieren, an den Dateianfang springen und dann Einlesen ... 's wäre zumindestens sparsammer im Speicherverbrauch, dafür ließt man allerdings die Datei zweimal ein :roll:

Hansa 16. Mai 2006 23:28

Re: Fremdes Datenformat einfach lesen in Delphi
 
Zitat:

Zitat von raiguen
{hier weitere MAssnahmnen um den String anhand der Doku zu zerlegen und entsprechend neu abzuspeichern}

So isset. Die "weiteren Maßnahmen" stehen oben in #3. Habe das vorweggenommen. Das wäre schon das Grundgerüst für das ganze Programm. Haken an der Sache ist, ob die Definition der alten Daten genau genug ist und ins eigene DB-Konzept paßt. Existiert die überhaupt schon ?

Berserker 27. Mai 2006 13:43

Re: Fremdes Datenformat einfach lesen in Delphi
 
Hallo.

Also ich bin schon ein Stück weitergekommen.
Ich lese die Textdatei in eine StringList ein und verarbeite diese dann.

Liste laden:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
 sl := TStringList.Create;
 sl.LoadFromFile('ADR_APO.UPD');
 Memo1.Lines := sl;
end;
Verarbeiten:
Delphi-Quellcode:
procedure TForm1.Button5Click(Sender: TObject);
var i: integer;
    zeile: string;
begin
 DS.Open;
 i := 0;
 while i < sl.Count do begin
  zeile := sl.Strings[i];
  Memo2.Lines.Add(zeile);
  if(zeile='00K') then begin
   // Kopfdefinition
   i := Lese_Kopf(i);
  end else if(zeile='00F') then begin
   i := Lese_Feld(i);
  end else begin
   Inc(i);
  end;
 end;
end;
Funktion um den Kopf zu lesen:
Delphi-Quellcode:
{** KOPF LESEN ****************************************************************}
function TForm1.Lese_Kopf(posi: integer): integer;
var i: integer;
    s, s1, prefix, zeile: string;
begin
  // BEGIN Kopf-Record lesen
  for i := 1 to anzahl_felder_k do begin
   Inc(posi);
   zeile := sl[posi];
   prefix := Copy(zeile,1,2);
   s := Copy(zeile,3,length(zeile));
   if( prefix='01') then begin
    edF01.Text := s;
   end else if( prefix='02') then begin
    edF02.Text := s;
   end else if( prefix='03') then begin
    edF03.Text := s;
   end else if( prefix='04') then begin
    edF04.Text := s;
   end else if( prefix='05') then begin
    edF05.Text := s;
   end else if( prefix='06') then begin
    edF06.Text := s;
   end else if( prefix='07') then begin
    edF07.Text := s;
   end else if( prefix='08') then begin
    edF08.Text := s;
    anzahl_tabelle_felder := StrToInt(s);
   end;
   result := posi;
  end;
  // END Kopf-Record lesen
end;
{******************************************************************************}
Für evtl. Verbesserungen bin ich immer offen.
Habe ja bisher noch nie mit solchen Files gearbeitet.

MfG, Ronny

Klaus01 27. Mai 2006 13:57

Re: Fremdes Datenformat einfach lesen in Delphi
 
Du könntest z.B. findComponet verwenden,
damit kannst Du dir die Aufzählung der Edit Componente (edF01, edF02 ..) sparen

Grüße
Klaus

Delphi-Quellcode:
{** KOPF LESEN ****************************************************************}
function TForm1.Lese_Kopf(posi: integer): integer;
var i: integer;
    s, s1, prefix, zeile: string;
begin
  // BEGIN Kopf-Record lesen
  for i := 1 to anzahl_felder_k do
    begin
      Inc(posi);
      zeile := sl[posi];
      prefix := Copy(zeile,1,2);
      s := Copy(zeile,3,length(zeile));
 
      TEdit(FindComponent('edF' + prefix)).text:=s;
 
      anzahl_tabelle_felder := StrToInt(s);
   end;
   result := posi;
  end;
  // END Kopf-Record lesen
end;
{******************************************************************************}

Berserker 27. Mai 2006 14:18

Re: Fremdes Datenformat einfach lesen in Delphi
 
Stimmt. Das ist natürlich wesentlich einfacher :)

Gibt es eine Möglichkeit, das ich via ReadLn Blockweise aus dem Textfile lesen kann?

Beispiel vom File:
00K
01ADR_APO
02UPD
0320060515
0420060501
05Testlieferant XYZ
06Adressen
071001
0815
00F
0101
02Key_ADR
031
040
05V
065
07NU1
00F
0102
02Firmenname
030
040
05V
0640
07AN1


Im Textfile gibt es mehrere Blöcke:

00K <- Beginn Kopfsatz (Dieser kommt nur einmal vor)
01(Dateiname)
02(Update oder Gesamtdatei)
03(Datum von)
04(Datum bis)
05(Lieferant)
06(Dateiname Lang)
07(Datei-ID
08(Anzahl der Felder)

Danach kommen die Feld-Definitionen
00F <- Begin einer Felddefinition (können mehrmals vorkommen, pro Feld ein solcher Block)
01 \
02 +--- Da stehen dann Feldname, Größe und so weiter
03 /

00D,00I,00U sind dann die Datensätze wobei D-Delete, I-Insert, U-Update ist
011449

Könne man dies nicht blockweise lesen und dann verarbeiten?
Wenn ja wie kann man dies bewerkstelligen?

Klaus01 27. Mai 2006 14:30

Re: Fremdes Datenformat einfach lesen in Delphi
 
Da die Datei nicht Datensatz orientiert (indiziert) ist geht es
wohl nicht anders.

Es sei denn die Zeilen sind alle gleich lang, dann könntest
Du eine gewisse Byteanzahl einlesen. (BlockRead)

Grüße
Klaus

Berserker 27. Mai 2006 14:32

Re: Fremdes Datenformat einfach lesen in Delphi
 
Also der Kopf ist immer 8 Zeilen Lang
die Felder-Defs sind immer 7 Zeilen lang
und die Feldzeilenanzahl ergibt sich ja durch die anzahl der Felder

Klaus01 27. Mai 2006 14:37

Re: Fremdes Datenformat einfach lesen in Delphi
 
Ich dachte auch eher an die Zeilenlänge, also die Anzahl an Zeichen pro Zeile.

Das ist bei der Datei wohl nicht der Fall.
Da wirst Du wohl bei Readln bleiben müssen.

Mußt Du denn ein und dieselbe Datei öfter einlesen?
Wenn ja, kannst Du Sie ja in eine datensatzorientierte Datei umwandeln.

Grüße
Klaus

marabu 27. Mai 2006 16:14

Re: Fremdes Datenformat einfach lesen in Delphi
 
Hallo Ronny,

hier ein kleines Code-Fragment für dich - vielleicht zeigt es dir den Weg zu einer etwas professionelleren Lösung. Die Daten würde ich aber in einem Konsolprogramm verarbeiten. Plausibilitätskontrollen und Behandlung von Datenfehlern habe ich weggelassen, damit man den eigentlichen Ansatz besser erkennt.

Delphi-Quellcode:
procedure TDemoForm.ProcessLine(groupCode: Char; index: Integer; line: String);
var
  iRow: Integer;
begin
  case groupCode of
    'K': ProcessK(index, line);
    'F': ProcessF(index, line);
    'D': ProcessD(index, line);
    'U': ProcessD(index, line);
    'I': ProcessD(index, line);
    else LogError();
  end;

{ === nur zum Testen ===
  with StringGrid do
  begin
    iRow := RowCount;
    RowCount := RowCount + 1;
    FixedRows := 1;
    Cells[0, iRow] := groupCode;
    Cells[1, iRow] := IntToStr(index);
    Cells[2, iRow] := line;
  end;
  === }
end;

procedure TDemoForm.ProcessActionExecute(Sender: TObject);
var
  tf: TextFile;
  index: Integer;  // record index
  sIndex: String[2];
  s: String;
  sGroup: String[1];
begin
  sGroup := ' ';
  AssignFile(tf, ParamStr(1));
  Reset(tf);
  while not Eof(tf) do
  begin
    ReadLn(tf, sIndex, s);
    index := StrToInt(sIndex);
    if index = 0
      then sGroup := Copy(s + ' ', 1, 1)
      else ProcessLine(sGroup[1], index, s);
  end;
  CloseFile(tf);
end;
Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:56 Uhr.

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