Von einer Textdatei zum Diagramm..

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
jonas_rotter1234
Beiträge: 14
Registriert: Sa 7. Nov 2015, 21:49

Von einer Textdatei zum Diagramm..

Beitrag von jonas_rotter1234 »

Liebe Lazarus-Community,

langsam bin ich so verzweifelt, dass ich mich dazu entschieden habe, mal hier nachzufragen. Ich möchte mit einer .txt-Datei, welche zunächst in ein Memo eingelesen wird und dann eigentlich weiter in ein StringGrid eingelesen werden soll, ein Diagramm erstellen. Bis jetzt habe ich folgenden Ansatz:

Code: Alles auswählen

var
  sl: TStringList;
  o : String;
  zeilennr : Integer;
begin
  sl:=TStringList.Create;
  o:='C:\Users\Jonas\Google Drive\Anlagendaten\' + DBEdit1.Text;
  try
    sl.LoadFromFile(o);
    for zeilennr:=0 to sl.Count-1 do
    begin
    Memo1.Lines.Assign(sl);
    end;
  finally
    sl.free;
  end;
end;
Zur Übertragung ins StringGrid habe ich noch keine wirklich Idee, da meine Ideen sich eher in die Richtung bewegen, ich aber meistens dann Fehlermeldungen erhalte.

Code: Alles auswählen

 for zeilennr := 0 to Pred(Memo1.Lines.Count) do
 begin
   text1 := Memo1.Lines[zeilennr];
   posi1 := Pos (':',text);
   StringGrid1.Cells[1,zeilennr+1] := copy (text1,1,posi1-1);
In der eingelesenen Textdatei gibt es also Datum & Uhrzeit, Dauer und Counter, welche möglichst alle ins StringGrid eingelesen werden sollen. Danach möchte ich am liebsten mit einer PaintBox ein Liniendiagramm erstellen.

Schon mal im Voraus herzlichen Dank für eure Bemühungen und Antworten.

Mit freundlichen Grüßen,
jonas_rotter1234 :)

wp_xyz
Beiträge: 5152
Registriert: Fr 8. Apr 2011, 09:01

Re: Von einer Textdatei zum Diagramm..

Beitrag von wp_xyz »

Die Stringliste sl darfst du den Memo.Lines nicht in der Schleife zuweisen, sondern nur 1x:

Code: Alles auswählen

 
var
  sl: TStringList;
begin
  sl:=TStringList.Create;
  o:='C:\Users\Jonas\Google Drive\Anlagendaten' + DBEdit1.Text;
  try
    sl.LoadFromFile(o);
    Memo1.Lines.Assign(sl);
  finally
    sl.free;
  end;
end;
Ich nehme an, die Text-Datei enthält Datum/Uhrzeit, Dauer und Counter in durch ein Spezialzeichen getrennten Spalten. Ein Tabulator? Ein Strichpunkt? Ein Komma? Für solche Dateitypen hat StringGrid schon eine Leseroutine eingebaut:

Code: Alles auswählen

 
procedure LoadFromCSVFile(AFilename: string; ADelimiter: Char=','; UseTitles: boolean=true; 
  FromLine: Integer=0; SkipEmptyLines: Boolean=true);
 
Falls der Spaltentrenner kein Komma ist, musst du das entsprechende Zeichen als "ADelimiter" angeben. "Mit UseTitles" definierst du, dass die 1. Zeile die Spaltenüberschriften enthält. "FromLine" ist die Zeilennummer, ab der Werte ins Grid übernommen werden (Nummer beginnt mit 0). Und "SkipEmptyLines" erlaubt, Leerzeilen zu überspringen.

Achtung: Dies ist die Syntax für Lazarus 1.5, ich glaube das SkipEmptyLines ist erst vor kurzem reingekommen. Ältere Lazarusversionen funktionieren aber sinngemäß genauso.

Das Diagramm machst du am besten mit TAChart. Da hast du gleich alles mit eingebaut: Achsenbeschriftung, verschiedene Kurzentypen, Zoomen etc. Um den Einstieg zu erleichtern, schau dir das Getting-Started-Tutorial an: http://wiki.lazarus.freepascal.org/TACh ... ng_started. Es gibt auch eine Dokumentation: http://wiki.lazarus.freepascal.org/TACh ... umentation, in der auch weitere Tutorials verlinkt sind.

jonas_rotter1234
Beiträge: 14
Registriert: Sa 7. Nov 2015, 21:49

Re: Von einer Textdatei zum Diagramm..

Beitrag von jonas_rotter1234 »

Hallo @wp_xyz!
Erst einmal vielen Dank für deine schnelle Antwort und deine Hilfe! Es kann sein, dass ich mich grad einfach blöd anstelle. Aber leider wird im StringGrid nichts ausgegeben. Was habe ich vergessen?

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Grids;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
      procedure LoadFromCSVFile(AFilename: string; ADelimiter: Char; UseTitles: boolean;
  FromLine: Integer; SkipEmptyLines: Boolean);
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
  o : String;
begin
  sl:=TStringList.Create;
  try
    sl.LoadFromFile('C:\Users\Jonas\Google Drive\Anlagendaten\MF-HKA4_Rotter');
    Memo1.Lines.Assign(sl);
  finally
    sl.free;
  end;
LoadFromCSVFile('C:\Users\Jonas\Google Drive\Anlagendaten\MF-HKA4_Rotter', ':', true, 1, true);
end;
 
procedure LoadFromCSVFile(AFilename: string; ADelimiter: Char=':'; UseTitles: boolean=true;
  FromLine: Integer=1; SkipEmptyLines: Boolean=true);
begin
 
end;
 
end.
Da ich mich leider mit LoadFromCSVFile nicht so auskenne, weiß ich auch nicht wirklich, was in die Prozedur alles rein soll...
Ich würde mich über eine Hilfe sehr freuen.

Mit freundlichen Grüßen,

jonas_rotter1234

wp_xyz
Beiträge: 5152
Registriert: Fr 8. Apr 2011, 09:01

Re: Von einer Textdatei zum Diagramm..

Beitrag von wp_xyz »

OK - da war ich zu schlampig und hab bei dem "LoadFromCSVFile" weggelassen, dass das eine Methode von TStringGrid ist; ich hatte gedacht, das würde sich aus dem Kontext ergeben. So müsste es gehen (ich nehme an, dass dein StringGrid den Standardnamen "StringGrid1" hat):

Code: Alles auswählen

 
procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
  o : String;   // wofür ist das?
  fn: String;   // Dateiname
  // Da du denselben Dateinamen zweimal verwendest, ist es günstiger dafür eine Variable zu spendieren
  // D.h. wenn du einmal einen anderen Dateinamen verwenden willst, musst du nur 1 Stelle ändern.
begin
  fn := 'C:\Users\Jonas\Google Drive\Anlagendaten\MF-HKA4_Rotter';
  sl:=TStringList.Create;
  try
    sl.LoadFromFile(fn);
    Memo1.Lines.Assign(sl);
  finally
    sl.free;
  end;
  StringGrid1.LoadFromCSVFile(fn, ':', true, 1, true);
end;

jonas_rotter1234
Beiträge: 14
Registriert: Sa 7. Nov 2015, 21:49

Re: Von einer Textdatei zum Diagramm..

Beitrag von jonas_rotter1234 »

Hallo wp_xyz!
Vielen Dank für die Antwort, du hast mir super weitergeholfen!
Hast du eine Idee, wie ich ein Diagramm zeichne, bei dem ein Funktionswert einem Datum zugeordnet ist?
Mit freundlichen Grüßen,

jonas_rotter1234

jonas_rotter1234
Beiträge: 14
Registriert: Sa 7. Nov 2015, 21:49

Re: Von einer Textdatei zum Diagramm..

Beitrag von jonas_rotter1234 »

...Beziehungsweise einfach z.B. mit einer Schleife in ein zweites Grid die Zeilen beschriften, habe in diese Richtung gedacht:

Code: Alles auswählen

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  i : Integer;
begin
StringGrid1.Row := StringGrid1.RowCount;
for i:=0 to StringGrid1.Row do begin
    StringGrid2.Cells[0,i];
  end;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var
  y,x : Real;
  i : Integer;
begin
StringGrid1.Row := StringGrid1.RowCount;
for i:=0 to StringGrid1.Row do begin
  x:=StrToFloat(StringGrid2.Cells[i,0]);
  y:=StrToFloat(StringGrid1.Cells[i,1]);
  Chart1LineSeries1.AddXY(x,y);
end;
end;
Ich weiß, die Datenumwandlung ist noch nicht richtig, aber was habe ich hier falsch gemacht bzw. wie kann ich das verbessern? Beim Ausführen wird mir: Index out of Range [0,5] angezeigt...

wp_xyz
Beiträge: 5152
Registriert: Fr 8. Apr 2011, 09:01

Re: Von einer Textdatei zum Diagramm..

Beitrag von wp_xyz »

jonas_rotter1234 hat geschrieben:Hast du eine Idee, wie ich ein Diagramm zeichne, bei dem ein Funktionswert einem Datum zugeordnet ist?
Weiß nicht, was genau das Problem ist... Enthält das Stringgrid Datumszellen? Dann wandle den String (z.B. '13.11.2015') mit Hilfe der Funktion StrToDate in eine Zahl, die du dann in der AddXY-Methode der Series als Parameter einsetzen kannst.

Code: Alles auswählen

 
var
  x: Double;
  y: TDate;
...
  x:=StrToFloat(StringGrid2.Cells[i,0]);
  y:=StrToDate(StringGrid1.Cells[i,1]);
  Chart1LineSeries1.AddXY(x, y);
jonas_rotter1234 hat geschrieben:Beziehungsweise einfach z.B. mit einer Schleife in ein zweites Grid die Zeilen beschriften, habe in diese Richtung gedacht:
Nochwas, was ich nicht verstehe...

Egal, was du erreichen willst, die Zeile "StringGrid1.Row := StringGrid.RowCount" ist falsch: StringGrid1.Row ist der Index der Zeile, in der sich die aktive Zelle befindet. Offenbar willst du hier die aktive Zelle in die letzte Zeile setzen. Nachdem die Zellen-Indizierung bei 0 beginnt, ist der Index der letzten Zelle aber RowCount-1, nicht RowCount. Lazarus bedankt sich dafür, auf eine nicht existierende Zeile zugreifen zu woillen, mit einem "Index out of range".

jonas_rotter1234
Beiträge: 14
Registriert: Sa 7. Nov 2015, 21:49

Re: Von einer Textdatei zum Diagramm..

Beitrag von jonas_rotter1234 »

Ich habe das jetzt so gemacht und jetzt funktioniert es auch:

Code: Alles auswählen

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  i,x : Integer;
begin
x := StringGrid1.RowCount;
for i:=0 to x-1 do begin
    StringGrid2.Cells[0,i]:=IntToStr(i);
  end;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var
  y,x : Real;
  i : Integer;
  s,s1,s2 : String;
begin
for i:=0 to StringGrid1.RowCount-1 do begin
  s:=StringGrid1.Cells[1,i];
  s1:=copy(s,18,18);
  s2:=copy(s1,2,4);
  x:=StrToFloat(StringGrid2.Cells[0,i]);
  y:=StrToFloat(s2);
  Chart1LineSeries1.AddXY(x,y);
end;
end; 
Ich bin grad sehr sehr glücklich und bedanke mich vielmals!!!!
Zuletzt geändert von Lori am Sa 14. Nov 2015, 09:05, insgesamt 2-mal geändert.
Grund: Bitte den Highlighter benutzen

Antworten