AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Einträge aus Datenbankfeld in Combobox
Thema durchsuchen
Ansicht
Themen-Optionen

Einträge aus Datenbankfeld in Combobox

Ein Thema von NoGAD · begonnen am 5. Feb 2021 · letzter Beitrag vom 11. Feb 2021
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#1

Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 20:38
Datenbank: ABS_Database • Version: 7.92 • Zugriff über: ABSTable/ABSQuery
Hallo,


in einer Tabelle habe ich ein Feld, welches ich als Wert einer Combobox zuweise.
Das passiert, weil vorhandene Werte bei Neueingaben zur Verfügung stehen sollen.

Nun dauert das ganze sehr lange, weil ich alle Einträge durchlaufe und zu einer Liste hinzufüge, die ich dann der jeweiligen Combobox zuweise.

Das ist mein Code dazu:

Delphi-Quellcode:
procedure TForm3.InitComboBox(Table_toInit: TABSTable);
var
  X: Integer;

  Dummy_String: string;
  Dummy_SL1, Dummy_SL2: TStringList;
  Dummy_SL_Regal, Dummy_SL_Fach: TStringList;
begin

  { Ersten Datensatz anwählen }
  Form_Bibo2.ABSTable1.First;
  { Listen initialisieren }
  Dummy_SL1 := TStringList.Create;
  Dummy_SL1.Sorted := True;
  Dummy_SL1.Duplicates := dupIgnore;

  Dummy_SL2 := TStringList.Create;
  Dummy_SL2.Sorted := True;
  Dummy_SL2.Duplicates := dupIgnore;

  Dummy_SL_Regal := TStringList.Create;
  Dummy_SL_Regal.Sorted := True;
  Dummy_SL_Regal.Duplicates := dupIgnore;

  Dummy_SL_Fach := TStringList.Create;
  Dummy_SL_Fach.Sorted := True;
  Dummy_SL_Fach.Duplicates := dupIgnore;

  for X := low(Const_Autors) to high(Const_Autors) do
    Dummy_SL1.Add(Const_Autors[X]);

  for X := low(Const_Publishers) to high(Const_Publishers) do
    Dummy_SL2.Add(Const_Publishers[X][1]);

  { Solange nicht das Tabellenende erreicht ist mache.. }
  while not Table_toInit.Eof do
  begin
    { Spalte einlesen Autor }
    Dummy_String := Trim(Table_toInit.FieldByName(Table_Bibo2.Labels_DB[1]).AsString);
    { Länge prüfen }
    if Length(Dummy_String) > 0 then
    begin
      { Zur Liste hinzufügen }
      Dummy_SL1.Add(Dummy_String);
    end;

    { Spalte einlesen Publisher }
    Dummy_String := Trim(Table_toInit.FieldByName(Table_Bibo2.Labels_DB[5]).AsString);
    { Länge prüfen }
    if Length(Dummy_String) > 0 then
    begin
      { Zur Liste hinzufügen }
      Dummy_SL2.Add(Dummy_String);
      { Breite des Eintrages an die ComBobox weitergeben }
    end;

    { Spalte einlesen Regal }
    Dummy_String := Trim(Table_toInit.FieldByName(Table_Bibo2.Labels_DB[10]).AsString);
    { Länge prüfen }
    if Length(Dummy_String) > 0 then
    begin
      { Zur Liste hinzufügen }
      Dummy_SL_Regal.Add(Dummy_String);
      { Breite des Eintrages an die ComBobox weitergeben }
    end;

    { Spalte einlesen Fach }
    Dummy_String := Trim(Table_toInit.FieldByName(Table_Bibo2.Labels_DB[11]).AsString);
    { Länge prüfen }
    if Length(Dummy_String) > 0 then
    begin
      { Zur Liste hinzufügen }
      Dummy_SL_Fach.Add(Dummy_String);
      { Breite des Eintrages an die ComBobox weitergeben }
    end;

    { Nächsten Datensatz anwählen }
    Table_toInit.Next;
  end;
  { .. und zurück zum ersten Datensatz }
  Table_toInit.First;

  { ComboBox-Inhalte nun zuweisen }
  ComboBox_AddBook_Author.Items.Assign(Dummy_SL1);
  ComboBox_AddBook_Publisher.Items.Assign(Dummy_SL2);
  ComboBox_AddBook_Regal.Items.Assign(Dummy_SL_Regal);
  ComboBox_AddBook_Fach.Items.Assign(Dummy_SL_Fach);
  { Listen aus dem Speicher entfernen }
  Dummy_SL1.Free;
  Dummy_SL2.Free;
  Dummy_SL_Regal.Free;
  Dummy_SL_Fach.Free;
end;
Habt ihr eine Idee, wie ich die ganze Sache beschleunigen kann und wenn, geht das per SQL Befehl?

LG Mathias
Mathias
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 20:45
Zitat:
Nun dauert das ganze sehr lange, weil ich alle ...
Ja und Nein,
es ist nicht nur deswegen.

Delphi-Referenz durchsuchenDisableControls



Und natürlich kannst du auch die jeweiligen Daten für jede ComboBox mit einer Abfrage von der DB holen, anstatt das aus diesem Dataset auszulesen,
inkl. Sortierung und Gruppierung bzw. Distinct (Doppeltes entfernen).

Autors und Publisher braucht man nur zu machen, wenn noch nichts in der ComboBox steht (beim ersten Mal), denn es ändert sich eh nie wieder (Konstante).
Und das sind nicht zufällig einfache statische oder dynamische String-Arrays?
Delphi-Quellcode:
ComboBox_AddBook_Author.Items.Clear;
ComboBox_AddBook_Author.Items.AddStrings(Const_Autors);

//bzw.
if ComboBox_AddBook_Author.Items.Count = 0 then
  ComboBox_AddBook_Author.Items.AddStrings(Const_Autors);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 5. Feb 2021 um 20:52 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 20:49
Hallo,
was ist denn das Ziel des ganzen?
Ich verstehe z.B. nicht, warum du das Sorted am Anfang machst und nicht zum Schluss.

Frage2: Wie viele Einträge haben denn die einzelnen ComboBoxen?

Frage3:
{ Ersten Datensatz anwählen }
Form_Bibo2.ABSTable1.First;
{ Solange nicht das Tabellenende erreicht ist mache.. }
while not Table_toInit.Eof do
{ .. und zurück zum ersten Datensatz }
Table_toInit.First;

Sind ganz andere Tabellen.
Heiko

Geändert von hoika ( 5. Feb 2021 um 21:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 21:17
Zitat:
Nun dauert das ganze sehr lange, weil ich alle ...
Ja und Nein,
es ist nicht nur deswegen.

Delphi-Referenz durchsuchenDisableControls



Und natürlich kannst du auch die jeweiligen Daten für jede ComboBox mit einer Abfrage von der DB holen, anstatt das aus diesem Dataset auszulesen,
inkl. Sortierung und Gruppierung bzw. Distinct (Doppeltes entfernen).

Autors und Publisher braucht man nur zu machen, wenn noch nichts in der ComboBox steht (beim ersten Mal), denn es ändert sich eh nie wieder (Konstante).
Und das sind nicht zufällig einfache statische oder dynamische String-Arrays?
Delphi-Quellcode:
ComboBox_AddBook_Author.Items.Clear;
ComboBox_AddBook_Author.Items.AddStrings(Const_Autors);

//bzw.
if ComboBox_AddBook_Author.Items.Count = 0 then
  ComboBox_AddBook_Author.Items.AddStrings(Const_Autors);

DisableControls kann ich leider nicht einsetzen, weil ich die Datenbank zum Beginn des Programmstarts auf Plausibilität prüfe. Hier Teste ich z.B. auch, ob es in der Datenbankstruktur Änderungen gab. Dazu muss ich auch die Tabelle einmal öffnen, um gelöschte Felder (Field) erkennen zu können.

Die Autoren sind als Array of String deklariert.

Const_Autors : array [ 1 .. 5889 ] of string = ( 'Autor 1', 'Autor 2' .... );

Bei der Verwendung von Deinem Code ergibt sich eine Fehlermeldung:
[dcc32 Fehler] Unit3.pas(212): E2250 Es gibt keine überladene Version von 'AddStrings', die man mit diesen Argumenten aufrufen kann
Mathias
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 21:21
Hallo,
was ist denn das Ziel des ganzen?
Ich verstehe z.B. nicht, warum du das Sorted am Anfang machst und nicht zum Schluss.

Frage2: Wie viele Einträge haben denn die einzelnen ComboBoxen?

Frage3:
{ Ersten Datensatz anwählen }
Form_Bibo2.ABSTable1.First;
{ Solange nicht das Tabellenende erreicht ist mache.. }
while not Table_toInit.Eof do
{ .. und zurück zum ersten Datensatz }
Table_toInit.First;

Sind ganz andere Tabellen.
Frage 1:
Ich bin kein Programmierer, mir fehlen viele Grundlagen. Sortet und dupignore hatte ich zum Anfang gestellt, weil ich hoffte, dass doppelte Einträge somit besser gefiltert werden.

Frage 2:
Const_Autors : array [ 1 .. 5889 ] of string = ('Autor 1', 'Autor 2', ... );

Hinzu kommen noch die Autoren aus der Datenbank, welche vom Benutzer hinzugefügt wurden.


Frage 3:
Danke, das war noch ein Flüchtigkeitsfehler, es waren dennoch die gleichen Tabellen.
Mathias
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 21:28
DisableControls hat doch nichts mit irgendwelchen Prüfungen zu tun?
Es hängt die GUI ab, damit diese nicht "sinnlos", beim Scrollen durch das DataSet, alles in die Edits lädt, was eh niemand sehen will.

Bei dupIgnore muß man Sorted=True machen, da die StringList sonst den Inhalt nicht schnell prüfen kann.
Auf die Semantik einer Datenbank bezogen macht mit Sorted=True das IndexOf einen IndexScan und mit False ein FullTableScan,
denn in einer sortierten Liste lässt sich schneller suchen.

Zitat:
Bei der Verwendung von Deinem Code ergibt sich eine Fehlermeldung
Welche Delphi-Version hast du?
Tipp: Das kann man hier im Profil angeben. (und in einigen Unterforen auch nochmal, falls die Frage mal abweichend vom Profil ist)

Delphi-Referenz durchsuchenTStrings.AddStrings
Mist, dachte das war als array of string und nicht als TArray<string> deklariert.
Dann geht es leider nur mit dynamischen Arrays.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 5. Feb 2021 um 21:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Einträge aus Datenbankfeld in Combobox

  Alt 5. Feb 2021, 21:47
DisableControls hat doch nichts mit irgendwelchen Prüfungen zu tun?

Bei dupIgnore muß man Sorted=True machen, da die StringList sonst den Inhalt nicht schnell prüfen kann.

Welche Delphi-Version hast du?
Tipp: Das kann man hier im Profil angeben. (und in einigen Unterforen auch nochmal, falls die Frage mal abweichend vom Profil ist)

Delphi-Referenz durchsuchenTStrings.AddStrings
Mist, dachte das war als array of string und nicht als TArray<string> deklariert.
Dann geht es leider nur mit dynamischen Arrays.
1. Also war es doch korrekt, sortet und dupignore vor der Zuweisung zu setzen?

2. Delphi 10.3 CE

3. array of string ist was anderes als TArray<string> ?

Die Schleife des Array wird schnell eingelesen.

Die Datenbankoperation dauert sehr lange. Da hätte ich mir gewünscht, eine schnellere Variante nutzen zu können.

LG Mathias
Mathias
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Einträge aus Datenbankfeld in Combobox

  Alt 6. Feb 2021, 04:42
Als "Typ" ist es das Gleiche (nur eine andere Notation),

aber als "Paramater" ist Ersteres ein "Open Array" und kein "Dynamic Array".

Also "Open Array" kann es praktisch jede Art von Array-Typ annehmen, sie die Format-Funktion, wo man auch direkt [irgendwas, anderes, hier] reingeben kann.
Und "Static Array" sind Jene, welche mit fester Größe definiert wurden.


Außerdem können en oder zwei Ressourcen-Schutzblöcke nie schaden. (try finally)

* TForm3 ist ein "blöder" Name.
* Wie bereits jemand sagte ist "Form_Bibo2.ABSTable1" die falsche Tabelle oder die falsche Variable (denn es gibt ja Table_toInit als Parameter).
* Zwischendrin ein paar alternative Schreibweisen. (siehe Kommentare)
* Ich weiß, es fehlen paar Leerzeichen. (Tipp: siehe [Zitat] unten rechts )
Delphi-Quellcode:
// ich weiß nicht seit wann, aber Array-Konstanten kann man nun auch ohne Längenangabe deklarieren
// und damit geht dann auch AddStrings.
const
  //Const_Autors: array[0..2] of string = ['a', 'b', 'c'];
  Const_Autors: TArray<string> = ['a', 'b', 'c'];
  Const_Publishers: array of array of string = [['d', 'g'], ['e', 'h'], ['f', 'i']];

procedure TForm3.InitComboBox(Table_toInit: TABSTable);
var
  TFAutor, TFPublisher, TFRegal, TFFach: TField;
  SLAutor, SLPublisher, SLRegal, SLFach: TStringList;
  i: Integer;
  S: string;
begin
  TFAutor := Table_toInit.FieldByName(Table_Bibo2.Labels_DB[1]); // nicht in jedem Schleifendurchlauf erneut das Field suchen
  TFPublisher := Table_toInit.FieldByName(Table_Bibo2.Labels_DB[5]);
  TFRegal := Table_toInit.FieldByName(Table_Bibo2.Labels_DB[10]);
  TFFach := Table_toInit.FieldByName(Table_Bibo2.Labels_DB[11]);

  SLAutor := TStringList.Create(dupIgnore, True, False);
  SLPublisher := TStringList.Create(dupIgnore, True, False);
  SLRegal := TStringList.Create(dupIgnore, True, False);
  SLFach := TStringList.Create(dupIgnore, True, False);
  Table_toInit.DisableControls; // GUI vorübergehend abhängen/deaktiveren, damit die nicht "sinnlos" bei jedem First/Next mitarbeitet.
  try
    {
    for S in Const_Autors do  // Einzeln übergeben, oder wie Nachfolgend als Eins
      SLAutor.Add(S);
    }

    SLAutor.AddStrings(Const_Autors);

    {
    // seit Delphi 2009?
    var Pub: array of string;  // der Unter-Typ von Const_Publishers[i] -> oben, VOR begin definiert
    for Pub in Const_Publishers do
      SLPublisher.Add(Pub[1]);

    // seit Delphi 10.4 nutzbar (war angelbich schon heimlich in 10.3 drin)
    for var Pub in Const_Publishers do
      SLPublisher.Add(Pub[1]);
    }

    for i := low(Const_Publishers) to high(Const_Publishers) do
      SLPublisher.Add(Const_Publishers[i][1]);

    {
    // DisableControls erst an der Schleife und nicht ins übergeordnete Try-Finally integriert
    Table_toInit.DisableControls;
    try
      Table_toInit.First;
      while not Table_toInit.Eof do begin
        ...
        Table_toInit.Next;
      end;
      Table_toInit.First;
    finally
      Table_toInit.EnableControls;
    end;
    }

    Table_toInit.First;
    while not Table_toInit.Eof do begin
      S := TFAutor.AsString.Trim;
      if S <> 'then
        SLAutor.Add(S);

      S := TFPublisher.AsString.Trim;
      if S <> 'then
        SLPublisher.Add(S);

      S := TFRegal.AsString.Trim;
      if S <> 'then
        SLRegal.Add(S);

      S := TFFach.AsString.Trim;
      if S <> 'then
        SLFach.Add(S);

      Table_toInit.Next;
    end;
    Table_toInit.First;
    {
    // Wozu überhaupt das Trim?
    // "falsche" Daten sind einfach "ungültig" ... gehört in den Daten behoben und nicht in der Anzeige
    Table_toInit.First;
    while not Table_toInit.Eof do begin
      if not TFAutor.IsEmpty    then SLAutor.Add    (TFAutor.AsString);
      if not TFPublisher.IsEmpty then SLPublisher.Add(TFPublisher.AsString);
      if not TFRegal.IsEmpty    then SLRegal.Add    (TFRegal.AsString);
      if not TFFach.IsEmpty      then SLFach.Add    (TFFach.AsString);
      Table_toInit.Next;
    end;
    Table_toInit.First;

    // Man könnte auch einfach "Alles" hinzufügen (ohne if-not-empty) und anschließend das '' wieder entfernen.
    //if SLAutor.Find('', i) then SLAutor.Delete(i);
    // und vorher in der Schleife bloß die SLAutor.Add(TFAutor.AsString); oder SLAutor.Add(TFAutor.AsString.Trim);
    }


    ComboBox_AddBook_Author.Items.Assign(SLAutor);
    ComboBox_AddBook_Publisher.Items.Assign(SLPublisher);
    ComboBox_AddBook_Regal.Items.Assign(SLRegal);
    ComboBox_AddBook_Fach.Items.Assign(SLFach);
  finally
    SLAutor.Free;
    SLPublisher.Free;
    SLRegal.Free;
    SLFach.Free;
    Table_toInit.EnableControls;
  end;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Feb 2021 um 04:57 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Einträge aus Datenbankfeld in Combobox

  Alt 6. Feb 2021, 09:40
Hallo,
weißt Du denn, wo genau das Performance-Problem ist?
Was sagt denn der Debugger?
Heiko

Geändert von hoika ( 6. Feb 2021 um 09:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Einträge aus Datenbankfeld in Combobox

  Alt 6. Feb 2021, 12:38
Hallo,
weißt Du denn, wo genau das Performance-Problem ist?
Was sagt denn der Debugger?
Wo das Problem genau ist, weiß ich leider noch nicht.

In der *dpr habe ich mittels GetTickCount jede Form-Erstellung gemessen. Komisch war hier immer, dass die Zeiten sehr gering waren.

Ich hänge heute Abend das Project mal an.
Mathias
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 10:00 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