![]() |
Delphi-Version: 10.4 Sydney
Prüfen ob ein Integerwert in einem ENUM existiert
Hallo zusammen,
habe da mal ein Frage zu Enums. Ich definiere ein Enum wie folgt:
Code:
Die Nummerierung mache ich deshalb so, weil dies den Spalten einer Tabelle entspricht, die ich sortieren möchte. type TOrderField = (ofBelegnummer=4, ofBelegdatum=6, ofKonto, ofKontoName, ofBank, ofZahldatum); var OrderField: TOrderField = ofBelegnummer; Beim Klick auf die Überschriften weise ich der Variablen OrderField die Spalte zu:
Code:
Im Nachgang wird die Tabelle neu gefüllt (aus einer Datenbank) mit einer entsprechenden Sortierung.
procedure TfrmMain.sgOPOSFixedCellClick(Sender: TObject; ACol, ARow: Integer);
begin if OrderField = TOrderField(ACol) then OrderASC := not OrderASC else OrderField := TOrderField(ACol); btnRefresh.Click; end; Das funktioniert prima, solange man auf eine Spalte klicke, die auch im Enum vorhanden ist. Ich würde jetzt gerne abfragen, ob denn die Spalte im Enum vorhanden ist. Irgendwie so:
Code:
Das funktioniert aber leider nicht...
if ACol IN TOrderField then
Hat von euch jemand eine Idee dazu? Schonmal herzlichen Dank Grüße P.S. Nein ich kann kein DBGrid verwenden, das die Sortierung von Haus aus kann... ;-) |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Du könntest vielleicht einen Helper dafür anlegen,
mal so hingeschrieben:
Delphi-Quellcode:
Wäre aber besser vor der Umwandlung zu Prüfen,
type
TOrderField = (ofBelegnummer=4, ofBelegdatum=6, ofKonto, ofKontoName, ofBank, ofZahldatum); TOrderField_Helper = record helper for TOrderField function Contains( const AValue : Integer ) : Boolean; end; ... function TOrderField_Helper.Contains( const AValue : Integer ) : Boolean; var LValue : TOrderField; begin LValue := TOrderField( AValue ); case LValue of TOrderField.ofBelegnummer, TOrderField.ofBelegdatum, TOrderField.ofKonto, TOrderField.ofKontoName, TOrderField.ofBank, TOrderField.ofZahldatum): Result := True; else Result := False; end; bin jetzt nicht sicher was passiert wenn AValue z.B. mit 100 reinkommt. Bin nicht am Rechner und kann es nicht checken ob das eine Exception wirft, aber eigentlich sollte es in den else-Zweig laufen. |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Du bist mit dem von Dir vorgeschlagenen Code schon auf dem richtigen Weg. Nur, dass Du Dir für den IN-Operator zusätzlich noch einen SET bauen (und bei Erweiterungen pflegen) musst:
Delphi-Quellcode:
OrderFieldSet: set of TOrderField = [ofBelegnummer, ofBelegdatum, ofKonto, ofKontoName, ofBank, ofZahldatum]
Jetzt kann eine FOR-Schleife von low( tOrderfield ) bis high( tOrderfield ) laufen und mit IN prüfen. Falls Start bei 0 gebraucht wird, muss noch ein Dummy mit Wert 0 eingefügt werden. |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Jupp, IN bringt bei einem ENUM nichts, da diese Variable wie ein Integer (alle ordinalen Typen) eh nur einen Wert haben kann. (dafür ist das = da)
Bei einem SET (je Wert ein Bit im Typen) oder Listen, da kann man schön auch mit IN arbeiten. (mit = dort ALLE Bits gleichzeitig vergleichen) In deinem Fall brauchst eher eine Konstante, wo du mit IN nachsehn kannst. Sobald auch nur ein Wert im SET mit einem Wert vordefiniert ist (=), werden die enthaltenen ENUMS nicht mehr in der RTTI gespeichert. Und man kann nicht nachsehen, ob es einen Wert darin gibt. (nur das High kann man noch benutzten) z.B.
Delphi-Quellcode:
oder
type
//TMyField = (of0, of1, of2, of3, ofBelegnummer, of5, ofBelegdatum, ofKonto, ofKontoName, ofBank, ofZahldatum); // hier könnte man auch via RTTI/TypInfo im Typ nachsehn, anstatt in einer Konstante/Variable TMyField = (ofBelegnummer=4, ofBelegdatum=6, ofKonto, ofKontoName, ofBank, ofZahldatum); TMyFields = set of TMyField; const MyOrderFields: TMyFields = [ofBelegnummer, ofBelegdatum, ofKonto, ofKontoName, ofBank, ofZahldatum]; if TOrderField(ACol) in MyOrderFields then
Delphi-Quellcode:
oder
const
ofBelegnummer = 4; ofBelegdatum = 6; ofKonto = 7; ofKontoName = 8; ofBank = 9; ofZahldatum = 10; type TMyFields = set of Byte; // oder auch nur = set of 0..10; const MyOrderFields: TMyFields = [ofBelegnummer, ofBelegdatum, ofKonto, ofKontoName, ofBank, ofZahldatum]; if ACol in MyOrderFields then ... Man kann sich auch einen Helper schreiben, welcher ... naja. Ich hatte mir mal vor Jahren das ![]()
Delphi-Quellcode:
type
TObjectHelper = class helper for TObject public function ClassIs(const ClassName: string): Boolean; overload; // entspricht dem IS ... prüft, ob die Klasse von der "namentlich" angegebenen Klasse abgeleitet wurde (TObject.IsClassName prüft nur, ob es genau die Klasse ist und beachtet auch kein NIL) function ClassIs(const ClassNames: array of string): Boolean; overload; function ClassIs(const ClassType: TClass): Boolean; overload; function ClassIs(const ClassTypes: array of TClass): Boolean; overload; function NameIs(const Objects: array of TObject): Boolean; overload; // Self in Objects function NameIs(const Names: array of string): Boolean; overload; // TComponent(Self).Name in Names // und noch bissl mehr Nützliches end; // ObjektZeiger vergleichen if Column.NameIs(ColBelegnummer, ColBelegdatum, ColKonto, ColKontoName, ColBank, ColZahldatum) then // Column.Name prüfen (case-insentitive) if Column.NameIs('ColBelegnummer', 'ColBelegdatum', 'ColKonto', 'ColKontoName', 'ColBank', 'ColZahldatum') then Aber denkbar wäre es inzwischen auch gut als Class Operator für IN :)
Delphi-Quellcode:
if Column in [ColBelegnummer, ColBelegdatum, ColKonto, ColKontoName, ColBank, ColZahldatum] then
|
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Ich hätte noch einen anderen Ansatz mit einem Helper, der nebenbei noch die Konstanten in der TOrderField-Definition eliminiert:
Delphi-Quellcode:
Verwendung dann so:
type
TOrderField = (ofNone, ofBelegnummer, ofBelegdatum, ofKonto, ofKontoName, ofBank, ofZahldatum); type TOrderFieldHelper = record helper for TOrderField private const cColumnMap: array [TOrderField] of Integer = (-1, 4, 6, 7, 8, 9, 10); public function GetColumn: Integer; procedure SetColumn(const Value: Integer); property Column: Integer read GetColumn write SetColumn; end; var OrderField: TOrderField = ofBelegnummer; ... function TOrderFieldHelper.GetColumn: Integer; begin Result := cColumnMap[Self]; end; procedure TOrderFieldHelper.SetColumn(const Value: Integer); var idx: TOrderField; begin for idx := Low(cColumnMap) to High(cColumnMap) do begin if cColumnMap[idx] = Value then begin Self := idx; Exit; end; end; Self := ofNone; end;
Delphi-Quellcode:
procedure TfrmMain.sgOPOSFixedCellClick(Sender: TObject; ACol, ARow: Integer);
begin if OrderField.Column = ACol then OrderASC := not OrderASC else OrderField.Column := ACol; btnRefresh.Click; end; |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Vielen Dank an alle für die vielen Antworten.
Ich schaue mir die Sache mit dem Helper mal genauer an, denn das sagt mir bislang nichts... Falls ich nicht weiter komme, werde ich mich nochmal melden! Besten Dank Frank |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Ich schon wieder...
Ich hab mir das Beispiel von Uwe Raabe angeschaut. Danke für den Hinweis mit dem Helper. Solch ein Hilfskonstrukt mit dem helper hatte ich bislang nicht gekannt. Allerdings bringt mich das mit meinem Problem nicht konkret weiter, denn ich will ja prüfen, ob die angeklickte Spalte im Enum vorhanden ist... Der ähnliche Ansatz mit einem helper von Rollo62 hingegen passt besser! Allerdings hatte ich die selbe Abfrage mit einem case of bereits im Click-Ereignis. Es funktioniert so, allerdings stört mich ein wenig, dass beim Ändern des Enums auch immer der restliche Code mitgeändert werden muss.. Eventuell setzte ich die Sache mit dem Set um, (wie das himitsu vorgeschlagen hat) denn da ist die Deklaration des Enums und des Sets zumindest an gleicher Stelle und es fällt auf, dass dort auch geändert werden muss. Also besten Dank für euere Antworten, hat mich auf jeden Fall weitergebracht... |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Class Helper und Record Helper sind einfach nur eine "nachträgliche" Erweiterung.
So kann man auch an Typen/Klassen direkt hilfreiche Methoden anhängen, anstatt sie als einzelfunktion irgendwo zu haben. z.B.
Delphi-Quellcode:
var
R1, R2: TRect; i: Integer; S := IntToStr(i); // Funktion S := i.ToString; // als Helper if EqualRect(R1, R2) then // Funktion if R1.Equal(R2) then // als RecordMethode ![]() ![]() Bzw. die Class Operator (in einem Class/Record Helper) können, die Operatoren für einen Typen erweitern ( := = <= >= < > <> + - * / div mod in shl shr ). |
AW: Prüfen ob ein Integerwert in einem ENUM existiert
Zitat:
Delphi-Quellcode:
das
OrderField.Column := ACol;
Delphi-Quellcode:
ist, dann ist das keine gültige Spalte. (Außer -1 wäre eine gültige Spalte)
OrderField = ofNone
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:19 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