AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Eintrag nur hinzufügen wenn nicht in Listview vorhanden

Eintrag nur hinzufügen wenn nicht in Listview vorhanden

Ein Thema von LordGinn · begonnen am 13. Okt 2014 · letzter Beitrag vom 21. Okt 2014
Antwort Antwort
Seite 2 von 3     12 3   
LordGinn

Registriert seit: 13. Okt 2014
16 Beiträge
 
FreePascal / Lazarus
 
#11

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 15. Okt 2014, 20:15
@cookie
Danke, ich habe das mit true und false geändert.
Den Code habe ich auch angepasst, doch gibt es ein kleines Problem. Wenn edit1.text nicht dem letzten Eintrag der Listview entspricht kommt die Meldung 'Eintrag bereits vorhanden' und wird aber trotzdem der Listview hinzugefügt mit der erfolgreichen Mitteilung. Wenn edit1.text dem letzten Eintrag entspricht funktioniert es perfekt.

@himitsu
Durchsuche ich nicht schon am Anfang die Liste?
Wie genau soll ich gefunden bzw nicht gefunden auswerten?
Mit IndexOf habe ich keinen Ansatz gefunden.
Ist das ein Problem, wenn ich es in Form2 lasse, läuft das Programm dann schlechter?

Delphi-Quellcode:
  procedure TForm2.Button1Click(Sender: TObject);
  var i: integer;
  begin

    if RadioButton1.checked
     then for i := 0 to Form1.Listview1.Items.Count - 1 do
       if not (form1.ListView1.Items[i].Caption<>edit1.text) then
               showmessage('Eintrag bereits vorhanden');
       if (form1.ListView1.Items[i].Caption<>edit1.text) then
       begin with
   form1.listview1.items.add do begin
   caption:=edit1.text;
   subitems.add(edit2.text);
   subitems.add(edit3.text);
   subitems.add(edit4.text);
   showmessage('Eintrag wurde hinzugefügt');
   end;
   end;
  Mit Zitat antworten Zitat
Benutzerbild von cookie22
cookie22

Registriert seit: 28. Jun 2006
Ort: Düsseldorf
936 Beiträge
 
Delphi XE2 Professional
 
#12

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 15. Okt 2014, 21:55
@cookie
Danke, ich habe das mit true und false geändert.
Den Code habe ich auch angepasst, doch gibt es ein kleines Problem. Wenn edit1.text nicht dem letzten Eintrag der Listview entspricht kommt die Meldung 'Eintrag bereits vorhanden' und wird aber trotzdem der Listview hinzugefügt mit der erfolgreichen Mitteilung. Wenn edit1.text dem letzten Eintrag entspricht funktioniert es perfekt.
...
Schau mal genauer hin. Hast du eventuell etwas vergessen?

Delphi-Quellcode:
if listview1.Items.IndexOf(DeinItem) = -1 then
...

Auf so etwas wollte himitsu hinaus.
Gruß
Cookie

Geändert von cookie22 (15. Okt 2014 um 21:58 Uhr)
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.736 Beiträge
 
Delphi 6 Enterprise
 
#13

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 16. Okt 2014, 08:17
Ich komm irgendwie mit deinen Einrückungen nicht klar und find die unübersichtlich, aber mMn fehlt da in der Version ein else-Zweig. Ausserdem ist es doch schöner, gewisse Dinge auszulagern, dann wird der Code übersichtlicher:

Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var i: integer;
begin
  if RadioButton1.checked then
    begin
    if EntryExistsInListView(edit1.text,Form1.Listview1) then
      showmessage('Eintrag bereits vorhanden')
    else if AddEntryToListView(edit1.text,Form1.Listview1) then
      showmessage('Eintrag wurde hinzugefügt')
    else
       showmessage('Eintrag war nicht vorhanden, konnte aber auch nicht hinzugefügt werden');
    end;
end;

function EntryExistsInListView(entry:String,LW:TListView):Boolean;
var i:integer;
begin
  Result:=false;
  for i := 0 to LW.Count - 1 do
    if LW.Items[i].Caption=entry then
      begin
      Result:=true;
      Break;
      end;

  //Könnte man dann ggf. ersetzen durch:
  //Result:=LW.Items.IndexOf(entry)>=0;
end;

function AddEntryToListView(entry:String,LW:TListView):Boolean;
begin
   Result:=true;
   LW.items.add
   LW.items[LW.Count-1].caption:=entry;
   //Muss man noch um diese Subentries aufbohren
   //und dafür sorgen, dass wenn irgendwas nicht klappt false als Result geliefert wird.
end;
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#14

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 16. Okt 2014, 09:39
Es ist grober Unfug die ListView für die Dublettenprüfung zu bemühen. Ist aber ein klassischer Anfängerfehler und habe ich zu meinen Anfangszeiten auch so gemacht, also keine falsche Scham.

Wie macht man es also richtig(er)?

Zunächst erstellt man sich eine Klasse, die die Daten selber aufnehmen kann
Delphi-Quellcode:
unit ModelData;

interface

type
  TDataModel = class
  private
    FVal1: string;
    FVal2: string;
    FVal3: string;
    FVal4: string;
  public
    constructor Create( const AVal1, AVal2, AVal3, AVal4: string );
    property Val1: string read FVal1;
    property Val2: string read FVal2;
    property Val3: string read FVal3;
    property Val4: string read FVal4;
  end;

implementation

{ TDataModel }

constructor TDataModel.Create( const AVal1, AVal2, AVal3, AVal4: string );
begin
  inherited Create;
  FVal1 := AVal1;
  FVal2 := AVal2;
  FVal3 := AVal3;
  FVal4 := AVal4;
end;

end.
Da ist nichts aufregendes dran.

Der Trick ist jetzt die Daten in einer Liste zu verwalten und diese Liste dann in der ListView zu präsentieren (anzeigen). Dadurch brauche ich jetzt nicht mehr die ListView irgendwie abzuklappern und mich auf den Kopf zu stellen, weil für die Anzeige die echten Daten irgendwie aufbereitet wurden, sondern ich vergleiche nur noch mit der einfachen Liste.

Das sieht dann z.B. so aus:
Delphi-Quellcode:
unit FormMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
  System.Generics.Collections, ModelData;

type
  TForm1 = class( TForm )
    ListView1: TListView;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    AddButton: TButton;
    procedure AddButtonClick( Sender: TObject );
  private
    FDataList: TList<TDataModel>;
    procedure PresentData;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

var
  Form1: TForm1;

implementation

uses
  System.Generics.Defaults;

{$R *.dfm}
{ TForm1 }

procedure TForm1.AddButtonClick( Sender: TObject );
var
  LItem: TDataModel;
begin
  // Aus den Eingaben eine Daten-Instanz erzeugen
  LItem := TDataModel.Create( Edit1.Text, Edit2.Text, Edit3.Text, Edit4.Text );
  try
    // Wenn es diese Daten-Instanz mit diesen Werten noch nicht gibt ...
    // (dank dem Comparer ist das ganz einfach zu prüfen)
    if not FDataList.Contains( LItem )
    then
      begin
        // ... dann fügen wir das in die Liste ein
        FDataList.Add( LItem );
        // setzen die Referenz auf NIL (siehe unten)
        LItem := nil;
        // präsentieren die neuen Daten
        PresentData;
      end;
  finally
    // Wenn LItem <> NIL, dann wird die Instanz zerstört
    LItem.Free;
  end;
end;

procedure TForm1.AfterConstruction;
begin
  inherited;

  FDataList := TObjectList<TDataModel>.Create(
    // Dieser Vergleicher (Comparer) kann die Daten in der Liste vergleichen
    // zum Sortieren, aber auch um mit Contains gleiche Instanzen zu finden
    TComparer<TDataModel>.Construct(
        function( const L, R: TDataModel ): Integer
    begin
      Result := CompareStr( L.Val1, R.Val1 );
      if Result = 0
      then
        Result := CompareStr( L.Val2, R.Val2 );
      if Result = 0
      then
        Result := CompareStr( L.Val3, R.Val3 );
      if Result = 0
      then
        Result := CompareStr( L.Val4, R.Val4 );
    end ), True );
end;

procedure TForm1.BeforeDestruction;
begin
  inherited;
  FDataList.Free;
end;

procedure TForm1.PresentData;
var
  LDataItem: TDataModel;
  LListItem: TListItem;
begin
  ListView1.Items.BeginUpdate;
  try
    // ListView leeren
    ListView1.Items.Clear;

    // durch alle Daten-Instanzen laufen
    for LDataItem in FDataList do
      begin
        // und in die ListeView eintragen
        LListItem := ListView1.Items.Add;

        LListItem.Caption := LDataItem.Val1;
        LListItem.SubItems.Add( LDataItem.Val2 );
        LListItem.SubItems.Add( LDataItem.Val3 );
        LListItem.SubItems.Add( LDataItem.Val4 );

        LListItem.Data := LDataItem;
      end;

  finally
    ListView1.Items.EndUpdate;
  end;
end;

end.
P.S. Da du keine Delphi-Version angegeben hast (Beitrag oder Profil) gehe ich davon aus, dass du schon eine neuere Version mit Generics und den Namespaces hast.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von cookie22
cookie22

Registriert seit: 28. Jun 2006
Ort: Düsseldorf
936 Beiträge
 
Delphi XE2 Professional
 
#15

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 16. Okt 2014, 10:55
Es ist grober Unfug die ListView für die Dublettenprüfung zu bemühen. Ist aber ein klassischer Anfängerfehler und habe ich zu meinen Anfangszeiten auch so gemacht, also keine falsche Scham.

Wie macht man es also richtig(er)?...
Anfängerfehler? Richtiger?

Er fragt das Ganze einmal ab in seinem Miniprojekt. Warum sollte man da eine eigene Klasse erstellen und 5x mehr Code produzieren?
Gruß
Cookie
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#16

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 16. Okt 2014, 12:17
Es ist grober Unfug die ListView für die Dublettenprüfung zu bemühen. Ist aber ein klassischer Anfängerfehler und habe ich zu meinen Anfangszeiten auch so gemacht, also keine falsche Scham.

Wie macht man es also richtig(er)?...
Anfängerfehler? Richtiger?

Er fragt das Ganze einmal ab in seinem Miniprojekt. Warum sollte man da eine eigene Klasse erstellen und 5x mehr Code produzieren?
Weil ...
  • es einfacher zu handhaben ist
  • er als Anfänger es auch gleich richtig lernen kann
  • er sich über diesen Weg die Anzeige basteln kann wie er möchte (ohne Rücksicht auf "oh, wie vergleiche ich denn jetzt")
  • die andere Vorgehensweise direkt mit der ListView sich wirklich nur für ein Miniprojekt eignet
  • viel Code nicht falsch ist (wenn er sich nicht wiederholt)
  • alle immer predigen Logik und Anzeige zu trennen (richtig) aber wenn es darauf ankommt dann doch nur Beispiele zeigen die das nicht beherzigen
  • ich eine Möglichkeit aufzeige Logik und Anzeige zu trennen (und auch nur in einer Schmalspur-Variante)
  • ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#17

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 16. Okt 2014, 12:24
Es ist grober Unfug die ListView für die Dublettenprüfung zu bemühen. Ist aber ein klassischer Anfängerfehler und habe ich zu meinen Anfangszeiten auch so gemacht, also keine falsche Scham.

Wie macht man es also richtig(er)?...
Anfängerfehler? Richtiger?

Er fragt das Ganze einmal ab in seinem Miniprojekt. Warum sollte man da eine eigene Klasse erstellen und 5x mehr Code produzieren?
Mmm, es kommt darauf an. Wenn es sich wirklich nur um 5 Zeilen handelt schein mir Sir Rufos Vorschlag auch Overkill zu sein. Wenn es aber mehr wird 50..500..5000 dann ist die Datenhaltung und -Verwalting in visuellen Komponenten wahrhaftig suboptimal.

(lösch mal leere Zeilen aus einem TMemo und mach das ganze mit einem eigenen Thread und Tstrings, das ist ein echter Aha-Effekt)

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
LordGinn

Registriert seit: 13. Okt 2014
16 Beiträge
 
FreePascal / Lazarus
 
#18

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 18. Okt 2014, 09:15
Danke an cookie22, Jumpy, Sir Rufo und p80286

Das mit dem IndexOf hat bei mir nicht funktioniert..

Ich werd versuchen eure Vorschläge zu verstehen, aber das wird ne Weile dauern.

Das mit dem Trennen von Daten und visueller Ansicht scheint mir sinnvoll zu sein. Ich werd mich dazu belesen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 18. Okt 2014, 09:23
  • Variable mit Startwert initialisieren (z.B. False oder -1)
  • Liste durchsuchen (deine For-Schleife)
  • bei Fund das Ergebnis merken (z.B. True oder die Schleifenposition, denn der Inhalt der Schleifenvariable ist außerrhalb der Schleife nicht mehr definiert)
  • die Suche entweder abbrechen (Break) oder weitersuchen
  • nach der Schleife das Ergebnis dann auswerten
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
LordGinn

Registriert seit: 13. Okt 2014
16 Beiträge
 
FreePascal / Lazarus
 
#20

AW: Eintrag nur hinzufügen wenn nicht in Listview vorhanden

  Alt 19. Okt 2014, 11:59
Danke himitsu

Ich habe jetzt die Radiobuttons entfernt und dafür auf der Form1 mehrere Buttons erstellt, das hat einiges vereinfacht.
Jetzt hat jede Listview einen eigenen Button fürs Hinzufügen und die Überprüfung funktioniert.

Ich muss dann nur noch herausfinden, wie man folgendes schreibt:
Wenn edit1.text und edit4.text in der selben Zeile der Listview auftauchen ist vorhanden true.

Delphi-Quellcode:
procedure TForm7.Button1Click(Sender: TObject);
var i: integer; vorhanden: boolean;
begin
   vorhanden:=false;
   for i := 0 to Form1.Listview2.Items.Count - 1 do
    if (form1.ListView2.Items[i].Caption=edit1.text) then vorhanden:=true;
    if vorhanden=true then showmessage('Eintrag ist bereits vorhanden');
    if vorhanden=false then
    begin with
    form1.listview2.items.add do begin
    caption:=edit1.text;
    subitems.add(edit2.text);
    subitems.add(edit3.text);
    subitems.add(edit4.text);
    showmessage('Eintrag wurde hinzugefügt');
    end;
    end;
end;
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 23:58 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