![]() |
Proleme bei Locate
Hallo zusammen
ich benutze schon längere Zeit Locate für schnell suchen in Datenbanken und zwar in folgender Form:
Delphi-Quellcode:
jetzt habe ich mir das ganze kopiert und für ein Unterformular verwenden wollen und sagt er das die Parameter: loCaseInsensitive, loPartialKey unbekannte Bezeichner sind und es Inkompatible Typen bei TlocateOptions und Set gibt.
procedure TFRM_Main.edt_schnellsucheChange(Sender: TObject);
begin with dm_Buecher.ADS_Buecher do Locate('Titel', edt_schnellsuche.Text, [loCaseInsensitive, loPartialKey]) end; Kann mir jemand helfen was ich da falsch mache? Gruß Flash |
AW: Proleme bei Locate
Uses vollständig?
|
AW: Proleme bei Locate
hab ich auch schon gedacht und ausprobiert, nur nichts gefunden.
|
AW: Proleme bei Locate
war doch uses, db wurde gebraucht.
|
AW: Proleme bei Locate
Lass mal das with weg
|
AW: Proleme bei Locate
Zitat:
|
AW: Proleme bei Locate
hab es gefunden, uses DB wurde benötigt.
Danke nochmal. |
AW: Proleme bei Locate
Und es wurde ja schon erwähnt, aber WITH ist hier vollkommener Schwachsinn überflüssig und nutzlos.
Außerdem kann es nie schaden, wenn man abschließende ; verwendet. (vorallem wenn man Code gerne mal rumkopiert)
Delphi-Quellcode:
Und die Aussage, daß man Locate zum Suchen in Datenbanken benutzt, ist ebenfalls falsch, denn man sucht damit nur im Dataset.
procedure TFRM_Main.edt_schnellsucheChange(Sender: TObject);
begin dm_Buecher.ADS_Buecher.Locate('Titel', edt_schnellsuche.Text, [loCaseInsensitive, loPartialKey]); end; Die Daten im Dataset mögen vielleicht vorher aus einer Datenbank gekommen sein, aber man kann das Dataset auch ohne Datenbank benutzen. Und zum "ich hab alles versucht": Das glaub ich nicht, denn OH (F1) und CodeInsight hätten einem sofort die Lösung verraten. (CodeInsight in dem Code, wo es noch funktionierte) |
AW: Proleme bei Locate
Zitat:
was ich kenne habe ich alles versucht ich habe alles versucht was mir bekannt ist Gruß K-H |
AW: Proleme bei Locate
Zitat:
Wenn Du schon sagst, das es hier(!) nutzloser und überflüssiger Schwachsinn ist, dann erkläre bitte, warum. Das es allgemein gesehen zu unübersichtlichem Code führen kann, wenn man nicht versteht, wie WITH funktioniert, und beim Debuggen etwas hinderlich ist, steht auf einem anderen Blatt. |
AW: Proleme bei Locate
Ich bezog meine Aussage ausschließlich auf diesen Code und da ist es nutzlos und verbessert das Codeverständnis auch nicht wirklich.
(
Delphi-Quellcode:
anstatt einem
with ... do
Delphi-Quellcode:
)
.
Und wie du schon sagtest, ist es eher hinderlich. - keine Vorteile - unnötiger Code, welcher den Lesefluß eher behindert - beim Debuggen oftmals hinderlich = Vorteile 0 und Nachteile (mindestens) 3 |
AW: Proleme bei Locate
Das Problem mit with ist, dass es zu sehr komplexen schlecht identifizierbaren Fehlern führen kann, wenn die Eigenschaft/Methode des falschen Objektes aufgerufen wird. Das kann passieren wenn bei einem Update der VCL Klassen neue Eigenschaften/Methoden bekommen. Dies ist bei XE2 passiert und hat bei Einigen zu massiven Problemen geführt.
|
AW: Proleme bei Locate
Ja das wissen wir ja alles.
Zitat:
Wenn es jemand verwenden will, so wie ich z.B. seit 30 Jahren, und damit keine Probleme hat, erfolgreiche Projekte durchgezogen hat und die Haare immer noch gleichmäßig wachsen und es auch sonst mit der Verdauung, dem Privatleben, den Freunden, dem Beruf und überhaupt klappt, wieso ist das dann so schlecht? Es erleichtert das Lesen des Codes, wenn man es sinnvoll einsetzt(!). Ich kann mir nämlich Endloszeilen sparen. [DELPIH] MyLongObjectName.TheComplicatedProperty.AndThisIsC omplex.Value := MyLongObjectName.TheComplicatedProperty.AndThisIsC omplex.Strings.IndexOf(MyLongObjectName.TheComplic atedProperty.AndThisIsComplex.Text); [/DELPHI] Hat was. Künstlerisches. Irgendwie. [DELPIH] With MyLongObjectName.TheComplicatedProperty.AndThisIsC omplex Do Value := Strings.IndexOf(Text); [/DELPHI] Finde ich viel einfacher zu verstehen und funktioniert, da Tippfehler fast ausgeschlossen sind. Beim Lesen spare ich Zeit. Ich muss natürlich wissen, das 'Strings' und 'Text' zu 'AndThisIsComplex' gehören, aber ich lese Code ja nicht, um zu lernen, sondern um ihn zu verstehen. Klar, ein WITH über drei Seiten ist etwas dümmlich, aber das sind Methodenrümpfe auch (die zu lang sind). Es gibt immer Möglichkeiten, etwas Sinnvolles so anzuwenden, das es krank wird. Das ist mit 'WITH' so, aber auch mit GOTO, EXIT, BREAK, CONTINUE, WHILE, REPEAT usw. Also mit so ziemlich jedem Sprachkonstrukt. Ich schlage mich allerdings nicht darum, es benutzen zu dürfen, denn es geht auch ohne (z.B. mit einer Aliasvariablen)
Delphi-Quellcode:
Ach, und das mir keiner kommt und sagt:"Büschen viel Wind um Nichts". :mrgreen:
a := MyLongObjectName.TheComplicatedProperty.AndThisIsComplex;
a.Value := a.Strings.IndexOf(a.Text); |
AW: Proleme bei Locate
Zitat:
Bei with besteht nun mal die Gefahr, das es zu Scope-Verschiebungen kommt und deshalb würde ich darauf verzichten. Auf "offizieller" Seite sieht man das ja auch ähnlich. ![]() |
AW: Proleme bei Locate
Kann man dann auch sowas umarbeiten ohne with?
Delphi-Quellcode:
procedure TFRM_Main.DBG_BuecherTitleClick(Column: TColumn);
begin with DM_Buecher.ADS_Buecher do if sort = Column.Field.FieldName then sort := Column.Field.FieldName + ' DESC' else sort := Column.Field.FieldName end; |
AW: Proleme bei Locate
Delphi-Quellcode:
oder
procedure TFRM_Main.DBG_BuecherTitleClick(Column: TColumn);
begin if sort = DM_Buecher.ADS_Buecher.Column.Field.FieldName then sort := DM_Buecher.ADS_BuecherColumn.Field.FieldName + ' DESC' else sort := DM_Buecher.ADS_BuecherColumn.Field.FieldName end;
Delphi-Quellcode:
procedure TFRM_Main.DBG_BuecherTitleClick(Column: TColumn);
var fieldname: string; begin fieldname := DM_Buecher.ADS_Buecher.Column.Field.FieldName: if sort = fieldname then sort := fieldname + ' DESC' else sort := fieldname; end; |
AW: Proleme bei Locate
die funktionieren beide nicht so recht:
bei der ersten Variante kennt er das sort nicht und kann nichts mit
Delphi-Quellcode:
anfangen
DM_Buecher.ADS_Buecher.Column.Field.FieldName
bei der zweiten kann er nichts mit
Delphi-Quellcode:
anfangen
Column.Field.FieldName:
|
AW: Proleme bei Locate
Zu welcher Klasse gehören die beiden Eigenschaften?
|
AW: Proleme bei Locate
Delphi-Quellcode:
Wenn alles* unterhalb des WITH zu der Klasse gehört, welche direkt im WITH gekapselt wurde, dann gibt es meistens keinerlei Probleme,
with DM_Buecher.ADS_Buecher do
if sort = Column.Field.FieldName then sort := Column.Field.FieldName + ' DESC' else sort := Column.Field.FieldName aber wie man bei Umstellungen auf XE2, oder sonstigen Umstellungen oder Erweiterungen von Klassenstrukturen, gesehn hat, gibt es sofort Probleme, wenn sich z.B. Methoden/Property im Scope verschieben, bzw. wenn sich plötzlich Gleichnamiges dazwischenschiebt (im Scope auftaucht). *) Property, Methoden/Funktionen, Felder und (eingebettete) Typen und Konstanten WITH kann ein mächtiges Werkzeug sein, womit man sich Arbeit erspart, aber man sollte es nicht inflationär und mit vorallem mit Bedacht einsetzen. Und in dem hier vorliegendem Fall war es nunmal vollkommen nutzlos und brachte keinerlei Vorteile. Zitat:
|
AW: Proleme bei Locate
Zitat:
Column ist ein Parameter der Methode und Sort ist eine Property von DM_Buecher.ADS_Buecher |
AW: Proleme bei Locate
Zitat:
Und was mag wohl passieren, wenn ADS_Buecher auch ein Column besitzt, bzw. in Zukunft mal Eines bekommt? |
AW: Proleme bei Locate
Sir Rufio hat schon recht, das gehört alles zu dem DM_Buecher.ADS_Buecher
Damit wird die Tabelle sortiert. Ich denke mal das in dem Fall wohl das with bleiben muß. |
AW: Proleme bei Locate
Zitat:
|
AW: Proleme bei Locate
Zitat:
Delphi-Quellcode:
procedure TFRM_Main.DBG_BuecherTitleClick(Column: TColumn);
var sort, fieldname: string; begin fieldname := DM_Buecher.ADS_Buecher.Column.Field.FieldName; sort := DM_Buecher.ADS_Buecher.sort; if sort = fieldname then sort := fieldname + ' DESC' else sort := fieldname; DM_Buecher.ADS_Buecher.sort:=sort; end; |
AW: Proleme bei Locate
Wobei man
Delphi-Quellcode:
weglassen kann.
sort := DM_Buecher.ADS_Buecher.sort;
|
AW: Proleme bei Locate
da kommt er wieder nicht mit dem Column.Field.FieldName von
Delphi-Quellcode:
klar
fieldname := DM_Buecher.ADS_Buecher.Column.Field.FieldName;
|
AW: Proleme bei Locate
Delphi-Quellcode:
procedure TFRM_Main.DBG_BuecherTitleClick(Column: TColumn);
begin Column.Sort; end;
Delphi-Quellcode:
type
TFieldSortMode = (fsmAuto, fsmAsc, fsmDesc); TFieldHelper = class helper for TField ... procedure Sort(aSortMode: TFieldSortMode = fsmAuto); ... end; procedure TFieldHelper.Sort(SortMode: TFieldSortMode); begin with DataSet do if (aSortMode = fsmDesc) or ((aSortMode = fsmAuto) and (Sort = Self.FieldName)) then Sort := Self.FieldName + ' DESC' else Sort := Self.FieldName; end; |
AW: Proleme bei Locate
das sieht ja sehr kompliziert und aufwendig aus und es ist doch wieder ein with drin da könnte ich ja gleich mein altes behalten.
es sei denn man kann damit nach mehreren Spalten sortieren, nach einer lösung dafür bin ich auch noch auf der Suche. |
AW: Proleme bei Locate
Das WITH kann man gerne noch rausmachen, wenn man will.
Delphi-Quellcode:
Gut, ich hab hier noch einen Fehler drin, denn es müßte
procedure TFieldHelper.Sort(SortMode: TFieldSortMode);
begin if (aSortMode = fsmDesc) or ((aSortMode = fsmAuto) and (DataSet.Sort = FieldName)) then DataSet.Sort := FieldName + ' DESC' else DataSet.Sort := FieldName; end;
Delphi-Quellcode:
heißen und/oder man baut sich dieses auch noch für die TColumn.
Column.Field.Sort;
Nja, es ist nicht komplizierter, als der andere Code. Nur die Position des Codes ist halt eine andere. Man kann sich so ein paar öfters gebrauchte Funktionen schön an einer Stelle zusammenfassen, aber anders, als wenn man sie nur irgendwo als "alleinstehende" Prozedur ablegt, ist sie hier an alle Fields direkt angehangen und somit greift hier auch die Codevervollständigung einem hilfreich unter die Arme. Ich hab mir da z.B. noch eine kleine Locate mit abgelegt, also
Delphi-Quellcode:
Das sind natürlich Vereinfachungen, welche man nur nutzten kann, wenn nur nur nach einem Feld sortiert, bzw. nur in Einem gesucht werden soll.
Field.DataSet.Sort := Field.FieldName + ' DESC';
Field.DataSet.Locate(Field.FieldName, Value, [loCaseInsensitive]); Field.Sort(fsmDesc); Field.Locate(Value); // mit optionalem Parameter für TLocateOptions |
AW: Proleme bei Locate
Der einzige mir gerade in den Sinn kommende Fall, in dem man ein with nicht so einfach ersetzen kann, ist so etwas:
Delphi-Quellcode:
Das mache ich mit IniFiles ganz gerne so. Ansonsten ist with immer ersetzbar, indem man das was zwischen "with" und "do" steht (plus Punkt am Ende) vor alle Member in dem Block setzt. Bei dem obigen bräuchte man eben eine Variable mehr. Kein Beinbruch, aber hier wäre es zumindest nicht mit einfachem Ausschreiben getan. (Gilt für alle Fälle, in denen das with-Teil frische Instanzen oder Records zurückliefert, d.h. keine einfache Variable oder Referenz auf etwas schon bestehendes ist. Factory und so Dinge.)
with TMyClass.Create do
begin try Property1 := Value1; Property2 := Value2; Property3 := Value3; Method1(Param1, Param2); finally Free; end; end; Wenn man Komponenten im Code erzeugt kann das recht nett sein, ansonsten vermeide ich es aber auch nach Möglichkeit. Die Codevervollständigung befriedigt meinen Hang zur Schreibfaulheit ausreichend, und ich hab's dann lieber ganz ausführlich da stehen. (Ich denk mir meine sprechenden Bezeichner ja nicht aus, um sie nachher wieder durch sowas zu verklausulieren :mrgreen:) Mehrfach-Withs gehören allerdings wirklich verboten. Die tun in aller Regel einfach nur weh. |
AW: Proleme bei Locate
Auch das ist ersetzbar
Delphi-Quellcode:
mc: TMyClass;
.. try mc := TMyClass.Create; mc.Property1 := Value1; mc.Property2 := Value2; mc.Property3 := Value3; mc.Method1(Param1, Param2); finally Free; end; end; |
AW: Proleme bei Locate
Zitat:
|
AW: Proleme bei Locate
Wenn schon, dann ordentlich:
Delphi-Quellcode:
oder:
mc: TMyClass;
{...} mc := nil; try mc := TMyClass.Create; {...} finally mc.Free; end; end;
Delphi-Quellcode:
mc: TMyClass;
{...} mc := TMyClass.Create; try {...} finally mc.Free; end; end; |
AW: Proleme bei Locate
Zitat:
Und schwups, wurde beim Free etwas vergessen, was nun vermutlich gleich mal die ganze Form freigibt. :angle2: PS:
Delphi-Quellcode:
kennen wohl Viele, wo dann ein try-finally-end draus wird, aber wer kennt z.B.
try[enter]
Delphi-Quellcode:
? (vorausgesetzt, das Delphi ist halbwegs aktuell [so um die 6 Jahre] und es ist keine Starter)
try[tab]
Delphi-Quellcode:
Und Delphi legt sogar von selbst die passende Variable an. :stupid:
xxx := Tyyy.Create(Self);
try finally xxx.Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz