TDBF Spaltenwerte abfragen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

TDBF Spaltenwerte abfragen

Beitrag von monta »

Ich bin gerade jenseits des geliebten SQLs am basteln mit dem TDBF Dataset.

Nun hab ich folgendes Problem, ich würde gerne in einem DBGrid eine Filterfunktion einbauen. Da das ja nicht direkt unterstützt wird, brauch ich also eine Liste der entsprechenden Werte, die in einer bestimmten Spalte vorkommen und kann dann daraus das entsprechende Filter-Attribut zusammenbasteln.

Aber, gibt es eine elegante Möglichkeit, alle Werte einer Spalte eines TDBFs als stringlist o.ä. zu erhlaten um dann die zum Filtern zur Verfügung stehenden Werte in eine ComboBox zu füllen?

Momentan geh ich ziemlich unelegant durch das DBF

Code: Alles auswählen

Liste := TStringList.Create;
    Liste.Sorted := true;
    Liste.Duplicates := dupIgnore;
    DBF.First;
    while not DBF.EOF do
    begin
      Liste.Add(DBF.FieldByName(Field).AsString);
      DBF.Next;
    end;
    IndexListe.AddStrings(Liste);
    Liste.Free;
Aber es muss da doch eigentlich einen eleganteren Weg geben (auch ohne SQL). :?:
Johannes

baba
Beiträge: 265
Registriert: Mi 4. Apr 2007, 17:47

Re: TDBF Spaltenwerte abfragen

Beitrag von baba »

Hallo Monta,

setz einfach einen Index drauf, hiervon kannst Du mehrere erstellen und diese mittels ORDER umschalten.

Bedenke aber, dass bei einem APPEND alle Indexdatein offen sein müssen. Wenn an einem Schlüsselfeld Änderungen durchgeführt werden, müssen auch die betreffenden Indexe offen sein - sonst kommt es zu undefinierbaren Ausgaben.

Gruß
Baba.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: TDBF Spaltenwerte abfragen

Beitrag von monta »

Aber ein Index filtert doch nicht, oder?

Wenn ich einen index setze, wird zwar die Spalte markiert. Aber wie soll ich es damit bspw. erreichen, das nur Einträge mit Vornamen 'monta' bspw. eangezeigt werden?
Konkret möchte ich eine ähnliche Funktion realisieren, wie in Excel/OO-Calc, wenn dort der Filter für eine Spalte aktiviert wird. Dann erscheint ja auch ein Dropdown-Feld, wo die verfügbaren Werte drin stehen. Aber an diese Liste mit Werten komm ich doch mit einem Index auch nicht, oder?
Bzw. ist es eventuell möglich einen Index komplett auszulesen um alle Werte auf einen Schlag zu erhalten?
Johannes

baba
Beiträge: 265
Registriert: Mi 4. Apr 2007, 17:47

Re: TDBF Spaltenwerte abfragen

Beitrag von baba »

monta hat geschrieben:Aber ein Index filtert doch nicht, oder?
Richtig!

Code: Alles auswählen

Index auf UpperCase(Name)
Suchen nach 'MO'
while Copy(FieldByName('NAME').AsString, 1, 2) = 'MO' then 
   ANZEIGEN
end;
Doppelte blendest Du mit der Option UNIQUE aus.

Du kannst auch einen Filter setzen, der wird aber bei größeren Dateien sehr langsam, da dieser die Daten sequenziell filtert - also erst vor der Abfrage prüft und ggfls. zum nächsten Satz springt.

Gruß
Baba.


//ERGÄNZT//

Stammt zwar aus Delphi, sollte aber auch bei Lazarus funktionieren:

Der Typ TIndexOptions beschreibt die Attribute eines Index.

Unit

Db

type
TIndexOption = (ixPrimary, ixUnique, ixDescending, ixCaseInsensitive, ixExpression, ixNonMaintained);
TIndexOptions = set of TIndexOption;

Beschreibung

TIndexOptions enthält eine Reihe von Attributen für einen bestimmten Index. Ein TIndexOptions-Wert kann keinen oder mehrere der folgenden Werte umfassen:

Wert Bedeutung

ixPrimary Der Index ist der Primärindex der Tabelle (gilt nicht für dBASE-Tabellen).
ixUnique Jeder Wert im Index ist eindeutig; es gibt keine Duplikate (gilt nicht für alle Tabellentypen).
ixDescending Der Index sortiert in absteigender Reihenfolge (gilt nicht für alle Tabellentypen).
ixExpression Der Index basiert auf einem dBASE-Schlüsselausdruck (gilt nur für dBASE-Tabellen).
ixCaseInsensitive Bei der Sortierung der Datensätze wird die Groß-/Kleinschreibung berücksichtigt (gilt nicht für alle Tabellentypen).

ixNonMaintained Der Index wird nicht automatisch aktualisiert, wenn Daten geändert werden (gilt nicht für alle Tabellentypen).

Achtung: Wenn Sie einen Index mit Optionen erzeugen, die für den verwendeten Tabellentyp nicht zulässig sind, löst AddIndex eine Exception aus.

Die oben aufgeführten Optionen werden nicht von allen Tabellentypen unterstützt. Zum Teil sind die Optionen auch nur für bestimmte Versionen eines Tabellentyps zulässig. Einzelheiten zu lokalen Tabellenebenen finden Sie in der Dokumentation der BDE-Verwaltung und des Datenbank-Explorers.

Primärindizes und echte eindeutige Indizes werden nur von dBASE-Tabellen ab Version 7 oder höher unterstützt (entsprechendes gilt für Visual dBASE 7). dBASE-Tabellen unterstützen weder absteigende Indizes noch Indizes, die nicht zwischen Groß- und Kleinschreibung unterscheiden. Verwenden Sie die Konstante ixExpression für Indizes, die auf mehreren Feldern basieren oder die dBASE-Sprachfunktionen zur Datenmanipulation verwenden (für Ausdrucksindizes). Die Konstante ixExpression ist nur bei dBASE-Tabellen wirksam.

Die Konstante ixDescending für Sekundärindizes wird nur von Paradox-Tabellen ab Version 7 und höher unterstützt. Die Konstante ixUnique ist nur für Paradox-Tabellen ab Version 5 und höher zulässig. Die Konstanten ixDescending und ixCaseInsensitive können nicht für Primärindizes verwendet werden.

Welche dieser Indexoptionen für andere Tabellentypen anwendbar sind, entnehmen Sie der Dokumentation des betreffenden Datenbankssystems.

shokwave
Beiträge: 475
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Re: TDBF Spaltenwerte abfragen

Beitrag von shokwave »

Hab zwar schon länger nix mehr mit TDBF gemacht, aber filten ging doch ungefähr so:

Code: Alles auswählen

TDBF1.Filter:='FELDNAME = "BEDINGUNG" ';
TDBF1.Filtered:=true;
mfg Ingo

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: TDBF Spaltenwerte abfragen

Beitrag von monta »

Ich glaube, ihr habt mich etwas falsch verstanden ;).

Es ging mir weniger darum, wie genau gefiltert wird, sondern darum, auf möglichst effizientem Wege eine Stringliste mit allen unterschiedlichen Werten einer einzelnen Spalte zu bekommen.

So wie im obigen Code mach ich es jetzt. Ich hab allerdings auch vergessen, das AfterScroll-Event des TDBF zu entfernen. Wenn das vorher ausgehangen wird, läuft der Code schon recht schnell durch.
Damit kann ich leben, für den Fall, das keiner eine schnellere Idee hat.
Johannes

baba
Beiträge: 265
Registriert: Mi 4. Apr 2007, 17:47

Re: TDBF Spaltenwerte abfragen

Beitrag von baba »

monta hat geschrieben:Ich glaube, ihr habt mich etwas falsch verstanden ;).
ne hatte ich schon verstanden. Leg einen Index mit der Option UNIQUE an und es sind keine doppelten Einträge mehr vorhanden, diese verbliebenen übernimmst Du in die Stringlist.

Alternativ gäbe es dann noch die TDBF.Table im Speicher. (Storage := stoMemory)

Baba.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: TDBF Spaltenwerte abfragen

Beitrag von monta »

Achso.

Da hab ich ja gleich die nächste Frage, wie lese ich den Index direkt aus?

(Irgendwie stell ich fest, das ich mehr "richtige" Datenbanken mit SQL bevorzuge.)
Johannes

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: TDBF Spaltenwerte abfragen

Beitrag von mse »

monta hat geschrieben:So wie im obigen Code mach ich es jetzt. Ich hab allerdings auch vergessen, das AfterScroll-Event des TDBF zu entfernen. Wenn das vorher ausgehangen wird, läuft der Code schon recht schnell durch.
DisableControls/EnableControls würde möglicherweise ebenfalls zur Beschleunigung beitragen. Zufälligerweise habe ich gerade letzthin den schnellen Datenzugriff über Arrayindex in die MSEgui DB Komponenten eingebaut, da ich das gleiche Bedürfnis hatte...

Martin
Zuletzt geändert von mse am Sa 25. Jul 2009, 10:21, insgesamt 1-mal geändert.

ralli
Beiträge: 374
Registriert: Mi 13. Sep 2006, 15:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Hagen a.T.W.
Kontaktdaten:

Re: TDBF Spaltenwerte abfragen

Beitrag von ralli »

Liest alle vorhandenen Indizes in eine ListBox ein.

Code: Alles auswählen

Datenbank.GetIndexNames(Indizes.Items)
Datenbank ist natürlich eine TDBF Kompo.
Pentium 4 - 2GB - Debian Lenny - Gnome 2.22.3 - Nvidia 8600 GT - FPC 2.2.2 - Lazarus 0.9.26 - GTK2

Antworten