Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Über Timer Stringlist 'weiterschalten' (https://www.delphipraxis.net/92299-ueber-timer-stringlist-weiterschalten.html)

Svenkan 17. Mai 2007 16:27


Über Timer Stringlist 'weiterschalten'
 
Hey Leute!
Da ich mit meinem Programm den aktuellen Vertretungsplan aus einer dbf auslesen lasse und nun nicht mehr nur in eine HTML-Datei ausgeben, sondern auch auf einem Monitor darstellen lassen will, benötige ich nun die Möglichkeit, dass das nur eine gewisse Anzahl an Zeilen in einem Stringgrid dargestellt werden (23) und falls noch mehr Zeilen vorhanden sind, über einen Timer dann autom. die nächste 'Seite' dargestellt wird.
Ich habe es bereits über eine Schleife probiert..jedoch erfolglos.
Gibt es dazu evtl ein Tutorial? Oder hat hier jemand eine Idee, wie dies zu realisieren ist?

Apollonius 17. Mai 2007 16:48

Re: Über Timer Stringlist 'weiterschalten'
 
Du willst, dass nach einer gewissen Zeit automatisch die nächste Seite angezeigt wird? Dann könntest du eine Schleife mit delay verwenden.

Svenkan 17. Mai 2007 16:57

Re: Über Timer Stringlist 'weiterschalten'
 
Das hilft mir leider nicht bei meinem allg. Problem, wie dies zu realisieren wäre.

Klaus01 17. Mai 2007 17:10

Re: Über Timer Stringlist 'weiterschalten'
 
Du könntest doch innerhalb des Timers ermitteln wieviele Zeilen
vorhanden sind, sind es mehr als 23 liest Du nur 23 ein und setzt ein
Flag (welches auch ausserhalb des Timers existiert). Beim nächsten Aufruf
des Timers prüfst Du ob das Flag gesetzt ist, ist es gesetzt werden die
nächsten Zeilen geladen, ist es nicht gesetzt werden die ersten 23 Zeilen geladen.

Grüße
Klaus

Svenkan 17. Mai 2007 17:13

Re: Über Timer Stringlist 'weiterschalten'
 
Hättest du dafür vlt. ein Beispiel?

Real_Thunder 17. Mai 2007 17:27

Re: Über Timer Stringlist 'weiterschalten'
 
Hmm.. gibt da mehrere Möglichkeiten..

erstmal ist zu klären wie du die einträge in das stringgrid einließt.

Eine ganz simple, wenn auch nicht keine sehr saubere lösung ist, wenn du Alle daten in ein unsichbares 'stringgrid',
einem record, einem 2d array oder wie auch immer einließt.

dann die anzahl der datensätze ermittelst, und mit einem timer oder einer scheife mit delay nach und nach auf das stringgrid setzt...
das du ja die anzahl der gesammtdatensätzte hast, und weiß vie wiele du pro zyklus auf dem stringgrid haben willst, sollte es doch an sich kein problem sein.

Mfg Real Thunder

p.s. wenn du beispielcode brauchst sage einfach bescheid

Klaus01 17. Mai 2007 17:27

Re: Über Timer Stringlist 'weiterschalten'
 
Hatte mir das ungefähr so vorgestellt.

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FlagMoreThan23 : Boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if FlagMoreThan23 then
    begin
      // load next lines
      if restZeilen = 0 then
        FlagMoreThan23:=false;
    end
  else
    begin
      if anzahlZeilen > 23 then
        begin
         // load first 23 lines
         FlagMoreThan23:=true;
       end;
    end;


end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FlagMoreThen23:=false;
end;
Grüße
Klaus

Svenkan 17. Mai 2007 17:48

Re: Über Timer Stringlist 'weiterschalten'
 
Zitat:

Zitat von Real_Thunder
wenn du beispielcode brauchst sage einfach bescheid

Wäre ganz nett, die Variante auch mal zu sehen. :)

Real_Thunder 17. Mai 2007 18:39

Re: Über Timer Stringlist 'weiterschalten'
 
Werde dan mal eben ein kleines beispielproject machen.
In ca 15 min Ist es denn da.

Svenkan 17. Mai 2007 18:41

Re: Über Timer Stringlist 'weiterschalten'
 
Ist echt sehr nett von dir. :)

Real_Thunder 17. Mai 2007 19:39

Re: Über Timer Stringlist 'weiterschalten'
 
Liste der Anhänge anzeigen (Anzahl: 1)
So ich habe mal die Record und Timer Variante gemacht...

Einfach auf Daten Holen klicken
zum testen habe Ich per Schleife 200 Datensätze erstellt.

Edit:
Um die Daten aktuell zu halten, kannst du anstatt die die aktuelle seite auf 0 zu sätzen einfach die Procedure getdata wieder aufrufen.


MfG Real Thunder

DP-Maintenance 17. Mai 2007 21:21

DP-Maintenance
 
Dieses Thema wurde von "Christian Seehase" von "Datenbanken" nach "Sonstige Fragen zu Delphi" verschoben.
Auch wenn das Programm dBase benutzt.. Das Problem hat damit nichts zu tun.

Svenkan 18. Mai 2007 11:33

Re: Über Timer Stringlist 'weiterschalten'
 
Danke!
Ich werdes mir mal direkt anschauen! :)

/edit: Wie kann ich denn in einem StringGrid die obere Zeile beschriften?

Real_Thunder 18. Mai 2007 12:11

Re: Über Timer Stringlist 'weiterschalten'
 
oberste zeile
Delphi-Quellcode:
stringgrid1.cells[1,0]:=Text;
die linke spalte ist string wert da ein Stringgrid ja an sich strings nimmt

also um in einem stringgrid eien strin in ein feld einzutragen machst du es es
Delphi-Quellcode:
stringgrid1.cells[Spalte,Zeile]:= DeinString;

die oberste zeile zeile kannste du im oncreate event der form befüllen, da sich diese ja nicht ändert.

Svenkan 18. Mai 2007 12:20

Re: Über Timer Stringlist 'weiterschalten'
 
Ah!
Dankeschön für das tolle Beispiel!
Hat mir wirklich sehr weitergeholfen! :)

Svenkan 18. Mai 2007 12:40

Re: Über Timer Stringlist 'weiterschalten'
 
Obwohl, ich hätte doch noch eine Frage:
es wird immer nur der allererste Eintrag aus der Tabelle in alle Zeilen des Grids geschrieben.

Delphi-Quellcode:
 for count := 0 to Pred(Query1.RecordCount) do begin
  for y:=1 to Pred(Query1.RecordCount) do begin
    daten[y-1].klasse:=Query1.FieldByName('KLASSEN').AsString;
    daten[y-1].stunde:=Query1.FieldByName('S').AsInteger;
    daten[y-1].fuer:=Query1.FieldByName('FUER').AsString;
    daten[y-1].wer:=Query1.FieldByName('WER').AsString;
    daten[y-1].fach:=Query1.FieldByName('FACH').AsString;
    daten[y-1].raum:=Query1.FieldByName('RAUM').AsString;
    daten[y-1].bemerkung:=Query1.FieldByName('BEMER_SCH').AsString;
  end;
 end;
Was müsste ich daran ändern, damit es wieder stimmt?

Sidorion 18. Mai 2007 12:44

Re: Über Timer Stringlist 'weiterschalten'
 
'Query1.next', wobei ich mich frage, wozu Du die äußere Schleife brauchst. Falls es dazu ist, die Daten mehrfach aus der Query zu lesen, dann solltest Du vor der inneren Schleife 'Query1.first' ausführen.

Svenkan 18. Mai 2007 12:47

Re: Über Timer Stringlist 'weiterschalten'
 
Ah! Wieder das next >.<
Ok..thx
Mhm..stimmt. Die eine Schleife ist völlig unnötig.

Svenkan 26. Mai 2007 18:21

Re: Über Timer Stringlist 'weiterschalten'
 
Mir fällt grade auf..
Es wird immer ein Eintrag zu wenig ausgegeben. Die letzte Tablerow fehlt irgendwie immer (also bei 5 mög. Zeilen werden nur die ersten 4 ausgegeben).

DeddyH 26. Mai 2007 18:26

Re: Über Timer Stringlist 'weiterschalten'
 
Delphi-Quellcode:
for y:=1 to Pred(Query1.RecordCount) do begin
Wieso 1 und nicht 0?

Svenkan 26. Mai 2007 19:03

Re: Über Timer Stringlist 'weiterschalten'
 
Liste der Anhänge anzeigen (Anzahl: 1)
siehe Anhang ;)

DeddyH 26. Mai 2007 19:57

Re: Über Timer Stringlist 'weiterschalten'
 
Hallo,
werd Dir mal einig ;). Entweder lässt Du das Pred weg oder Du fängst bei 0 an und änderst daten[y-1] in daten[y].

Svenkan 27. Mai 2007 12:03

Re: Über Timer Stringlist 'weiterschalten'
 
Das würde ich ja gerne machen, aber jeder deiner Vorschläge zieht ne Zugriffsverletzung beim Lesen hinter sich. :(

DeddyH 27. Mai 2007 12:19

Re: Über Timer Stringlist 'weiterschalten'
 
Zeig doch mal den aktuellen Source.

Svenkan 27. Mai 2007 12:35

Re: Über Timer Stringlist 'weiterschalten'
 
So, ich habs jetzt doch hinbekommen. :)
Hatte was übersehen.
Trotzdem danke!

Svenkan 27. Mai 2007 12:52

Re: Über Timer Stringlist 'weiterschalten'
 
Wobei..wie bekomme ich es hin, dass ich so eine Funktion jede Sekunde neu ausführen lasse?
So liest er mir ja nur den Inhalt aus, der beim Start des Programms in der Datei vorhanden war.
Wenn nun aber neue Einträge hinzukommen, muss zunächst das Programm neu gestartet werden....

DeddyH 27. Mai 2007 14:19

Re: Über Timer Stringlist 'weiterschalten'
 
Wie wäre es mit einem Timer?

Svenkan 28. Mai 2007 12:36

Re: Über Timer Stringlist 'weiterschalten'
 
Man kann Funktionen also auch darin einbetten?
War mir da nicht so sicher, deshalb hab ich besser nochmal nachgefragt..
OK, werds ausprobieren. ;)

Svenkan 28. Mai 2007 18:14

Re: Über Timer Stringlist 'weiterschalten'
 
Liste der Anhänge anzeigen (Anzahl: 2)
Mhm..
Wenn ich das über nen Timer laufen lasse, wird ab der 2. Seite alles nur noch mit einem Eintrag gefüllt. :/

DeddyH 28. Mai 2007 18:31

Re: Über Timer Stringlist 'weiterschalten'
 
Vielleicht braucht die Funktion länger als eine Sekunde. Setz doch mal einen Button auf die Form und aktualisiere über den. Mal sehen, ob der Fehler dann immer noch auftritt.

Svenkan 28. Mai 2007 18:38

Re: Über Timer Stringlist 'weiterschalten'
 
Ich hab das jetzt ja in den normalen Timer mit reingesetzt, wo auch dann nach im Moment 10s gewechselt wird.
Die erste Seite wird ganz normal aufgerufen.
Vorher wurde die Funktion GetData nur im FormCreate ausgeführt, da hats funktioniert (es wurden nur leider dann die Sachen geladen, die zu dem Zeitpunkt in der .dbf waren).
Oder kann es sein, dass irgendwie etwas wieder freigegeben werden muss?

DeddyH 28. Mai 2007 18:41

Re: Über Timer Stringlist 'weiterschalten'
 
Ohne den Source zu kennen, kann ich da nichts zu sagen. :zwinker:

Svenkan 28. Mai 2007 18:44

Re: Über Timer Stringlist 'weiterschalten'
 
(bitte nicht wieder wg. Einrückung schlagen :oops:)

GetData-Procedure:

Delphi-Quellcode:
procedure TForm2.GetData;
var  y,ya: Integer;
begin
Label7.Caption:=TimeToStr(Time);
Label8.Caption:=DateToStr(Now);
if not (Query1.RecordCount=0) then begin
 SetLength(Daten,Query1.RecordCount);

  for y:=1 to Query1.RecordCount do begin
    daten[y-1].klasse:=Query1.FieldByName('KLASSEN').AsString;
    daten[y-1].stunde:=Query1.FieldByName('S').AsString+'.';
    daten[y-1].fuer:=Query1.FieldByName('FUER').AsString;
    daten[y-1].wer:=Query1.FieldByName('WER').AsString;
    daten[y-1].fach:=Query1.FieldByName('FACH').AsString;
    daten[y-1].bemerkung:=Query1.FieldByName('BEMER_SCH').AsString;
    daten[y-1].raum:=Query1.FieldByName('RAUM').AsString;

    Query1.Next;
  end;

  gesseiten:=length(Daten) div 19;
  aktuseite:=0;
 end;

if NOT (Query2.RecordCount=0) then begin
 SetLength(Daten2,Query2.RecordCount);
  for ya:=1 to Query2.RecordCount do begin
    daten2[ya-1].klasse:=Query2.FieldByName('KLASSEN').AsString;
    daten2[ya-1].stunde:=Query2.FieldByName('S').AsString+'.';
    daten2[ya-1].wer:=Query2.FieldByName('WER').AsString;
    daten2[ya-1].fuer:=Query2.FieldByName('FUER').AsString;
    daten2[ya-1].fach:=Query2.FieldByName('FACH').AsString;
    daten2[ya-1].bemerkung:=Query2.FieldByName('BEMER_SCH').AsString;
    daten2[ya-1].raum:=Query2.FieldByName('RAUM').AsString;

    Query2.Next;
  end;

  gesseitena:=length(Daten2) div 19;
  aktuseitea:=0;
end;
end;
Timer-Aufruf:

Delphi-Quellcode:
procedure TForm2.TimerReloadTimer(Sender: TObject);
var
   Ini: TIniFile;
   y,ya,i,ia,count,counta,ReloadTime,dnr:integer;
   morgen_m,heute_d,morgen_d: String;
   tomorrow,today: TDateTime;
begin
GetData;

  dnr:=DayOfWeek(Date);
  if dnr=7 then begin
   today:=Date+2;
   tomorrow:=Date+3;
  end
  else if dnr=6 then begin
   today:=Date+3;
   tomorrow:=Date+4;
  end
  else if dnr=1 then begin
   today:=Date+1;
   tomorrow:=Date+2;
  end
  else begin
   today:=Date;
   tomorrow:=Date+1;
  end;

 try
    Ini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'conf.ini');
    ReloadTime:=(Ini.ReadInteger('Zeiteinstellungen','Tagwechsel',10)*1000);
    morgen_m:=Ini.ReadString('Zeiteinstellungen','Datum morgen',DatetoStr(tomorrow));
    if StrToDate(morgen_m)<tomorrow then morgen_m:=DateToStr(tomorrow)
    else tomorrow:=StrToDate(morgen_m);
  finally
    Ini.Free;
  end;

 if PageControl1.TabIndex=0 then begin
  if aktuseite = Gesseiten then
    count := length(Daten) mod 19
  else
    count := 19;
  y:= 19*AktuSeite;
  stringgrid1.RowCount:=count+1;
  for i:=0 to count-1 do begin
    stringgrid1.Cells[0,i+1]:= Daten[i+y].klasse;
    stringgrid1.Cells[1,i+1]:= Daten[i+y].stunde;
    stringgrid1.Cells[2,i+1]:= Daten[i+y].fuer;
    stringgrid1.Cells[3,i+1]:= Daten[i+y].wer;
    stringgrid1.Cells[4,i+1]:= Daten[i+y].fach;
    stringgrid1.Cells[5,i+1]:= Daten[i+y].bemerkung;
    stringgrid1.Cells[6,i+1]:= Daten[i+y].raum;
  end;

  if AktuSeite = GesSeiten then
    AktuSeite := 0
  else
    AktuSeite:=AktuSeite+1;

 heute_d := LongDayNames[DayOfWeek(today)];

 Label5.Caption:='Vertretungsplan für den';
 Label6.Caption:=DateToStr(today)+' ('+heute_d+')';

 end
 else if PageControl1.TabIndex=1 then begin
  if aktuseitea = Gesseitena then
    counta := length(Daten2) mod 19
  else
    counta := 19;
  ya:= 19*AktuSeitea;

  stringgrid2.RowCount:=counta+1;
  for ia:=0 to counta-1 do begin
    stringgrid2.Cells[0,ia+1]:= Daten2[ia+ya].klasse;
    stringgrid2.Cells[1,ia+1]:= Daten2[ia+ya].stunde;
    stringgrid2.Cells[2,ia+1]:= Daten2[ia+ya].fuer;
    stringgrid2.Cells[3,ia+1]:= Daten2[ia+ya].wer;
    stringgrid2.Cells[4,ia+1]:= Daten2[ia+ya].fach;
    stringgrid2.Cells[5,ia+1]:= Daten2[ia+ya].bemerkung;
    stringgrid2.Cells[6,ia+1]:= Daten2[ia+ya].raum;
  end;

  if AktuSeitea = GesSeitena then
    AktuSeitea := 0
  else
    AktuSeitea:=AktuSeitea+1;

  morgen_d := LongDayNames[DayOfWeek(tomorrow)];

  Label5.Caption:='Vertretungsplan für den';
  Label6.Caption:=DateToStr(tomorrow)+' ('+morgen_d+')';

 end
 else if PageControl1.TabIndex=2 then begin
  Label5.Caption:='Meldungen';
  Label6.Caption:='';
 end;

 TimerReload.Interval:=ReloadTime;
 if PageControl1.TabIndex=0 then TimerNextTab.Interval:=ReloadTime*(GesSeiten+1)
 else if PageControl1.TabIndex=1 then TimerNextTab.Interval:=Reloadtime*(GesSeitena+1)
 else if Pagecontrol1.TabIndex=2 then TimerNextTab.Interval:=ReloadTime;
 TimerNextTab.Enabled:=True;
end;

DeddyH 28. Mai 2007 18:48

Re: Über Timer Stringlist 'weiterschalten'
 
Hallo, das sieht so aus, als ob Deine Queries die ganze Zeit über offen sind. Dadurch behalten sie natürlich ihre ursprüngliche Datenmenge. Mach mal am Anfang von GetData ein
Delphi-Quellcode:
Query1.Close;
Query2.Close;
Query1.Open;
Query2.Open;

Svenkan 28. Mai 2007 18:51

Re: Über Timer Stringlist 'weiterschalten'
 
Jetzt wird immer nur die erste Seite des jeweiligen Tages angezeigt (und zwar x Mal, je nachdem, wie viele Seiten es insg. gibt).
Aber immerhin werden die gezeigten Werte schonmal korrekt dargestellt (was ja daran liegt, dass der Timer zum Tabwechsel danach ausgelegt ist).

/edit: Es funktioniert! :) Hatte noch vergessen rauszunehmen, dassa dann autom. jedes Mal auf die Seite 0 schaltet. Dankeschön! :)


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