Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Proleme bei Locate (https://www.delphipraxis.net/170302-proleme-bei-locate.html)

Flash68 10. Sep 2012 13:59

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:
procedure TFRM_Main.edt_schnellsucheChange(Sender: TObject);
begin
   with dm_Buecher.ADS_Buecher do Locate('Titel', edt_schnellsuche.Text, [loCaseInsensitive, loPartialKey])
end;
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.

Kann mir jemand helfen was ich da falsch mache?

Gruß

Flash

mkinzler 10. Sep 2012 14:01

AW: Proleme bei Locate
 
Uses vollständig?

Flash68 10. Sep 2012 14:02

AW: Proleme bei Locate
 
hab ich auch schon gedacht und ausprobiert, nur nichts gefunden.

Flash68 10. Sep 2012 14:06

AW: Proleme bei Locate
 
war doch uses, db wurde gebraucht.

mkinzler 10. Sep 2012 14:06

AW: Proleme bei Locate
 
Lass mal das with weg

Perlsau 10. Sep 2012 14:07

AW: Proleme bei Locate
 
Zitat:

Zitat von Flash68 (Beitrag 1182353)
hab ich auch schon gedacht und ausprobiert, nur nichts gefunden.

Was genau hast du ausprobiert?

Flash68 10. Sep 2012 14:11

AW: Proleme bei Locate
 
hab es gefunden, uses DB wurde benötigt.

Danke nochmal.

himitsu 10. Sep 2012 14:29

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:
procedure TFRM_Main.edt_schnellsucheChange(Sender: TObject);
begin
  dm_Buecher.ADS_Buecher.Locate('Titel', edt_schnellsuche.Text, [loCaseInsensitive, loPartialKey]);
end;
Und die Aussage, daß man Locate zum Suchen in Datenbanken benutzt, ist ebenfalls falsch, denn man sucht damit nur im Dataset.
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)

p80286 10. Sep 2012 15:26

AW: Proleme bei Locate
 
Zitat:

Zitat von himitsu (Beitrag 1182365)

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)

da fehlt noch ein vor bzw ein Nachsatz:
was ich kenne habe ich alles versucht
ich habe alles versucht was mir bekannt ist

Gruß
K-H

Furtbichler 10. Sep 2012 22:38

AW: Proleme bei Locate
 
Zitat:

Zitat von himitsu (Beitrag 1182365)
Und es wurde ja schon erwähnt, aber WITH ist hier vollkommener Schwachsinn überflüssig und nutzlos.

Quatsch, es ist hier vollkommen legal, sinnvoll und nützlich. Es spart ein paar Zeichen beim Tippen und macht den Code leserlicher. Ein wenig jedenfalls. Und auch nur, wenn man weiß, wie WITH funktioniert, d.h. wenn man Ahnung hat ;-)

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.

himitsu 10. Sep 2012 22:42

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:
with ... do
anstatt einem
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

mkinzler 11. Sep 2012 05:36

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.

Furtbichler 11. Sep 2012 07:22

AW: Proleme bei Locate
 
Ja das wissen wir ja alles.

Zitat:

Zitat von mkinzler (Beitrag 1182416)
..Dies ist bei XE2 passiert und hat bei Einigen zu massiven Problemen geführt.

Das ist *NICHTS* im Vergleich zum Wechsel des Datentyps 'String' von Ansi auf Wide. Und ist 'String' deshalb nutzlos, böse und falsch? ;-)

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:
a := MyLongObjectName.TheComplicatedProperty.AndThisIsComplex;
a.Value := a.Strings.IndexOf(a.Text);
Ach, und das mir keiner kommt und sagt:"Büschen viel Wind um Nichts". :mrgreen:

mkinzler 11. Sep 2012 07:29

AW: Proleme bei Locate
 
Zitat:

Das ist *NICHTS* im Vergleich zum Wechsel des Datentyps 'String' von Ansi auf Wide. Und ist 'String' deshalb nutzlos, böse und falsch?
Damit hatte man aber nur Probleme, wenn man sich auf inoffizielle Implementierungsdetails verlassen hat. Beim "sauberen" Umgang mit Strings gab es keine Probleme.
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.

http://stackoverflow.com/questions/5...a-bad-practice

Flash68 11. Sep 2012 08:04

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;

mkinzler 11. Sep 2012 08:09

AW: Proleme bei Locate
 
Delphi-Quellcode:
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;
oder
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;

Flash68 11. Sep 2012 08:36

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:
DM_Buecher.ADS_Buecher.Column.Field.FieldName
anfangen

bei der zweiten kann er nichts mit

Delphi-Quellcode:
Column.Field.FieldName:
anfangen

mkinzler 11. Sep 2012 08:38

AW: Proleme bei Locate
 
Zu welcher Klasse gehören die beiden Eigenschaften?

himitsu 11. Sep 2012 08:47

AW: Proleme bei Locate
 
Delphi-Quellcode:
  with DM_Buecher.ADS_Buecher do
    if sort = Column.Field.FieldName then
      sort := Column.Field.FieldName + ' DESC'
    else
      sort := Column.Field.FieldName
Wenn alles* unterhalb des WITH zu der Klasse gehört, welche direkt im WITH gekapselt wurde, dann gibt es meistens keinerlei Probleme,
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:

Delphi-Quellcode:
with ... do
anstatt einem
Delphi-Quellcode:
.


Sir Rufo 11. Sep 2012 08:55

AW: Proleme bei Locate
 
Zitat:

Zitat von mkinzler (Beitrag 1182433)
Zu welcher Klasse gehören die beiden Eigenschaften?

Das sieht man doch ;)

Column ist ein Parameter der Methode und Sort ist eine Property von DM_Buecher.ADS_Buecher

himitsu 11. Sep 2012 08:59

AW: Proleme bei Locate
 
Zitat:

Zitat von Sir Rufo (Beitrag 1182436)
Das sieht man doch ;)

Sort könnte auch eine globale Variable sein, oder ein Feld/Property von TFRM_Main.
Und was mag wohl passieren, wenn ADS_Buecher auch ein Column besitzt, bzw. in Zukunft mal Eines bekommt?

Flash68 11. Sep 2012 09:43

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ß.

mkinzler 11. Sep 2012 09:49

AW: Proleme bei Locate
 
Zitat:

Zitat von Flash68 (Beitrag 1182447)
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ß.

Müssen nicht.

Jumpy 11. Sep 2012 09:51

AW: Proleme bei Locate
 
Zitat:

Zitat von Flash68 (Beitrag 1182447)
Ich denke mal das in dem Fall wohl das with bleiben muß.

Alles was mit with geht, muss ohne erst recht gehen. Diejenigen, die Beispiele genannt haben sind wohl davon ausgegangen, dass sort eine globale Variable ist. Um mal eines der Beispiele aufzugreifen:

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;

mkinzler 11. Sep 2012 09:56

AW: Proleme bei Locate
 
Wobei man
Delphi-Quellcode:
sort := DM_Buecher.ADS_Buecher.sort;
weglassen kann.

Flash68 11. Sep 2012 10:05

AW: Proleme bei Locate
 
da kommt er wieder nicht mit dem Column.Field.FieldName von

Delphi-Quellcode:
fieldname := DM_Buecher.ADS_Buecher.Column.Field.FieldName;
klar

himitsu 11. Sep 2012 10:08

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;

Flash68 11. Sep 2012 10:32

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.

himitsu 11. Sep 2012 11:00

AW: Proleme bei Locate
 
Das WITH kann man gerne noch rausmachen, wenn man will.
Delphi-Quellcode:
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;
Gut, ich hab hier noch einen Fehler drin, denn es müßte
Delphi-Quellcode:
Column.Field.Sort;
heißen und/oder man baut sich dieses auch noch für die TColumn.

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:
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
Das sind natürlich Vereinfachungen, welche man nur nutzten kann, wenn nur nur nach einem Feld sortiert, bzw. nur in Einem gesucht werden soll.

Medium 11. Sep 2012 11:28

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:
with TMyClass.Create do
begin
  try
    Property1 := Value1;
    Property2 := Value2;
    Property3 := Value3;
    Method1(Param1, Param2);
  finally
    Free;
  end;
end;
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.)

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.

mkinzler 11. Sep 2012 11:37

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;

Medium 11. Sep 2012 11:40

AW: Proleme bei Locate
 
Zitat:

Zitat von Medium (Beitrag 1182465)
Bei dem obigen bräuchte man eben eine Variable mehr. Kein Beinbruch, aber hier wäre es zumindest nicht mit einfachem Ausschreiben getan.

Schon klar.

Blup 11. Sep 2012 11:48

AW: Proleme bei Locate
 
Wenn schon, dann ordentlich:
Delphi-Quellcode:
mc: TMyClass;
{...}
  mc := nil;
  try
    mc := TMyClass.Create;
{...}
  finally
    mc.Free;
  end;
end;
oder:
Delphi-Quellcode:
mc: TMyClass;
{...}
  mc := TMyClass.Create;
  try
{...}
  finally
    mc.Free;
  end;
end;

himitsu 11. Sep 2012 11:54

AW: Proleme bei Locate
 
Zitat:

Zitat von mkinzler (Beitrag 1182468)
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;

Hier ist auch ein anderes Problem des WITH aufgefallen, denn beim Umbau fällt auf, daß der Scope vieles verschleift.
Und schwups, wurde beim Free etwas vergessen, was nun vermutlich gleich mal die ganze Form freigibt. :angle2:

PS:
Delphi-Quellcode:
try[enter]
kennen wohl Viele, wo dann ein try-finally-end draus wird, aber wer kennt z.B.
Delphi-Quellcode:
try[tab]
? (vorausgesetzt, das Delphi ist halbwegs aktuell [so um die 6 Jahre] und es ist keine Starter)

Delphi-Quellcode:
xxx := Tyyy.Create(Self);
try
   
finally
  xxx.Free;
end;
Und Delphi legt sogar von selbst die passende Variable an. :stupid:


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