strings einer combobox vergleichen
Hallo,
ich möchte hier nachdem ich die Datei eingelesen haben, die erste spalte der Tabelle zu einer combobox hinzufügen. Dies mache ich mit dem Befehl combobox.items.add(); aber ich möchte hier die mehrmals vorkommenden strings löschen, sodass ein string nur einmal vorkommt. Leider komme ich hier nicht weiter. ich wäre dankbar für die Hilfe:-D.
Code:
unit Datei;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls, Buttons, Grids, StdCtrls; type { TForm1 } TForm1 = class(TForm) schliess_knopf: TButton; einlesen_knopf: TButton; s_standortname: TComboBox; Label1: TLabel; oeffnen_knopf: TButton; ende_knopf: TBitBtn; fuss: TStatusBar; OpenDialog: TOpenDialog; etabelle: TStringGrid; procedure beenden(Sender: TObject); procedure einlesen(Sender: TObject); procedure FormShow(Sender: TObject); procedure schliessen(Sender: TObject); end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } var anzahl: integer; datei_name: string; datei: textfile; procedure TForm1.FormShow(Sender: TObject); begin datei_name:='d:\temp\windenergie01.csv'; with etabelle do begin Cells[1,0]:='Standort'; Cells[2,0]:='Windrad'; Cells[3,0]:='Nennleistung'; Cells[4,0]:='Datum'; Cells[5,0]:='Energiemenge'; end; // end; procedure TForm1.schliessen(Sender: TObject); begin // end; procedure TForm1.beenden(Sender: TObject); begin close; end; procedure TForm1.einlesen(Sender: TObject); var i,posi: integer; maxi,wert: double; buffer,eintrag,s1,s2,s3,s4,s5: string; ok: boolean; begin with opendialog do begin title:='Windenergie einlesen'; filename:=datei_name; initialdir:=extractfilepath(datei_name); filter:='Windenergieergebnisse (*.csv)|*.csv|alle Dateien (*.*)|*.*'; end; if opendialog.execute then begin datei_name:=opendialog.filename; assignfile(datei,datei_name); {$I-} reset(datei); readln(datei); i:=0; while not(eof(datei)) do begin inc(i); readln(datei,eintrag); //Suedkueste,ElCedro2,3.4MW,01.02.2017,4092kWh posi:=pos(',',eintrag); s1:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //ElCedro2,3.4MW,01.02.2017,4092kWh posi:=pos(',',eintrag); s2:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //3.4MW,01.02.2017,4092kWh posi:=pos(',',eintrag); s3:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //01.02.2017,4092kWh posi:=pos(',',eintrag); s4:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //4092kWh s5:=eintrag; // with etabelle do begin if i>=rowcount then rowcount:=rowcount+1; cells[1,i]:=s1; cells[2,i]:=s2; cells[3,i]:=s3; cells[4,i]:=s4; cells[5,i]:=s5; end; //standortname in combobox schreiben d1:=s1; s_standortname.Items.Add(etabelle.Cells[1,i]); //-- // end; closefile(datei); {$I+} ok:=(ioresult=0); //-- //-- end; end; //einlesen end. |
AW: strings einer combobox vergleichen
Moin,
wahrscheinlich gibt es 1000 bessere Lösungen aber wie wäre es damit
Delphi-Quellcode:
Das ist Pseudo-Code - also nicht kopieren, aber der Ansatz ist eine Idee :-)function NameBereitsVorhanden(const SuchString: String): Boolean; var i: integer; gefunden: Boolean; begin gefunden := false; for i := 0 to ETabelle.Count -1 do begin if SuchString := ETabelle:.String[i] then gefunden := true; end; Result := gefunden end; // with etabelle do begin if i>=rowcount then rowcount:=rowcount+1; cells[1,i]:=s1; cells[2,i]:=s2; cells[3,i]:=s3; cells[4,i]:=s4; cells[5,i]:=s5; end; //standortname in combobox schreiben d1:=s1; if not NameBereitsVorhanden(etabelle.Cells[1,i]) then s_standortname.Items.Add(etabelle.Cells[1,i]); gruß hans |
AW: strings einer combobox vergleichen
Delphi-Quellcode:
//standortname in combobox schreiben
d1:=s1; if s_standortname.Items.IndexOf(etabelle.Cells[1,i]) < 0 then begin s_standortname.Items.Add(etabelle.Cells[1,i]); end; |
AW: strings einer combobox vergleichen
Du schreibst, dass du die Einträge einzeln zu deiner Combobox hinzufügst. In diesem Fall könntest du eine Proc schreiben, welche überprüft, ob neuereintrag bereits in der Liste vorkommt oder nicht:
Delphi-Quellcode:
if combobox.Items.IndexOf( neuereintrag ) < 0 then
combobox.Items.Add( neuereintrag ); |
AW: strings einer combobox vergleichen
Hat die Combobox nicht sogar eine Eigenschaft, die man nutzen kann, dass sie keine Doubletten beinhaltet?
|
AW: strings einer combobox vergleichen
Kann sein, ich kenn's nur von TStringList - dort über .Duplicates := dupIgnore; aber nur (wieso dem so ist, weiss wohl nicht mal die Firma) wenn die Elemente sortiert sind, also .Sorted := true;
Also etwa so:
Delphi-Quellcode:
hs := TStringList.Create;
try hs.Sorted := true; hs.Duplicates := dupIgnore; hs.Text := combobox1.items.Text; combobox1.Items.Text := hs.Text; finally hs.Free; end; |
AW: strings einer combobox vergleichen
Das dachte ich zuerst auch. Sieht aber so aus, als gäbe es da nur TStringList.Duplicates. Da TComboBox.Items aber vom Typ TStrings ist, gibt's da offenbar kein simples Property, um Duplikate zu verhindern. Daher ist die Variante mit TComboBox.Items.IndexOf wohl ein einfacher Workaround. Oder man erweitert TComboBox mit einer Ableitung um eine Methode, die die Existenz eines Strings in der Liste prüft.
Grüße Dalai |
AW: strings einer combobox vergleichen
Ah. OK. Ich hatte nur im Hinterkopf, dass da was war.
Warum aber nicht erst alles in eine Stringliste packen und diese dann der Combobox zuweisen? |
AW: strings einer combobox vergleichen
Zitat:
Man landet also in beiden Fällen zur Suche nach Dubletten bei IndexOf. Dann kann man es auch direkt verwenden ;-) |
AW: strings einer combobox vergleichen
Lade die Liste erst mit dupIgnore in eine TStringsList und kopiere das Ergebnis dann EnBlock in die ComboBox.
Ist auch noch viel schneller als die Strings einzeln in die ComboBox zu bringen. |
AW: strings einer combobox vergleichen
Zitat:
Zitat:
|
AW: strings einer combobox vergleichen
Zitat:
Man kann auch mit zwei Stringlists arbeiten: Einer sortierten und einer unsortierten. Insert liefert -1 zurück, wenn der String beim Einfügen in eine sortierte Stringlist bereits existierte. In dem Fall fügt man ihn nicht in die unsoriterte ein. Und noch ein Hinweis zum Code in #6: Statt Text zuzuweisen kann man auch gleich die StringList auf Items zuweisen.
Delphi-Quellcode:
combobox1.Items := Text;
|
AW: strings einer combobox vergleichen
Zitat:
|
AW: strings einer combobox vergleichen
Zitat:
|
AW: strings einer combobox vergleichen
Zitat:
wie kann man die strings in der liste aufaddieren? denn die Liste läuft innerhalb einer while schleife und deshalb wird nur der letzte Eintrag zu der liste hinzugefügt.
Code:
stringlist:=TStringList.Create;
stringlist.Sorted:=true; stringlist.Duplicates:=dupIgnore; with stringlist do begin add(etabelle.cells[1,i]); end; with ListBox1 do begin items.Assign(stringlist); end; stringlist.free; |
AW: strings einer combobox vergleichen
Wo ist da eine while-Schleife in deinem Code?
Code:
Und lass das with-do bitte weg. Es erschwert das Debuggen und führt schnell zu schwer zufindeden Fehlern.
StringListe erzeugen
StringListe Eigenschaften setzen while() begin StringListe.Add(); end; StringListe Combobox zuweisen StringListe freigeben |
AW: strings einer combobox vergleichen
Zitat:
Code:
unit klausur011; //21.03.2019
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls, Buttons, Grids, StdCtrls; type { TForm1 } TForm1 = class(TForm) ComboBox1: TComboBox; Label4: TLabel; Label5: TLabel; Label6: TLabel; ListBox1: TListBox; M_menge: TLabel; Label2: TLabel; K_menge: TLabel; Label3: TLabel; sanzahl: TLabel; schliess_knopf: TButton; einlesen_knopf: TButton; Label1: TLabel; oeffnen_knopf: TButton; ende_knopf: TBitBtn; fuss: TStatusBar; OpenDialog: TOpenDialog; etabelle: TStringGrid; procedure beenden(Sender: TObject); procedure einlesen(Sender: TObject); procedure FormShow(Sender: TObject); procedure schliessen(Sender: TObject); end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } Type TFeld= array [0..1000] of string; var k:integer; datei_name: string; datei: textfile; element:TFeld; procedure TForm1.FormShow(Sender: TObject); begin datei_name:='d:\temp\windenergie01.csv'; with etabelle do begin Cells[1,0]:='Standort'; Cells[2,0]:='Windrad'; Cells[3,0]:='Nennleistung'; Cells[4,0]:='Datum'; Cells[5,0]:='Energiemenge'; end; // end; procedure TForm1.schliessen(Sender: TObject); begin // end; procedure TForm1.beenden(Sender: TObject); begin close; end; procedure TForm1.einlesen(Sender: TObject); var i,posi,anzahl: integer; wert,menge: double; buffer,eintrag,s1,s2,s3,s4,s5,s6,d1: string; stringlist:TStringList; ok:boolean; begin with opendialog do begin title:='Windenergie einlesen'; filename:=datei_name; initialdir:=extractfilepath(datei_name); filter:='Windenergieergebnisse (*.csv)|*.csv|alle Dateien (*.*)|*.*'; end; //------------------------------------------------------------------------------- if opendialog.execute then begin datei_name:=opendialog.filename; assignfile(datei,datei_name); {$I-} reset(datei); readln(datei); i:=0; menge:=0.0; anzahl:=0; while not(eof(datei)) do begin inc(i); readln(datei,eintrag); //Suedkueste,ElCedro2,3.4MW,01.02.2017,4092kWh posi:=pos(',',eintrag); s1:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //ElCedro2,3.4MW,01.02.2017,4092kWh posi:=pos(',',eintrag); s2:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //3.4MW,01.02.2017,4092kWh posi:=pos(',',eintrag); s3:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //01.02.2017,4092kWh posi:=pos(',',eintrag); s4:=copy(eintrag,1,posi-1); delete(eintrag,1,posi); //4092kWh s5:=eintrag; //Energiemenge berechnen in kWh posi:=Pos('k',s5); s6:=Copy(s5,1,posi-1); menge:=menge+strtofloat(s6); K_menge.Caption:=Floattostr(menge); //Energie menge in nWh wert:=menge/1000; M_menge.caption:=Floattostr(wert); //Tabellenausgabe with etabelle do begin if i>=rowcount then rowcount:=rowcount+1; cells[0,i]:=inttostr(i); cells[1,i]:=s1; element[i]:=s1; // in feld speichern cells[2,i]:=s2; cells[3,i]:=s3; cells[4,i]:=s4; cells[5,i]:=s5; end; //etabelle //standortname in combobox schreiben stringlist:=TStringList.Create; //stringlist.Sorted:=true; //stringlist.Duplicates:=dupIgnore; with stringlist do begin for i:=1 to anzahl do Add(element[i]); end; with combobox1 do begin Assign(stringlist); end; stringlist.free; //zeilenanzahl ermitteln inc(anzahl); sanzahl.caption:=inttostr(anzahl); //----------------------- fuss.Panels[0].Text:=datei_name; closefile(datei); {$I+} end; // hier ist die while schleife ok:=(ioresult=0); end; //opendlg end; // begin block end. |
AW: strings einer combobox vergleichen
Du erzeugst die StringListe ja jedes mal neu in der Schleife, wenn ich das richtig gesehen habe. Das kann ja nicht funktionieren, wie gewollt. Einmal vor der Schleife erzeugen und dann füllen.
Noch ein Tipp: Zerleg die Ellen lange Prozedur in mehrere kleinere. Das macht den Code übersichtlicher und leichter verständlich. |
AW: strings einer combobox vergleichen
Zitat:
angezeigt. |
AW: strings einer combobox vergleichen
Das wirst du selber programmieren müssen, indem du nach dem gewählten Eintrag der Combobox im Stringgrid suchst. Alle Zeilen durch gehen und mit pos vergleichen.
|
AW: strings einer combobox vergleichen
es hört sich schwer an :?
|
AW: strings einer combobox vergleichen
Nö. Soll nur in einer Spalte gesucht werden musst du ja nur die Zeilen durchgehen, dir den Inhalt der Spalte holen und mit dem gewählten Eintrag vergleichen. Wenn identisch, hast du die Zeile im StringGrid gefunden.
Soll in jeder Spalte gesucht werden, wird es etwas komplizierter, da du dann zwei verschachtelte Schleifen brauchst: Eine für die Zeilen und darin eine für die Spalten. Setz erst mal die erste Anforderung um: Der gesuchte Inhalt ist immer in der ersten Spalte.
Code:
SuchString := Combobox ausgewählt
for i := 0 to ZeilenStringGrid - 1 do begin sgString := Zeile[i,0] // oder so ähnlich. Habe jetzt die Syntax nicht im Kopf if SuchString = sgString // gefunden begin Zeile im StringGrid hervorheben break; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:34 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