Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Datensatz auswerten und aufteilen. (https://www.delphipraxis.net/135778-datensatz-auswerten-und-aufteilen.html)

Jens Hartmann 17. Jun 2009 22:49


Datensatz auswerten und aufteilen.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

EDIT.....ACHTUNG CROSSPOST......EDIT.END

CROSSPOST IM DF

jetzt melde ich mich nochmal mit einem Problem. Ich hatte mal einen Beitrag, bei dem es um das Zerlegen von Stringlisten ging, um den Inhalt aufzuteilen und nach wunsch in ein VirtualStringTree als Tabelle anzuzeigen.

Siehe alten Beitrag...

Alter Beitrag

Nachdem ich jetzt mein Programm erstmal verfeinert habe, möchte ich nun gerne auf einen Kundenwunsch reagieren, und einen neuen Zentralentyp in meine Software integrieren.

Bislang, konnte ich alle Daten, die mir zur Verfügung gestellt wurden, an verschieden Kriterien auseinanderhalten. Heißt zum Beispiel, das ich einen START-String hatte, oder einen STOP-String, zumindest immer irgendwas, was immer gleich war, um die Position der Druckdatei zu erkennen.

Leider versuche ich das ganze bei dem neuen Typ jetzt schon seid mehrern Tagen, und komme leider auf keine Lösung. Die Anbindung selber, habe ich realisiert bekommen und diese Funktioniert auch. Die Daten die mir die Zentrale sendet, wird auch in einem Memo sauber angezeigt und wie bei einem Protokolldrucker geschrieben. Dies kommt aber durch die mitgelieferten Sonderzeichen....
#13#10 oder so #$D#$A

Das Ende von einem Datensatz, wird im Memo durch die doppelte Version gelößt.

Und zwar so #$D#$A' '#$D#$A

Mein Problem liegt allerdings darin, das meine Komponente ComDataPacket (siehe alter Beitrag) oder "ComPortLib" scheinbar zumindestens nicht die Zeichen #$D#$A' '#$D#$A lesen bzw. auswerten kann.

Deshalb jetzt meine Frage. Im Anhang liegt der Datensatz. Erkennt da jemand ein anderes Kriterium, um die einzelnen Datensätze auseinander zu halten, oder weiß jemand, wie ich sonst folgende Zeichen #$D#$A' '#$D#$A auswerten kann.

Über Eure antworten, bin ich jetzt schon dankbar.

Also Gruß Jens.

PS: Sorry, das der Text solange ist, aber ich wusste ich, wie ich mein Problem kürzer beschreiben konnte.

sx2008 18. Jun 2009 01:13

Re: Datensatz auswerten und aufteilen.
 
Schreib' die Daten in eine TStringList, dann kannst du danach bequem die Einzelteile auslesen:
Delphi-Quellcode:
var
  list : TStringList;
begin
  list := TStringList.Create;
  list.Text := deinDatenString;
  list.Delete(0); // 1. Zeile löschen, da sie leer ist
  ShowMessage(list[0]); // ABSCHALT irgendwas
  ShowMessage(Trim(list[1])); // Alle ......
  list.Free;

Jens Hartmann 18. Jun 2009 07:07

Re: Datensatz auswerten und aufteilen.
 
Ja, ich weiß.
Das ist aber gar nicht so das Problem. Das Problem liegt eher darin, das die Daten die von der Zentrale kommen, immer gesendet werden, da in der Zentrale nur die Einstellung NICHT ÜBERWACHTER DRUCKER möglich ist.

Soll heißen, die Daten werden einfach von der Zentrale gesendet. Da aber es ja jetzt sein kann, das beim Programm Start ein Datensatz in der Mitte anfängt, und zwar so.

LT. äZ-TBL '#$D#$A' Alle Zentralenschaltpkte'#$D#$A' '#$D#$A,

muss ja meine Software erkennen, das dieser 1. Satz Müll ist, und gar nicht erst in meine Tabelle eingetragen wird bzw, wenn dann so....

ID Datum Uhrzeit Ereignis Typ
LT. . Alle Zen....
36 10.10.2009 usw.

Daher müsste ich, den meiner Meinung nach einzigen eindeutigen Unterschied, die zwei Zeilenumbrüche am Schluss von jedem Datensatz erkennen. Das wäre, ja mit einer Art...

Delphi-Quellcode:
if Daten = #13#10#13#10 then
  {Möglich},
Aber, da die Schnittstelle, ja meistens mehr als einen Datensatz finden wird, weil ja wie gesagt, die Zentrale immer einfach sendet, kann natürlich auch so was in der Variablen stehen...

LT. äZ-TBL '#$D#$A' Alle Zentralenschaltpkte'#$D#$A' '#$D#$A
' 36 17.06.09 14:32 '#$D#$A' ABSCHALT. äM-TBL '#$D#$A' Alle Melderschaltpunkte'#$D#$A' '#$D#$A
' 37 17.06.09 14:32 '#$D#$A' ABSCHALT. äL”A '#$D#$A' Alle L”schanlagen'#$D#$A' '#$D#$A
' 39 17.06.09 14:36 ID: 2'#$D#$A' Codebetrieb EIN '#$D#$A' Codebetrieb'#$D#$A' '#$D#$A
' 40 17.06.09 14:36 '#$D#$A' ABSCHALT. äU

Damit ensteht jetzt eigendlich mein Hauptproblem, ist ein gelesen Puffer, mit folgenden Daten gefüllt. würde der erse Datensatz als Müll erkannt, und entsorgt. Soweit OK. Jetzt würde meine Var. Funktionieren und Daten bis zum letzten Datensatz ordenlich verarbeiten. Wird dieser jetzt ausgewertet, stell die Software natürlich fest, das dieser nicht komplett ist, und würde in aber trotzallem eintragen, was ja auch richtig wäre.

Beim nächsten lesen der Schnittstellen Daten, würde aber jetzt folgendes empfangen...

EE '#$D#$A' Alle šbertragungseinr.'#$D#$A' '#$D#$A
' 41 17.06.09 14:36 '#$D#$A' ABSCHALT. äSG '#$D#$A' Alle Steuergruppen'#$D#$A' '#$D#$A
' 42 17.06.09 14:36 '#$D#$A' ABSCHALT. äZ-TBL '#$D#$A'

Daraus, würde sich ergeben, das der oberste Datensatz wieder entsorgt würde(da Müll) und mit dem zweite weiter gearbeitet würde. Daraus, würde entstehen, das jeder 2,3,4 (je nach Geschwindigkeit und Anzahl der Auftretenden Ereignisse der Zentrale) in der späteren Tabelle fehlen würde.

Ich hoffe das ist so irgendwie OK beschrieben.

Vieleicht weiß ja jemand, wie ich damit umgehen kann.

Gruß Jens

Jens Hartmann 18. Jun 2009 13:45

Re: Datensatz auswerten und aufteilen.
 
Habe jetzt nochmal so ein bißchen an der Überlegung gebastelt.

Folgender gedanke ist mir jetzt gekomme. Wenn ich es über eine StringList realisieren würde, müsste es doch möglich sein, eine Schleife zu bauen, die immer solange läuft, bis kein Sting mehr kommt, der mit #10#13#10#13 abgeschlossen ist.

Dann würde ich, Zeile für Zeile schreiben, wenn dieses Kriterium erfüllt ist aufhören, und anschließend neu einlesen. Heiß also
das der letzte Datensatz zwar nicht komplett ist, aber in der Stringliste vorhanden bleibt, und die Stringliste nur um den neuen String erweitert wird.

Delphi-Quellcode:
var
  list : TStringList;
begin
  list := TStringList.Create;
  list.Text := DatenZentrale
  list.Delete(0); // 1. Zeile löschen, da sie leer ist
  ShowMessage(list[0]); // ABSCHALT irgendwas
 
  //Wenn noch ein #13#10#13#10 irgendwo in der Liste ist, dann lösche list[0] und
  list.Delete(0);
  ShowMessage(list[0]); // Alle ......
  list.Free;
Mein Problem, ist jetzt nur, wie kann ich es Abfragen, ob hinter einem #13#10#13#10 irgendwann nochmal ein #13#10#13#10 kommt.

Gruß Jens

DeddyH 18. Jun 2009 14:03

Re: Datensatz auswerten und aufteilen.
 
Versuch es mal mit PosEx() auf den Text der Stringliste.

Jens Hartmann 18. Jun 2009 23:52

Re: Datensatz auswerten und aufteilen.
 
Hallo DeddyH,

Danke für den guten Tip. Ich habe zwar die Lösung noch nicht fertig, aber ich weiß jetzt, das es mit PosEx und Pos gehen muss.
Ich habe einfach mal das ganze Simuliert, und habe jetzt schon folgendes Ergebnis. Also das zerlegen des Datensatzes
müsste so funktionieren.

Ich stell meinen Code mal hier ein, vieleicht ist er ja für Euch Interessant, oder es hat noch jemand Tips.

Der Code verarbeitet die Daten zwar noch nicht wie erforderlich, aber er gibt im ShowMessage die Datensätze aus. Optimal zum testen, auch für andere Stringprobleme.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
s : String;
Pos1 : Integer;
Pos2 : Integer;
Datensatz1 : String;
Datensatz2 : String;
begin
s := ' 51  17.06.09 14:36 #$D#$A     ABSCHALT. MG 1-01 MB1 #$D#$A     Gruppe#$D#$A     #$D#$A'+
  '52  17.06.09 14:37 #$D#$A     ABSCHALT. MG 2-01 MB1 #$D#$A     Gruppe#$D#$A     #$D#$A';
Pos1 := Pos('#$D#$A     #$D#$A', s);
if Pos1 <> 0 then
begin
  ShowMessage('Erstes Ende Datensatz an Position: ' + IntToStr(Pos1));
  Datensatz1 := Copy(s,0,Pos1);
  ShowMessage(Datensatz1);
  Pos2 := PosEx('#$D#$A     #$D#$A', s, Pos1 + 1);
  if Pos2 <> 0 then
    begin
    ShowMessage('Weiteren Datensatz gefunden an Position: ' + IntToStr(Pos2));
    Datensatz2 := Copy(s,Pos1,Pos2);
    ShowMessage(Datensatz2);
    end
  else
    ShowMessage('Es wurde nur ein vollständiger Datensatz gefunden');
  end
  else
  begin
    ShowMessage('Es wurde kein Vollständiger Datensatz gefunden');
  end;
end;
Also, wenn noch jemand Anregungen hat, nehme ich die gerne zur Kenntnis.

Gruß Jens

Jens Hartmann 21. Jun 2009 18:41

Re: Datensatz auswerten und aufteilen.
 
Hallo und guten Abend zusammen,

war mal wieder schwerer als gedacht. In der Theorie, funktioniert mein gedanke wunderbar, leider aber in der Praxis nicht, da die Daten der Schnittestelle nicht in einem kompletten Datensatz vorhanden sind.

Das Problem liegt darin, das ich Sie nicht als Packet empfangen kann, da ich ja scheinbar keinen immer vorhanden StartString habe, und wenn ich nur Daten die im Ausgangspuffer der Schnittstelle lese, ließt meine Komponente immer, und somit ist der Datensatz nie vollständig.

Daher mal ne frage zum StartString: was ja schon in meinem oben genannten Beitrag nicht funktioniert hat, war die Variante mit

#$D#$A#$A#$1B oder #13#10 als StartString,

Wäre es eventuell doch möglich, diesen irgendwie, und wenn mit einer anderen Komponente zu nutzen. Weil dann wäre mein Problem gelößt,

Oder, kann ich als StartString auch einen Integer von 0000 bis 9999 nehmen.

Meine Zentrale hat am Anfang immmer die laufende Nummer des Ereignisses. Dies ist immer von 0 - 9999 Möglich. Kann man irgendwie folgendes sagen...

Delphi-Quellcode:
ComPacket1.StartString := IntToStr(0..9999); // geht so nicht, weiß ich. Aber ich hoffe ihr wisst was ich meine.
:gruebel:

Gruß Jens

mschaefer 21. Jun 2009 19:27

Re: Datensatz auswerten und aufteilen.
 
So etwas Schleier ist mir ja noch auf Deinem Problem,
aber bei Übertragungskomponenten hat #13#10 meist intern
Funktionalität...

Grüße // Martin

Jens Hartmann 21. Jun 2009 20:17

Re: Datensatz auswerten und aufteilen.
 
Ja, du hast recht. Das habe ich ja oben geschrieben. Das seltsame ist halt, das folgendes im String zu sehen ist, aber nicht ausgewertet werden kann.

#$D#$A#$A#$1B

Auswerten, kann ich mit #13#10. Meine Schnittstellenüberwachung StartString, erkennt aber leider gar nichts von beidem. Die Function die Du mir gesendet hast, wofür soll das sein. :gruebel:

Wenn die Daten irgendwie Intern in der Schnittstelle genutzt werden, gib es denn vieleicht eine Komponente, die anders arbeitet?

Mein Problem liegt ja momentan darin, das ich ohne StartString gar keine Daten bekomme, und mit der Variante RxChar lesen (Daten von Schnittstelle lesen, wenn vorhanden) Ist ein Ereigniss meiner Komponente, bekomme ich keine kompletten Datensatz, und müsste noch umständlich anfangen, den Datensatz zusammenzubauen.

Gruß Jens

mschaefer 21. Jun 2009 21:22

Re: Datensatz auswerten und aufteilen.
 
Wenn in den Daten #10#13 vorkommt macht die daraus eine Stringstücl '%10%13' mit ausgeschriebenen Zahlen. Dadurch hat man in den Nutzdaten niemals #13#10 als Byte-Werte ...

Grüße // Martin

Jens Hartmann 21. Jun 2009 21:27

Re: Datensatz auswerten und aufteilen.
 
Ja, kann man die nicht nutzen?

alzaimar 21. Jun 2009 21:29

Re: Datensatz auswerten und aufteilen.
 
Eigentlich müsste das doch ganz einfach gehen:
1. Suche nach '$0D$0A'.
2. Wir sind am Anfang des Datensatzes. (P <- aktuelle Position)
3. Suche nach '$0D$0A'
4. Wir sind am Ende des Datensatzes. (Q <- aktuelle Position)
5. Datensatz <- Daten[P..Q-2]
6. Datensatz verarbeiten
7. Gehe zu 1

Jens Hartmann 21. Jun 2009 22:00

Re: Datensatz auswerten und aufteilen.
 
Hallo alzaimer,

das dachte ich auch. Ist es aber leider nicht. Das Problem liegt darin, das ich das ja nur machen kann, wenn ich einen kompletten Datensatz zur Verfügung hätte. Das Problem dabei ist, den bekomme ich nur mit der Komponente ComPacket hin. Dafür, benötige ich allerdings einen Start und Stop String, den ich ja leider nicht habe.

Also lese ich von der Schnittstelle mit dem Ereignis RxChar. Hierbei, werden sobald Daten an der Schnittstelle diese eingelesen, verarbeitet und dann kann das Ereignis erneut ausgelößt werden.

Daraus folgt, das die Empfangen Zeichen immer Abhängig von der Anzahl der auftretenden Ereignisse, sowie der Verarbeitungszeit der zuletzt Empfangen Daten.

Somit, wäre es halt einfach, wenn wenigstens immer ein kompletter Datensatz an der Schnittstelle anliegen würde. Das Problem entsteht nämlich Hauptsächlich, wenn nur ein Paar einzelne Zeichen vorhanden sind. Dann muss ich erst anfangen, den Datensatz zusammenzubauen. Also alles nicht so einfach.

Ich habe es mittlerweile realisiert, 6 Zentralentypen und deren Daten zu verarbeiten. Doch bei allen, kann ich es halt über Packet mit Start und Stop machen.

Somit ist halt das größte Problem, das ich die Daten nach dem Empfangen erstmal wieder passend zusammen basteln müsste. Und ich denke einfach, das das einfacher gehen muss.

Gruß jens

Jens Hartmann 21. Jun 2009 22:26

Re: Datensatz auswerten und aufteilen.
 
Ich habe es hinbekommen. Und es war ganz einfach.

Mein Fehler lag in folgendem.

STARTString ist #$D#$A#
STOPString ist #$D#$A#$A#$1B

Ich habe geschrieben...

Delphi-Quellcode:
ComDataPacket1.StartString := '#$D#$A';
ComDataPacket1.StopString := '#$D#$A#$A#$1B';

//Richtig wäre, und so funktioniert es auch....

ComDataPacket1.StartString := #$D#$A;
ComDataPacket1.StopString := #$D#$A#$A#$1B;

//Die '   ' um den String, dürfen ja nicht sein.
:thumb:

Danke trotzdem für Eure Bemühungen. Aber mschaefer, was hat es mit deinem Code auf sich. Was sollte ich damit probieren?

Gruß Jens

alzaimar 21. Jun 2009 22:52

Re: Datensatz auswerten und aufteilen.
 
Zitat:

Zitat von Jens Hartmann
das dachte ich auch. Ist es aber leider nicht.

Doch, so ist es. Das nennt sich 'Frame' und genau das passiert im Com-Handler, den Du verwendest. In dessen Handler wird jeder Frame nach der o.g. Methode erkannt. Dabei kann es natürlich passieren, das der 1.Frame unerkannt bleibt, weil man ja gerade in der Mitte des Frames anfängt, zu lesen.

Jens Hartmann 22. Jun 2009 17:06

Re: Datensatz auswerten und aufteilen.
 
Danke alzaimer,

für die Erklärung über den Frame. Das wusste ich noch nicht. Aber wie du ja wahrscheinlich gelesen hast. Ich habe es ja dann doch noch hinbekommen.

Trotzdem Danke,

Gruss Jens


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:33 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 by Thomas Breitkreuz