Programmierung

Fortschrittsanzeige

Bei Verarbeitungen die länger als ein paar Sekunden dauern, gehört es zum guten Ton, den Anwender über eine Fortschrittsanzeige über den aktuellen Status der Operation zu informieren.

In diesem Artikel stelle ich ein universelles Modul zur Steuerung einer Fortschrittsanzeige unter Verwendung des Progress-Objektes vor.

Das Modul SysPrg, das Sie am Ende des Artikels downloaden können basiert auf dem Paradigma der Modularen Programmierung und stellt eine definierte Schnittstelle zur Anzeige von Fortschrittsinformationen zur Verfügung.

Im einfachsten Fall werden nur drei Funktionen benötigt, um einen ansprechenden Dialog zur Visualisierung eines Fortschritts anzuzeigen:

// Anzahl Elemente
tCount # 500;

// Fortschrittanzeige starten
Prg.Start(tCount);

for   tCounter # 1;
loop  Inc (tCounter);
while (tCounter <= tCount)
{
  // Fortschritt aktualisieren
  if (Prg.Update(tCounter, 0, CnvAI(tCounter)) < 0)
    // Abbruch
    break;

  // Verarbeitung
  // ...
}

// Fortschrittsanzeige beenden
Prg.Stop();

Mit der Funktion Prg.Start() wird die Fortschrittsanzeige gestartet. Dabei wird die Anzahl der zu verarbeitenden Elemente übergeben. Anschließend wird innerhalb einer Schleife mit der Funktion Prg.Update() der Fortschritt aktualisiert. Hierfür wird das aktuelle Element und ein optionaler Elementtext übergeben. Am Ende der Verarbeitung wird die Anzeige durch die Funktion Prg.Stop() beendet.

Der dargestellte Dialog sieht so aus:

Neben dem Fortschrittsbalken, der den prozentualen Fortschritt der Verarbeitung anzeigt, wird auch das aktuelle Element, die Anzahl der bereits verarbeiteten Elemente, die geschätzte noch benötigte Zeit und die durchschnittliche Geschwindigkeit angezeigt.

Wird die dargestellte Abbrechen-Schaltfläche gedrückt, liefert die Funktion Prg.Update() einen negativen Wert zurück und die Verarbeitungsschleife wird abgebrochen.

Durch die Übergabe weiterer Argumente an die Funktion Prg.Start(), kann die Anzeige um einen Titel und eine Einheit ergänzt werden. Außerdem kann über Optionen gesteuert werden, ob der Elementtext und die Abbrechen-Schaltfläche angezeigt werden sollen:

Prg.Start(
  tCount, // Anzahl Elemente
  'Datenbank sichern', // Titel
  'MB', // Einheit
  0, // Aktualisierungsintervall [ms] (Standard: 1000)
  0.0, // Faktor (Standard: 1.0)
  _Prg.NoText | _Prg.NoStop // Optionen
);

Der dabei dargestellte Dialog sieht so aus:

Statt für die Fortschrittsanzeige einen eigenen Dialog zu starten, kann das Modul den Fortschritt auch in einem bereits sichtbaren Fenster anzeigen. Dazu müssen die Deskriptoren der anzusteuernden Oberflächenobjekte beim Aufruf der Funktion Prg.Start() übergeben werden:

with MyFrame
{
  Prg.Start(
    tCount, // Anzahl Elemente
    '', // Titel
    '', // Einheit
    0, // Aktualisierungsintervall [ms] (Standard: 1000)
    0.0, // Faktor (Standard: 1.0)
    0, // Optionen
    $:prgProgress, // Progress-Objekt
    0, // Label-Objekt für Elementtext
    $:lblProgress // Label-Objekt für Fortschrittsinformation
  );
}

Eine solche Fortschrittsanzeige könnte beispielsweise so aussehen:

Das Modul bietet noch weitere Möglichkeiten zur Konfiguration der Fortschrittsanzeige. Laden Sie sich die Ressourcen herunter und probieren Sie es doch einfach mal aus.

Download

Zum downloaden hier klicken SysPrg.zip (6.48 KB)
Sie müssen angemeldet sein, um die Datei herunterladen zu können.

2 Kommentare

2 Kommentare “Fortschrittsanzeige”

  1. Wenn die Ermittlung der genauen Anzahl der Elemente viel Zeit in Anspruch nimmt, genügt vielleicht ein Näherungswert, z.B. aus der Differenz zweier Datensatzpositionen berechnet.

    Wenn die zu zählenden Elemente nicht in den Integer-Zahlenraum passen, können Sie entweder mit einem Faktor arbeiten und z.B. nur jede 10000. Operation zählen oder das Modul auf BigInt erweitern.

    Der Einfluß auf das Zeitverhalten der Verarbeitung ist relativ gering. Die Oberfläche wird nicht bei jedem Schleifendurchlauf aktualisiert, sondern im Standardfall nur jede Sekunde.

    Testen Sie es doch einfach mal =)

  2. Die Herausforderung bei vielen Fortschrittsanzeigen liegt eher darin, die Gesamt-Anzahl zu ermitteln.
    Und für manche Anwendungen, das eine Int-Variable für die Gesamt-Anzahl nicht ausreicht.

    Eine weitere Frage wäre das Zeitverhalten der Prozedur bei sehr vielen Datensätzen im Vergleich zu einem Setzen eines Fortschritts-Bakens "zu Fuß"

Kommentar abgeben