Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Arrays (https://www.delphipraxis.net/204046-arrays.html)

Jacob 18. Apr 2020 13:12

Delphi-Version: 10.3 Rio

Arrays
 
Hi,
ich arbeite momentan mit einer ListBox. Zu dieser habe ich eine Funktion geschrieben, die es mir erlaubt (erlauben sollte), Elemente zu löschen.
Im Hintergrund habe ich einen Array, der zum ListenIndex die Daten festhält.
Wird nun in der ListBox ein Element gelöscht, soll dieses ebenfalls (um später Probleme beim Speichern zu vermeiden) aus dem Array gelöscht werden.
Dazu verwende ich einen zweiten Array, der die Werte mit Auslassung des zu löschenden Elements aufnimmt.

-MyItems ist der Array, in dem die Daten gespeichert werden
-_object ist die ListBox
-_index ist der Index des ausgewählten Elements in der ListBox
Code:
var
  _array: TArray2;
  I1,I2,a: Integer;
begin

  a := 0;
  _array := MyItems;

  for I1 := 0 to _object.Items.Count do
  begin

    if I1 <> _index then
    begin

      for I2 := 0 to 8 do
      begin

        _array[a, I2] := MyItems[I1, I2]; //Hier wird mir der Fehler angezeigt: Zugriffsverletzung bei Adresse ...

      end;

      a := a + 1;
    end;

  end;

  MyItems := _array;
  _object.Items.Delete(_index);

  Result := _object;
An beschriebener Stelle bricht das Programm ab. Der Compiler zeigt so weit keine Fehler.
Wenn ihr Ideen habt, immer her damit.

Vielen Dank,
Jacob.

DieDolly 18. Apr 2020 13:28

AW: Arrays
 
Da du ja so oder so schon eine ObjectListe zu haben scheinst, wäre hier VirtualStringTree echt einfacher.
Wenn das richtig aufgebaut ist, brauchst du dich um die Löschung quasi nicht kümmern.

Das mit dem Array, oder den zwei Arrays, wird vorne und hinten nix.

Du solltest den Titel ändern.

zeras 18. Apr 2020 13:40

AW: Arrays
 
Zitat:

Zitat von Jacob (Beitrag 1462412)

for I1 := 0 to _object.Items.Count do
begin

Hier stimmt schon das Iterieren nicht. Du startest mit 0 (was ja auch OK ist), läufst aber bis "Count". Hier muss es "Count -1" heißen.

Aber die Infos oben sollten beschreiben, was besser gemacht werden kann.

himitsu 18. Apr 2020 15:08

AW: Arrays
 
Warum überhaupt sorum?

Die ListBox und auch andere ListenKomponenten, sowie TStringList, haben nicht umsonst eine Data/Object-Eigenschaft an den Items, wo man seine Daten verlinken/reintun kann, anstatt zu versuchen mehrere Listen synchron zu halten.

p80286 18. Apr 2020 21:54

AW: Arrays
 
a)Ich habe eine Liste, die /bzw. _Teile der Listendatensätze in einer .... angezeigt werden.
b)Tritt in der ... eine Löschanforderung für einen Datensatz auf, wird dieser Datensatz in der Liste gelöscht.
gehe zu a)

Gruß
K-H

scrat1979 18. Apr 2020 23:26

AW: Arrays
 
Ich würde - wie schon beschrieben - die Objekte der Liste direkt in der Listbox referenzieren und beim Löschen das (dann ja bekannte) Objekt aus der Liste löschen. Sollten mehrere Items in einem Durchgang gelöscht werden, nicht vergessen von „hinten nach vorne“ zu iterieren, da durch das Delete die Elemente verschoben werden und dann die Indizes sowie „Count“ nicht mehr passen.

himitsu 19. Apr 2020 00:02

AW: Arrays
 
Zitat:

Zitat von scrat1979 (Beitrag 1462437)
da durch das Delete die Elemente verschoben werden und dann die Indizes sowie „Count“ nicht mehr passen.

Ja, dass Count so nicht mehr passt, ist ein "merkliches" Problem,
aber wenn du löschst, wann wird da auch der nächste Eintrag übersprungen.

Wenn man sorum arbeitet, dann nehmen man eine der anderen Schleifen (z.B. WHILE)
und darf beim Löschen den Index nicht hochzählen, also Delete ODER Index+1.

scrat1979 19. Apr 2020 12:21

AW: Arrays
 
Zitat:

Zitat von himitsu (Beitrag 1462441)
Zitat:

Zitat von scrat1979 (Beitrag 1462437)
da durch das Delete die Elemente verschoben werden und dann die Indizes sowie „Count“ nicht mehr passen.

Ja, dass Count so nicht mehr passt, ist ein "merkliches" Problem,
aber wenn du löschst, wann wird da auch der nächste Eintrag übersprungen.

Wenn man sorum arbeitet, dann nehmen man eine der anderen Schleifen (z.B. WHILE)
und darf beim Löschen den Index nicht hochzählen, also Delete ODER Index+1.

Daher würde ich bei Löschaktionen in Listen immer von "Count-1" nach 0 durchiterieren. Zumindest habe ich das so "gelernt".

himitsu 19. Apr 2020 12:53

AW: Arrays
 
Jo, weil es mehrere Voreile hat.
  • weniger zu überlegen, in der einfacheren Schleife
  • beim FOR sogar mit einen schöneren ENDE .... immer "konstant" 0 (oder 1), statt einer Variable
    • das FOR cached sogar das Ende, also kopiert sich den Wert zu Begin in eine Varialbe, anstatt immer wieder die Funktion Count/Length/High zu verwenden
    • drum knallt es dann auch so schön, was gut ist, damit man die übersprungenen Einträge sofort bemerkt
    • und falls nur ein Eintrag gelöscht wird, dann merkt man auch sofort das vergessene BREAK
  • und in dem Array / der Liste muß bei "mehreren" Löschungen weniger Speicher kopiert werden, da hinten das Ende immer kürzer wird.


OK, bei verketteten Listen ist Reihenfolge egal, da geht man einfach der Kette entlang, wobei des hier in der Doppelkette vermutlich noch einfacher geht.


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