Autor |
Beitrag |
Tower
      
Beiträge: 99
|
Verfasst: Mi 02.04.03 11:26
Hallo!
Ich greife mittels dbExpress-Komponenten auf eine Interbase-DB zu, die leider einige CHAR-Felder enthält. Wenn ich jetzt zB mit einem DBEdit auf ein solches CHAR-Feld zugreife, wird die gesamte Länge immer mit Leerzeichen aufgefüllt!
Das ClientDataSet, das ich dazu benutze hat "DisableStringTrim" auf "False" gesetzt - was lt. Hilfe genau dieses Verhalten vermeiden sollte.
Tut's aber leider nicht. Muss ich da noch was anderes beachten? Bzw. kennt jemand eine sonstige Möglichkeit, das zu beheben?
Danke euch!
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 08.04.03 15:40
Hallo!
Kannst du denn die Felder auf DB-Ebene nicht einfach zu Varchar konvertieren?
Cu,
Udontknow
|
|
Luncustaf
      
Beiträge: 324
Win 2k
D7 Ent.
|
Verfasst: Di 08.04.03 15:42
ich weis net wie die express kompoenenten aufgebautsind aber probier mal mit
dbedit.text(?) := trim(charfeld);
so amche ich es zumindest immer wenn ich was trimmen muss - benutze aber auch sql also ich weis net inwiefern du auf die db zugreifst vlltwäre auch bisserl code net schlecht
gr€€tz
PS: weis aber net ob das geht
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Di 08.04.03 15:49
hi, ich arbeite auch mit IB-Express.
Wenn du die Felder mit ParamByName oder FieldByName einliest solltest du einfach so zuweisen:
Quelltext 1: 2:
| Variable := Trim(FieldByName('Datenbankfeld').AsValue); Variable := Trim(ParamByName('Datenbankfeld').AsValue); |
wobei AsValue auch AsInteger, AsBlob, AsString, etc. sein kann...
Achja, bevor ich es vergesse:
Die Trim-Funktion braucht die Sysutils - unit  Solltest du einbinden.
|
|
Tower 
      
Beiträge: 99
|
Verfasst: Mi 09.04.03 09:43
Das Problem ist, dass ich nicht (nur) Felder auslese und weiterverarbeite, sondern sie vor allem direkt editierbar machen will. Sprich: Ich habe mehrere DBEdit-Komponenten u.ä., dich ich über eine DataSource an die ClientDataSets angebunden habe (die wiederum über einen DataSetProvider an eine sqlDataSet-Komponente angebunden sind).
Im Grunde soll also der Anwender nur etwas eingeben können und es beim nächsten Mal genau so wieder vorfinden. Was er im Prinzip auch tut, nur dass die eingegebenen Strings halt plötzlich zig Leerzeichen hinten angehängt haben...
Insofern könnte die Trim-Lösung zwar funktionieren, wäre aber wegen der Menge der DBEdit-usw.-Felder ziemlich umständlich.
Und vor allem: da GIBT es schon diese verdammte DisableStringTrim-Property, dann soll die gefälligst auch ihren Job machen!!
@Udontknow: Ich bin nicht ganz sicher. WAHRSCHEINLICH könnte ich das sogar, aber da das Projekt schon sehr lange entwickelt wird, will und kann mir niemand die Garantie dafür geben, dass nicht irgendwelche versteckten kleinen Routinchen, die nur alle Jubeljahre mal aufgerufen werden, auch mit VarChar noch funktionieren...
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mi 09.04.03 09:58
naja, DBGrid-Komponenten und ähnliches benutze ich nicht. Ich schreib mir DB-Klassen zur Verwaltung der Tabellen und zeichne entweder meine Kompos selbst oder nehme Stringgrids. Hast du dir mal den Overhead für die DB angeschaut, den die DBGrid-Komponenten ner InterbaseDB senden? Naja, musst du wissen. Allerdings hab ich keine Ahnung was man mit den DBGrids da machen kann, weil die dich sowieso ziemlich einschränken.
Naja kommt auch auf die DB-Appliktion drauf an. Also wenn du Tabellen mit > 500 Datensätzen anzeigen willst dann würd ich dir IMAO das Datenmodul und die IBQueries empfehlen. Da kannst du trimmen soviel du willst und bist trotzdem extrem schnell. Wenn du von vornherein weißt wieviel Datensätze du hast, kannst du sogar die IBQueries ohne Overhead verwenden und bist noch schneller im Lesen, Schreiben und Ändern 
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mi 09.04.03 10:13
Eine weitere Möglichkeit wäre das Erstellen eines Ereignisses, das für sämtliche StringFelder aufgerufen wird. Im Endeffekt die Trim-Methode, nur nicht ganz so umständlich wie vermutet.
Ich gehe davon aus, dass ein Datenmodul vorhanden ist, indem alle Datasets liegen.
Quelltext 1: 2: 3: 4: 5:
| procedure TDatenModul.OnFieldGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin DisplayText:=True; Text:=Trim(Text); end; |
Dieses Ereignis muss in allen StringFeldern vorhanden sein. Das erreichst du durch folgenden Aufruf:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TDatenModul.ConfigureFields; var i,j:integer; var DS:TDataset; begin for i:=0 to ComponentCount-1 do if Components[i].InheritsFrom(TDataset) then begin DS:=TDataset(Components[i]); for j:=0 to DS.Fields.Count-1 do if DS.Fields[j].InheritsFrom(TStringField) then DS.Fields[j].OnGetText:=Self.OnFieldGetText; end; end; |
Cu,
Udontknow
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mi 09.04.03 10:19
@ShadowCaster:
Du bist der erste, der in diesem Thread über DBGrids spricht.  Es geht um das Trimmen, nicht um Performance. Wenn es tatsächlich so ein großes Projekt ist, wird er kaum die Musse haben, alles auf IBDatasets etc. umzustricken (wobei niemand einen davon abhält).
Cu,
Udontknow
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mi 09.04.03 11:12
Sorry... hab wohl den falschen Begriff genutzt. Ich meinte natürlich die Datasets nur bei mir läuft das alles unter dem Oberbegriff DBGrids und das läuft wiederum unter den Oberbegriffen: langsam, für große Anwendungen ineffizient, großer Overhead
Die Umstellung aufs Datenmodul ist in der Tat sehr aufwendig. Ich hab mir Klassen geschrieben, die die einzelnen Tabellen handeln aber dennoch braucht eine Klasse mit 5-10 Standartfunktionen gleich 200-300 Zeilen. Bei 10 Tabellen kann man sich ja ausmalen, wie viel das wird... Aber mittlerweile kann ich auf fertige Klassen zurückgreifen und muss nurnoch kopieren. So kann ich eine Datenbanktabelle mit allen Features in ner halben bis einer Stunde Arbeit voll ins Programm integrieren.
Zuletzt bearbeitet von ShadowCaster am Mi 09.04.03 13:16, insgesamt 1-mal bearbeitet
|
|
Tower 
      
Beiträge: 99
|
Verfasst: Mi 09.04.03 13:11
@Udontknow: Ja, das funktioniert perfekt, danke! Eine kleine Änderung war allerdings noch nötig:
Quelltext 1: 2: 3: 4: 5:
| procedure TDatenModul.OnFieldGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin // DisplayText := True - auskommentiert, weil: wird nicht verwendet Text:=Trim(Sender.AsString); end; |
PS: Kannst du (oder sonstjemand) in verständlichem Deutsch sagen, was der Unterschied zwischen "InheritsFrom" und dem "is"-Operator ist? Die Hilfe durchblicke ich da nicht so ganz...
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mi 09.04.03 13:25
Im Grunde genommen bezieht sich der is Operator auf das Objekt an sich, während die Methode InheritsFrom sich auf die zugrundeliegende Klasse des Objekts bezieht.
Beispiel:
Quelltext 1: 2: 3: 4:
| type TButtonNachfahre=class(TButton) end;
var MeinButton:TButtonNachfahre; |
"MeinButton is TButton" liefert dasselbe wie "MeinButton.InheritsFrom(TButton)". InheritsFrom kann aber auch folgendes:
Die Prüfung "TButtonNachfahre.InheritsFrom(TButton)" ist erlaubt, während "TButtonNachfahre is TButton" nicht erlaubt ist. Der is-Parameter ist für Objekte gedacht, ein Vergleich mit Klassen ist nicht möglich.
Ich habe es mir angewöhnt, einfach immer InheritsFrom zu benutzen.
Cu,
Udontknow
|
|