Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Datei einlesen - Milchalarm (https://www.delphipraxis.net/126026-datei-einlesen-milchalarm.html)

ljmarkus 16. Dez 2008 15:33


Datei einlesen - Milchalarm
 
Hallo.

für einen Freund möchte ich ein Milchalarm Programm schreiben.
Die Daten von der Melkanlage liegen als File vor.

Wie kann ich eine Text-Datei öffnen und zb. in Zeile 8 gehen und die Position (Cursorposition) 5,6,7 auslesen ?



schon mal vielen Dank, Markus

Klaus01 16. Dez 2008 15:40

Re: Datei einlesen - Milchalarm
 
Hallo,

eine Datei kannst Du z.B. in eine StringList einlesen.

Delphi-Quellcode:
sl := TStringList.create;
sl.loadFromFile;
s:=sl[7];  die 8. Zeile
b5:=s[5];  der 5. Buchstabe
...
sl.free;
Wenn Du die Buchstaben 5-7 brauchst,
kannst Du sie mit der Funktion copy() (siehe Delphi Hilfe)
herauskopieren.

Grüße
Klaus

mkinzler 16. Dez 2008 15:42

Re: Datei einlesen - Milchalarm
 
Hat die Datei ein bestimmtes Format (CSV; Trennung mit Komma, Stringpunkt, Tab, ...)?

ljmarkus 16. Dez 2008 15:48

Re: Datei einlesen - Milchalarm
 
Liste der Anhänge anzeigen (Anzahl: 1)
Die hat folgendes Format:


VN000000 15767 120081012 223 210 usw...
VN000000 22197 220071224 183 198 usw...

Aufgeschlüsselt ist das Format:

unbekannt Kuhnr. Transponder unbekannt Gemelk1 Gemelk2 usw.
VN000000 1 5767 120081012 223 210
VN000000 2 2197 220071224 183 198

usw.



lg, markus



edit: im Anhang 1ne Datei mit 3 Datensätzen.

mkinzler 16. Dez 2008 15:50

Re: Datei einlesen - Milchalarm
 
Könnte man ja auch eine CSV-DataSet verwenden oder halt ein 2 geschachtelte StringListen mit entsprechenden Delimiter oder Explode()

ljmarkus 16. Dez 2008 16:45

Re: Datei einlesen - Milchalarm
 
Hab mal eine Datei mit angehängt.

lg, markus

Der.Kaktus 16. Dez 2008 16:53

Re: Datei einlesen - Milchalarm
 
Hallo,
wenn ich die Struktur so sehe, ist sie doch eindeutig und leicht in eine Datenbank, zum besseren bearbeiten/auswerten, zu implementieren.
Nimm einfach eine einfache Datenbank(kbmMemtable z.B.) erzeuge eine Datenbankstruktur..(Vnr....KuhNr. ..usw.) und konvertiere (einfache Variante) z.B.
Delphi-Quellcode:
 KB1.VNr:=copy(1,8,vnr);
etc. jeden Datensatz.

DeddyH 16. Dez 2008 16:54

Re: Datei einlesen - Milchalarm
 
Da das so aussieht, als ob die Sätze feste Längen haben, gebe ich Kaki vollinhaltlich Recht, das müsste recht einfach zu parsen sein.

ljmarkus 16. Dez 2008 16:55

Re: Datei einlesen - Milchalarm
 
hört sich gut an, nur wie mache ich es ?


lg, markus

DeddyH 16. Dez 2008 16:59

Re: Datei einlesen - Milchalarm
 
Das Einfachste dürfte ein Record oder eine Klasse sein, die die zu füllenden Felder beinhaltet. Durch den Einsatz von Copy kannst Du diese dann der Reihe nach befüllen. Ich bin gerade unter Linux unterwegs, aber ich könnte das ja mal schnell mit Lazarus probieren.

[edit] So, hier mal eine "Schmalspurversion" mit einer ListView (vsReport):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var sl: TStringList;
    i: integer;
    s: string;
    Item: TListItem;
begin
  sl := TStringList.Create;
  try
    sl.LoadFromFile(Dateiname);
    for i := 0 to sl.Count - 1 do
      begin
        if Length(sl[i]) < 3 then break;
        s := sl[i];
        Delete(s,1,8);  //die ersten 8 Stellen werden nicht benutzt
        Item := ListView1.Items.Add;
        Item.Caption := Copy(s,1,4);  //Kuh-Nr. (Stelle 1 bis 4)
        Item.SubItems.Add(Copy(s,5,4));//Transponder (Stelle 5 bis 8)
      end;
  finally
    sl.Free;
  end;
end;
[/edit]

Der.Kaktus 16. Dez 2008 17:10

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von ljmarkus
hört sich gut an, nur wie mache ich es ?


lg, markus

Habe mal nen Auszug aus einem aelteren Konvertierungsprogramm hier..benoetigte Unit kbmmemtable...(suche mal bei Google..kleiner Version als 5.6 ist Kostenfrei!!)

Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
var EF,AF:TEXTFILE;
    s:String;
    Options:TkbmMemTableSaveFlags;
begin
(***************************************************************************)
 AssignFile(EF,'C:\WORK\XXDAT012005.TXT'); //Deine Eingabedatei
 reset(EF);
 Assignfile(AF,'C:\WORK\XX_R1.2005.TXT'); //Kontrolldatei (ist nicht noetig bei Dir) erzeugt die Datei im CSV-Format
 rewrite(AF); //Datei Neuerstellen
 Writeln(AF,'PLZ;Ort;bei'); //Header fuer CSV-Kontrolldatei schreiben
 Screen.cursor:=crhourglass; //Cursor als Sanduhr..damit man was sieht *g*
 kbmMemTable1.Close;
 kbmMemTable1.FieldDefs.Clear; //We dont need this line, but it does not hurt either.
 kbmMemTable1.FieldDefs.Add('PLZ', FtString, 5, False);
 kbmMemTable1.FieldDefs.Add('ORT',FtString, 30, False);
 kbmMemTable1.FieldDefs.Add('BEI', FtString, 30, False);
 with kbmMemTable1.IndexDefs do
 begin
  Clear;
  Add('Index1','PLZ',[]); //Indizies erstellen ..bei Dir evtl die VNR...Index2 bei Dir nicht noetig(?)
  Add('Index2','ORT',[]);
 end;
 kbmMemTable1.CreateTable; //Tabelle erzeugen
 kbmMemTable1.active:=true;
 While Not EOF(EF) do
 begin
  s:='';
  Read(ef,s);readln(ef);
  With kbmMemTable1 do
  begin
   Append; //Datensatz anhaengen
   Application.Processmessages;
   FieldByname('PLZ').asstring:=OEM_Ansi(TrimRight(Copy(s,18,5)));
   FieldByname('ORT').asstring:=OEM_Ansi(TrimRight(Copy(s,106,23)));
   FieldByname('Bei').asstring:=OEM_Ansi(TrimRight(Copy(s,75,29)));

   Post;//Datensatz in Datenbank speichern
   Writeln(AF,OEM_Ansi(Copy(s,18,5))+';'+OEM_Ansi(Copy(s,106,23))+';'+OEM_Ansi(Copy(s,75,29))); //Ausgabe in Kontrolldatei
  end;
 end;
 Closefile(EF);
 CloseFile(AF);
 Screen.cursor:=crdefault; //Standardcursor setzen

//Datei als DB speichern
 Options:=[mtfSaveData, mtfSaveCalculated, mtfSaveBlobs, mtfSaveDef];
 Options:=Options+[mtfSaveIndexDef];
 Options:=Options+[mtfSaveDeltas];
 KbmMemTable1.SaveToBinaryFile('C:\WORK\XX2005_1.dat',options);
 Showmessage('save mem1');
End;
P.S.: Fuer alle anderen die das lesen..ich weiss..ist ohne Try und {$I+ bzw. - }..also kein Kommentar bitte ;-)

ljmarkus 16. Dez 2008 17:11

Re: Datei einlesen - Milchalarm
 
Liste der Anhänge anzeigen (Anzahl: 1)
der ganze Hintergrund ist der:

Morgens wird gemolken und dann steht bei Gemelk1 für jede Kuh die Zahlen. Gemelk2 ist dann noch 0.
Abend steht dann bei Gemelk1 das von Morgens und bei Gemelk2 das vom Abend.

Am nächsten Tag wieder wie oben.

Das ganze soll nun in eine kleine Datenbank wo so 3 Gemelke von jeder Kuh drinnen stehen und verglichen werden:

Gemelk2 kleiner als 20% von Gemelk1 = Nachricht
Gemelk1 kleiner als 20% von Gemelk2 vom Vortag = Nachricht.


im Anhang nochmal die ganze Datei mit Beschriftung von mir.

Der.Kaktus 16. Dez 2008 17:15

Re: Datei einlesen - Milchalarm
 
..Wenn Du in die Datenbank noch das Datum aufnimmst und evtl einen Index drauf setzt..kannst Du die Datei prima weiterverarbeiten.

mkinzler 16. Dez 2008 17:21

Re: Datei einlesen - Milchalarm
 
Man könnte es auch mit einem CSV-DataSet ( z.B. TJvCSVDataSet) versuchen

Der.Kaktus 16. Dez 2008 17:23

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von mkinzler
Man könnte es auch mit einem CSV-DataSet ( z.B. TJvCSVDataSet) versuchen

Ich habe dies noch nicht genutzt..aber setzt sicher CSV Datei vorraus..welche ich ja erzeuge..koennte man sicher als Äquivalent fuer die "kbmMemtable" nehmen. :thumb:

mkinzler 16. Dez 2008 17:26

Re: Datei einlesen - Milchalarm
 
Man könnte die Datei gleich damit öffnen

DeddyH 16. Dez 2008 17:27

Re: Datei einlesen - Milchalarm
 
Das Dumme ist, dass es hier kein Trennzeichen gibt, sondern nur feste Feldlängen.

Der.Kaktus 16. Dez 2008 17:28

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von mkinzler
Man könnte die Datei gleich damit öffnen

Delimiterangabe also moeglich..OK ein Trim muesste aber erfolgen!
[Edit]
Ich weiss nicht wie "Fit" der Autor ist..deshalb wuerde ich zur einfachen Read..copy Variante tendieren.
[/Edit]
P.S.: Deddy war schneller und besser :-D

Noch ein Edit...

ich habe mal sowas anstatt Kuehe fuer Bullen geschrieben..(Besamungsstation)incl. Anbindung an die Messstation..da hatte ich auch solche Quelldaten und kam mit der Read/Copy Methode gut hin.

mkinzler 16. Dez 2008 17:41

Re: Datei einlesen - Milchalarm
 
Im Beispiel sind Trennzeichen(Leerzeichen) vorhanden.

ljmarkus 16. Dez 2008 17:42

Re: Datei einlesen - Milchalarm
 
@Der.Kaktus

der Autor ist nicht so fit *grins*

Wie meinst Du das mit der Read/Copy Funktion ?


lg, markus

Der.Kaktus 16. Dez 2008 17:45

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von ljmarkus
@Der.Kaktus

der Autor ist nicht so fit *grins*

Wie meinst Du das mit der Read/Copy Funktion ?


lg, markus

Wie in meinem Beispiel...Datei einlesen Satz fuer Satz und mit dem copy-Befehl die einzelnen Felder rausholen.

ljmarkus 16. Dez 2008 17:48

Re: Datei einlesen - Milchalarm
 
wenn ich kbmmemtable installieren will sagt es das er das Package dbrtl nicht finden.

Google spuckt leider auch nix brauchbares raus wo ich es herbekomme.


lg, markus

mkinzler 16. Dez 2008 17:50

Re: Datei einlesen - Milchalarm
 
Den PE-Versionen fehlt leider der Datenbankteil der VCL :cry:

Der.Kaktus 16. Dez 2008 17:52

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von ljmarkus
wenn ich kbmmemtable installieren will sagt es das er das Package dbrtl nicht finden.

Google spuckt leider auch nix brauchbares raus wo ich es herbekomme.


lg, markus

Habe noch ne Uraltversion "TkbmMEMTABLE v. 2.53g (2. Oct. 2001)"..die ging prima!

@mkinzler ups..uebersah seine Version..schaute nur nach D7 !!

ljmarkus 16. Dez 2008 17:53

Re: Datei einlesen - Milchalarm
 
und nun ?

mkinzler 16. Dez 2008 17:54

Re: Datei einlesen - Milchalarm
 
Zitat:

Habe noch ne Uraltversion "TkbmMEMTABLE v. 2.53g (2. Oct. 2001)"..die ging prima!
Implemnetiert die TDataSet und Co.?
Zitat:

und nun ?
Record für Werte nehmen und als DynArray oder Liste implementieren

Michael Habbe 16. Dez 2008 17:54

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von ljmarkus
wenn ich kbmmemtable installieren will sagt es das er das Package dbrtl nicht finden.

Google spuckt leider auch nix brauchbares raus wo ich es herbekomme.


lg, markus


Arbeitest Du wie im Profil steht mit D7 Personal?
Dann wird das mit Datenbankzugriff nix, da dieses eine Beschränkung der Version ist.



edith: der rote kasten fehlte :gruebel:

ljmarkus 16. Dez 2008 17:56

Re: Datei einlesen - Milchalarm
 
ja mit der D7 Personal arbeite ich.

Der.Kaktus 16. Dez 2008 17:56

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von mkinzler
Zitat:

Habe noch ne Uraltversion "TkbmMEMTABLE v. 2.53g (2. Oct. 2001)"..die ging prima!
Implemnetiert die TDataSet und Co.?

Jep..s.o. habs zu spaet gelesen..muss er nur die Konvertierung nehmen(ohne kbmmemtable..hat er CSV-Datei..kann die dann evtl.?? mit Excel bzw. JV... weiterbearbeiten.(?)

DeddyH 16. Dez 2008 17:58

Re: Datei einlesen - Milchalarm
 
Schau Dir nochmal mein Edit an: http://www.delphipraxis.net/internal...=976899#976899

Der.Kaktus 16. Dez 2008 18:02

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von DeddyH

oder so :thumb:

ljmarkus 16. Dez 2008 18:04

Re: Datei einlesen - Milchalarm
 
Was ist die Tlist ? Delphi kennt die nicht.


lg, markus

mkinzler 16. Dez 2008 18:06

Re: Datei einlesen - Milchalarm
 
Hast du Classes den Uses hinzugefügt?

DeddyH 16. Dez 2008 18:07

Re: Datei einlesen - Milchalarm
 
Meinst Du jetzt die TStringlist? Die ist in Classes definiert, die ListView ist eine Komponente (Eigenschaft ViewStyle auf vsReport gestellt).

ljmarkus 16. Dez 2008 18:10

Re: Datei einlesen - Milchalarm
 
Zitat:

Zitat von mkinzler
Hast du Classes den Uses hinzugefügt?

Ja habe ich dort stehen.

Michael Habbe 16. Dez 2008 18:17

Re: Datei einlesen - Milchalarm
 
Wenn Du keine DB-Komponenten verwenden kannst, versuch es mal mit dem StringGrid, das sollte es auch in der Personal geben.

Delphi-Quellcode:
procedure tuwas;
var
  f: Textfile;
  s: String;
  i: integer;
begin
  i := 1;
  AssignFile(f, Milchdatei);
  reset(f);
  while not eof(f) do
  begin
    readln(f, s);
    StringGrid1.Cells[i, 1] := Copy(s, 1, 5);
    StringGrid1.Cells[i, 2] := Copy(s, 6, 5);
    StringGrid1.Cells[i, 3] := Copy(s, 10, 5);
    StringGrid1.Cells[i, 4] := Copy(s, 17, 5);
    StringGrid1.Cells[i, 5] := Copy(s, 25, 5);
    inc(i);
  end;
  CloseFile(f);
end;
Die Zahlen im Copy müssen natürlich an Deine Datei angepasst werden.


edit: Runde Klammern durch eckige ersetzt, Quelltext ohne Delphi getippt :mrgreen:

ljmarkus 16. Dez 2008 18:30

Re: Datei einlesen - Milchalarm
 
bei StringGrid1.Cells(i, 1) := Copy(s,1,4); meggert er rum:

'[' expected but '(' found


so muss es lauten:

StringGrid1.Cells[i, 1] := Copy(s,1,4)

DeddyH 16. Dez 2008 18:32

Re: Datei einlesen - Milchalarm
 
Delphi-Quellcode:
StringGrid1.Cells[i, 1] := Copy(s,1,4);


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:55 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