AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Listenelemente bedingt löschen

Ein Thema von Björn Ole · begonnen am 15. Okt 2009 · letzter Beitrag vom 16. Okt 2009
Antwort Antwort
Benutzerbild von Björn Ole
Björn Ole

Registriert seit: 10. Jul 2008
166 Beiträge
 
Delphi XE Professional
 
#1

Listenelemente bedingt löschen

  Alt 15. Okt 2009, 19:33
Nabend zusammen,


ich bräuchte mal ein ppar Optimierungsanstöße. Und zwar:

In meiner Anwendung befindet sich eine Liste mit Elementen.
Mit Hilfe einer procedure sollen nun entweder alle oder alle selektierten Elementen gelöscht werden.
Wird jedoch mit einem zu löschenden Element gerade gearbeitet (Thread im Hintergrund),
soll es übersprungen werden, es sei denn, der Benutzer will es trotzdem löschen.

Hier mal mein Ansatz.

Delphi-Quellcode:
procedure DeleteItems(AOnlySelected: boolean);
var
  i: integer;
  bIsBusy: boolean; // true, wenn Item gerade in Benutzung
  bDeleteAllBusy: boolean; // true, wenn der Benutzer Item trotzdem löschen will
  bCanDelete: boolean;
begin
  for i := Items.Count - 1 downto do
  begin
    bIsBusy := IsItemBusy(i){prüft, ob Item gerade vom Thread bearbeitet wird};
    if bIsBusy then
      bDeleteAllBusy := UserWantsToDeleteAllBusyItems{kümmert sich um UserAbfrage};

    if bIsBusy and (not bDeleteAllBusy) then
      Continue; // Item überspringen, da busy und Benutzer nicht löschen will

    bCanDelete := not (AOnlySelected and not Items[i].Selected);
    if bCanDelete then
      Delete(i);
  end;
end;
Mir kommt die Umsetzung von der Logik her viel zu aufgebläht und unschön vor.
Habt ihr einen besseren Weg?

Sehr sinnvoll wäre es zusätzlich noch, wenn die Benutzerabfrage nur einmal erscheinen würde, so nach dem Motto
"Zu löschende Elemente sind in Benutzung. Trotzdem alle (selektierten) löschen? Ja/Nein/Abbrechen"

Meine Birne qualmt allein schon von der Problembeschreibung...


Dankerli,
Björn
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.157 Beiträge
 
Delphi 12 Athens
 
#2

Re: Listenelemente bedingt löschen

  Alt 15. Okt 2009, 20:39
Hat sich Delphi eigentlich nicht wegen des bDeleteAllBusy beschwert,
welches bei (not bIsBusy) nicht initialisiert wird?

erste Zusammenfassung:
Delphi-Quellcode:
for i := Items.Count - 1 downto 0 do
begin
  if IsItemBusy(i) and not UserWantsToDeleteAllBusyItems then
    Continue;

  bCanDelete := not (AOnlySelected and not Items[i].Selected);
  if bCanDelete then
    Delete(i);
end;
zweite/weitere Zusammenfassung:
Delphi-Quellcode:
var
  i: integer;

begin
  for i := Items.Count - 1 downto 0 do
    if not (IsItemBusy(i) and not UserWantsToDeleteAllBusyItems)
        and not (AOnlySelected and not Items[i].Selected) then
      Delete(i);
end;
und mit der Userabfrage eventuell so
Delphi-Quellcode:
var
  i: integer;
  UWD, CalledUWD: boolean;

  function GetUWD;
  begin
    if not CalledUWD then
    begin
      UWD := UserWantsToDeleteAllBusyItems;
      CalledUWD := true;
    end;
    Result := UWD;
  end;

begin
  UWD := false;
  CalledUWD := false;
  for i := Items.Count - 1 downto 0 do
    if not (IsItemBusy(i) and not GetUWD)
        and not (AOnlySelected and not Items[i].Selected) then
      Delete(i);
end;

jetzt bleibt noch eine Frage: hat sich der himi da irgendwo vertan?


[edit]
OK, ein Fehlerchen in GetUWD war schonmal drinnen
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Björn Ole
Björn Ole

Registriert seit: 10. Jul 2008
166 Beiträge
 
Delphi XE Professional
 
#3

Re: Listenelemente bedingt löschen

  Alt 15. Okt 2009, 21:31
Danke für Deine so flotte Antwort.

Zitat von himitsu:
Hat sich Delphi eigentlich nicht wegen des bDeleteAllBusy beschwert,
welches bei (not bIsBusy) nicht initialisiert wird?
Ja, aber da bDeleteAllBusy nur gesetzt und ausgelesen wird, wenn bIsBusy = true ist, hab ich darauf erstmal keine Rücksicht genommen.


Es gibt (nur) noch zwei Ungereimtheiten bei deiner Version:

1) Die Userabfrage wird genau andersrum gewertet, d.h. klickt der User auf Ja (= trotzdem entfernen) wird aufgehört, bei Nein wird munter weitergelöscht.
Edit: Beim Klick auf Absenden kam mir der Geistesblitz, UWD := MessageBox({Weiterlöschen Ja/Nein?}) = ID_NO;

2) Wenn nur selektierte Einträge gelöscht werden sollen, wird trotzdem über das Löschen von nicht selektierten, jedoch in Arbeit befindlichen Einträgen gefragt.

Ich werd mich selbst auch mal versuchen, muss aber deinen, übrigens sehr viel hübscheren Code, erstmal vollständig verdauen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.157 Beiträge
 
Delphi 12 Athens
 
#4

Re: Listenelemente bedingt löschen

  Alt 15. Okt 2009, 21:53
Zitat von Björn Ole:
Edit: Beim Klick auf Absenden kam mir ...
war bei mir vorhin nicht anders

und wegen der Ungereimtheiten:
eigentlich/theoretisch sollte sich nichts verändert haben,
gegenüber deinem ursprünglichen Code


Ach ja, normaler Weise wird in Delphi nicht immer ALLES ausgewertet

if a or b then ist hier z.B. a = true, dann steht das Ergebnis schon fest
und b wird nicht mehr verarbeitet ... also wenn b eine Funktion ist, dann würde sie nicht aufgerufen.


gut, da war och ein Fehler, aber auf beiden Seiten
hab was falsch zusammengesetzt

und wenn ich das jetzt nochmal versuche,
Delphi-Quellcode:
bIsBusy := IsItemBusy(i);
if bIsBusy then
  bDeleteAllBusy := UserWantsToDeleteAllBusyItems;

if bIsBusy and (not bDeleteAllBusy) then
  Continue;

//bCanDelete := not (AOnlySelected and not Items[i].Selected);
//if bCanDelete then
// Delete(i);
Delphi-Quellcode:
bIsBusy := IsItemBusy(i);
DeleteAllBusy := bIsBusy and UserWantsToDeleteAllBusyItems;

if bIsBusy and (not bDeleteAllBusy) then
  Continue;
Delphi-Quellcode:
bIsBusy := IsItemBusy(i);

if bIsBusy and (not (bIsBusy and UserWantsToDeleteAllBusyItems)) then
  Continue;
Delphi-Quellcode:
bIsBusy := IsItemBusy(i);

if bIsBusy and not (bIsBusy and UserWantsToDeleteAllBusyItems) then
  Continue;
dann kommt auch ein Problem deiner Seits raus
bIsBusy and not bIsBusy kann ja wohl nicht gehn und würde immer FALSE ergeben


[add]
Delphi-Quellcode:
procedure DeleteItems(AOnlySelected: boolean);
var
  i: integer;
  UWD, CalledUWD: boolean;

  function GetUWD;
  begin
    if not CalledUWD then
    begin
      UWD := UserWantsToDeleteAllBusyItems;
      CalledUWD := true;
    end;
    Result := UWD;
  end;

begin
  for i := Items.Count - 1 downto 0 do
  begin
    if (not IsItemBusy(i) or UserWantsToDeleteAllBusyItems)
        and (not AOnlySelected or Items[i].Selected) then
      Delete(i);
  end;
end;
mal sehn, ob ich's jetzt kappiert hab
- nur löschen wenn nicht IsItemBusy oder der User will es doch
- und nur löschen wenn selektiert bzw. AOnlySelected=nein
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Björn Ole
Björn Ole

Registriert seit: 10. Jul 2008
166 Beiträge
 
Delphi XE Professional
 
#5

Re: Listenelemente bedingt löschen

  Alt 16. Okt 2009, 01:07
Ja Du hast recht, jetzt wo ich das so aufgebröselt sehe, fällt mir das auch auf...

Danke für deinen letzten Vorschlag.
Ein Fehlverhalten hat er noch, und zwar wenn ein Item selektiert ist, das gerade nicht bearbeitet wird,
dazu ein nicht selektiertes Item, was bearbeitet wird. Nun ein DeleteItems(true) und es kommt trotzdem eine Abfrage.

Problem lässt sich allerdings leicht beheben, nämlich einfach die beiden if Bedingungen vertauschen:

Delphi-Quellcode:
for i := Items.Count - 1 downto 0 do
  if (not AOnlySelected or Items[i].Selected)
    and (not IsItemBusy(i) or GetUWD) then
    Delete(i);
Jetzt läufts genau so wie ich mir das vorgestellt habe.
Vielen Dank himi!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz