Autor Beitrag
freedy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 403
Erhaltene Danke: 1

Winows 7
Delphi XE
BeitragVerfasst: Do 10.02.05 19:39 
Hallo Forum!

Mir war mal wieder langweilig und da dachte ich mir, dass meinem Programm noch ein letzter Schliff fehlt. :)

Nein, ganz im Ernst... es wird so gefordert.

Aber hier nun mein Problem. Ich habe eine Prodezur laufen, die einige Berechnungen mit sich bringt. Da möchte ich gerne dem Benutzer zeigen, wie lange er noch warten muss. Kennt man ja aus vielen Progs.

Hier mal mein (reduzierter) Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
procedure TableCreateClick;
var
  Index : Integer;
  Line : String;
  EstimatedTime : TDateTime;
  t1, t2 : TDateTime;
  TimeStr : String;
begin
  try
    Screen.Cursor := crHourGlass;

    // Zeit holen
    t1 := Time;

    for Index := 0 to Count - 1 do
    begin

      // Hier wird die Berechnung ausgeführt

      // wenn das Zeitintervall zu klein ist, rechnet er immer mit NULL 
      // deshalb nur jeden 50. Schritt berechnen.
      if ((Count - Index) Mod 50 = 0then
      begin
        t2 := Time;
        EstimatedTime := (Count - Index) * (t2 - t1);
        TimeStr := FormatDateTime('nn:ss', EstimatedTime);

        if Label6.Caption <> TimeStr then
          Label6.Caption := TimeStr;
        t1 := Time;
      end;
    end;

  finally
    Screen.Cursor := crDefault;
  end;
end;


Anstelle von sinnvollen Ausgaben auf meinem Label, werden ständig wechselnde Zeiten ausgegeben.

Hat jemand sowas schon einmal gemacht? Danke für eure Tips.

Gruß
freedy
Elite
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 10.02.05 19:44 
Für gewöhnlich wird vor Anfang der Berechnung überschlagen oder manchmal sogar genau berechnet, wie lange der Vorgang dauert, dann die Skala-Einteilung(TProgressBar) vorgenommen und in regelmäßigen Abständen während der Berechnung der Fortschritt aktualisiert.
freedy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 403
Erhaltene Danke: 1

Winows 7
Delphi XE
BeitragVerfasst: Do 10.02.05 20:05 
Hm... okay. Klingt erstmal einleuchtend. Eine Progressbar habe ich auch schon. Das klappt.

Ich würde aber gerne zeigen, wie lange der Vorgang noch dauert in Minuten/Sekunden.

Denn in knapp 15sec. gibt es auf der ProgressBar gerade mal 1%. Den Benutzer interessiert, ob er sich einen Kaffee kochen kann, oder nicht. :wink:

Gruß
freedy
patrick
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1481

WIN2k, WIN XP
D6 Personal, D2005 PE
BeitragVerfasst: Do 10.02.05 22:41 
damit hast du dir schon selbst die antwort gegeben:
alles was du machen musst ist folgendes:
wenn das programm für 1% 15 sekunden braucht, dann kannst du berechnen wie lange es für 100% brauchst.

_________________
Patrick
im zweifelsfall immer das richtige tun!!!
patrick
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1481

WIN2k, WIN XP
D6 Personal, D2005 PE
BeitragVerfasst: Do 10.02.05 23:34 
ich hab auf die schnelle dann mal eine entsprechende funktion erstellt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
{-----------------------------------------------------------------------------
  Procedure: CalcEstimateTime
  Version:   1.0.0.0
  Author:    Patrick || NetTraxX.de.vu
  Date:      10.02.2005 22:28:22
  Arguments: StartTime,CurrentTime,MaxProgress,CurrentProgress:integer
  Result:    single - Estimate time in seconds
  Purpose:   StartTime and CurrentTime have to be milliseconds
  Notes:
-----------------------------------------------------------------------------}

function CalcEstimateTime(StartTime,CurrentTime,MaxProgress,CurrentProgress:integer):single;
var DivTime,
    ProgressDiv:integer;
begin
  DivTime := CurrentTime - StartTime;
  ProgressDiv := (MaxProgress - CurrentProgress);
  result := (DivTime / CurrentProgress) * ProgressDiv / 1000;
end;


aufrufbeispiel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
var
  Form1: TForm1;
  GetStartTime: integer;
implementation

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetStartTime:=GetTickCount;
  Timer1.Enabled:=true;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var GetCurrentTime:integer;
begin
  ProgressBar1.StepIt;
  GetCurrentTime:=GetTickCount;
  Edit1.Text:=FloatToStr(CalcEstimateTime(GetStartTime,GetCurrentTime,progressbar1.Max,progressbar1.Position));
end;

_________________
Patrick
im zweifelsfall immer das richtige tun!!!
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Fr 11.02.05 15:14 
Das ganze bitte nicht bei CurrentProgress=0 aufrufen ;-)
patrick
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1481

WIN2k, WIN XP
D6 Personal, D2005 PE
BeitragVerfasst: Fr 11.02.05 18:03 
jo, kann man nachvollziehen ^^
ich hab meine "schlampige" version überarbeitet und ne sicherheitsabfrage eingebaut.
hier die version 1.0.1.0:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
{-----------------------------------------------------------------------------
  Procedure: CalcEstimateTime
  Version:   1.0.1.0
  Author:    Patrick || NetTraxX.de.vu
  Date:      10.02.2005 22:28:22
  Arguments: StartTime,CurrentTime,MaxProgress,CurrentProgress:integer
  Result:    single - Estimate time in seconds
                    - "-1" on error
  Purpose:   StartTime and CurrentTime have to be milliseconds
  Notes:
-----------------------------------------------------------------------------}

function CalcEstimateTime(StartTime,CurrentTime,MaxProgress,CurrentProgress:integer):single;
var DivTime,
    ProgressDiv:integer;
begin
  DivTime := CurrentTime - StartTime;
  ProgressDiv := (MaxProgress - CurrentProgress);

  if (DivTime >= 0and (ProgressDiv >= 0and (CurrentProgress > 0then
  begin
    result := (DivTime / CurrentProgress) * ProgressDiv / 1000;
  end
  else
  begin
    result:=-1;
  end;
end;

im fehlerfall wir als resultat -1 ausgegeben.
das kommt davon wenn man spät nachts ne 0815 programmierung hinrotzt :oops:

_________________
Patrick
im zweifelsfall immer das richtige tun!!!