Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Einträge aus Datenbankfeld in Combobox (https://www.delphipraxis.net/206884-eintraege-aus-datenbankfeld-combobox.html)

NoGAD 5. Feb 2021 19:38

Datenbank: ABS_Database • Version: 7.92 • Zugriff über: ABSTable/ABSQuery

Einträge aus Datenbankfeld in Combobox
 
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

himitsu 5. Feb 2021 19:45

AW: Einträge aus Datenbankfeld in Combobox
 
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);

hoika 5. Feb 2021 19:49

AW: Einträge aus Datenbankfeld in Combobox
 
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.

NoGAD 5. Feb 2021 20:17

AW: Einträge aus Datenbankfeld in Combobox
 
Zitat:

Zitat von himitsu (Beitrag 1482374)
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

NoGAD 5. Feb 2021 20:21

AW: Einträge aus Datenbankfeld in Combobox
 
Zitat:

Zitat von hoika (Beitrag 1482375)
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.

himitsu 5. Feb 2021 20:28

AW: Einträge aus Datenbankfeld in Combobox
 
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
Delphi-Quellcode:
array of string
und nicht als
Delphi-Quellcode:
TArray<string>
deklariert.
Dann geht es leider nur mit dynamischen Arrays. :cry:

NoGAD 5. Feb 2021 20:47

AW: Einträge aus Datenbankfeld in Combobox
 
Zitat:

Zitat von himitsu (Beitrag 1482380)
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
Delphi-Quellcode:
array of string
und nicht als
Delphi-Quellcode:
TArray<string>
deklariert.
Dann geht es leider nur mit dynamischen Arrays. :cry:

1. Also war es doch korrekt, sortet und dupignore vor der Zuweisung zu setzen?

2. Delphi 10.3 CE

3.
Delphi-Quellcode:
array of string
ist was anderes als
Delphi-Quellcode:
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

himitsu 6. Feb 2021 03:42

AW: Einträge aus Datenbankfeld in Combobox
 
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
Delphi-Quellcode:
[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 :wink:)
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;

hoika 6. Feb 2021 08:40

AW: Einträge aus Datenbankfeld in Combobox
 
Hallo,
weißt Du denn, wo genau das Performance-Problem ist?
Was sagt denn der Debugger?

NoGAD 6. Feb 2021 11:38

AW: Einträge aus Datenbankfeld in Combobox
 
Zitat:

Zitat von hoika (Beitrag 1482390)
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.

hoika 6. Feb 2021 11:55

AW: Einträge aus Datenbankfeld in Combobox
 
Hallo,
ohne die DB wird das aber nichts.

Schon mal durchdebuggt?
Klammere einfach mal alles aus und dann schrittweise wieder rein.

NoGAD 7. Feb 2021 11:10

AW: Einträge aus Datenbankfeld in Combobox
 
Dauert noch etwas, ich bin noch auf der Suche :-(

Danke erstmal.

LG :-)

himitsu 7. Feb 2021 11:27

AW: Einträge aus Datenbankfeld in Combobox
 
Bei Google suchenAQTime / Hier im Forum suchenAQTime und auch im GetIt zu finden
https://www.youtube.com/watch?v=OZzY_2JqdGY
https://www.youtube.com/watch?v=ZTBM8cIucEE
https://www.youtube.com/watch?v=WKQh-fiXpKI



Aber beachte, dass Messen das Gemessene auch etwas beeinflussen kann.
Ich hatte mal eine "winzige" oft durchlaufene Schleife, die in Real fast keine Zeit brauchte, aber beim Messen angeblich der Hauptverursacher war. (ein bissl nachdenken sollte man also dennoch)

NoGAD 8. Feb 2021 03:49

AW: Einträge aus Datenbankfeld in Combobox
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal ein Testprogramm erstellt.

Falls jemand von euch ABSDatabase einsetzt oder die Demo ausprobieren möchte, kann mir eventuell weiterhelfen.

In der Unit
Code:
Unit_ABS_Functions_01.pas
gibt es die Function
Code:
function Restructure_Table_Query(_Database_Construct: TABS_Construct; _Table_Construct: TTable_Construct): TABS_Function_Result;
Diese wird intern durch eine andere Function aufgerufen.

Bei einer größeren Datenbank (2000 +) dauert es unglaublich lange, bis die Tabelle restrukturiert wird.

Vielleicht fällt euch dazu noch was ein :-)

Nachtrag:

In der Unit
Code:
Unit_initialization_01
kann die Zeitmessung aktiviert werden:
Code:
_DebugTimeKeeper := true;


LG Mathias

hoika 8. Feb 2021 05:33

AW: Einträge aus Datenbankfeld in Combobox
 
Hallo,
was hat das jetzt mit dem Originalproblem zu tun?

hoika 8. Feb 2021 08:37

AW: Einträge aus Datenbankfeld in Combobox
 
Hallo,
ich habe mal kurz draufgeschaut.

1. Du mischst Tables und Queries (dort auch RequestLive=True?)
2. "WHERE 1 = 0" könnte ein Full Table Scan werden (wenn ADS nicht so gut optimiert)

Ich würde mal nachschauen, ob du bei ABS nicht an die Systemtabelle (Systemkatalog) rankommst. Dort stehen alle Tabellen/ Felder/ Feldtypen drin.
Dann musst du nicht durch irgendwelche Queries gehen, ob festzustellen, ob der Datentyp stimmt.

Da du ja jetzt weisst, dass die Methode langsam ist, Debugger anwerfen.

Frickler 8. Feb 2021 09:26

AW: Einträge aus Datenbankfeld in Combobox
 
Zitat:

Zitat von hoika (Beitrag 1482460)
Ich würde mal nachschauen, ob du bei ADS nicht an die Systemtabelle (Systemkatalog) rankommst. Dort stehen alle Tabellen/ Felder/ Feldtypen drin.
Dann musst du nicht durch irgendwelche Queries gehen, ob festzustellen, ob der Datentyp stimmt.

Da du ja jatzt weisst, dass die Methode langsam ist, Debugger anwerfen.

ABS, nicht ADS. ABS = "Absolute Database" ist eine reine ISAM-Datenbank mit aufgepfropftem SQL (so wie die BDE Paradox zu SQL verhalf). SQL ist da langsamer, als wenn man navigierend durch die Datenbank geht - es ist nur bequemer für komplexe Abfragen. Darum ist es wichtig, Indexe zu nutzen, und dann per SetRange durch die Daten zu gehen.

NoGAD 8. Feb 2021 17:01

AW: Einträge aus Datenbankfeld in Combobox
 
Danke. Ich teste mich mal durch.

LG Mathias. :-)

NoGAD 11. Feb 2021 16:10

AW: Einträge aus Datenbankfeld in Combobox
 
Zitat:

Zitat von Frickler (Beitrag 1482466)
SQL ist da langsamer, als wenn man navigierend durch die Datenbank geht ...


Da hat Frickler recht, ich habe Herrn Lysenko, der Inhaber/Entwickler der Datenbank, per E-Mail angefragt, ob es dazu eine schnellere Möglichkeit gibt.

Hier die Antwort:


Hello Mathias,

Thank you for your question.
Now each table could be modified several times (once for adding field, then for modifying field size, ...)
But ALTER table is very time-consuming operation if table is large.

You can speed up this procedure, if you will use
1 TABSTable.RestructureTable call for all table structure modifications (adding fields, change field size, ...)
See https://componentace.com/help/absdb_...ringtables.htm

Best regards,
Andrey Lysenko


Kleine Notiz am Ende, der Thread ist für mich auch abgeschlossen.

Nach viel Überlegung, ist mir bewusst geworden, dass es im Prinzip ja auch viel, viel einfacher wäre, wenn ich separate Tabellen für bestimmte Einträge anlege. Hier z.B. für Autoren und Verlage, ebenso für Bücherschränke/Zimmer, in denen die stehen/Regale/Fächer. Dann kann ich die schneller in eine Combobox einlesen, weil es im Prinzip nur einmal und nicht n-mal in einer Tabelle vorkommt. Oder eben gleich in eine DBCombobox.

Das Thema Datenbank ist für mich immer noch absolut abstrakt. Ich komme ständig an meine Grenzen der Lernbarkeit - weil ich es einfach nicht begreife.

Dafür ist mir letzte Nacht eine (aus meiner Sicht) tolle Idee eingefallen, wie ich unabhängig von einem Generalschlüssel eine Datenbankverschlüsselung erreichen kann, die dennoch mit einer Art Generalschlüssel versehen werden kann. Dazu mache ich einen separaten Thread auf, zu finden hier: https://www.delphipraxis.net/206951-...-masterkey.htm


LG Mathias :-)


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