Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - String mit einem Set(?) vergleichen


Darkpara - Fr 20.07.07 13:42
Titel: String mit einem Set(?) vergleichen
hiho,

habe wieder ma eine frage an euch! :D

und zwar:

Ich habe einen Type gemacht:


Delphi-Quelltext
1:
2:
3:
4:
type
  TCardType = (ST1PSD, ST1PDD,ST1X2_DE1,ST1X4_DE1,ST1X16_DE1,ST1Y2_TE2,
               ST1Y2_TPE3,ST1Y16_TE2,ST1Y16_TPE3,ST1Y2_R2,ST1X1616_DE1_S1,
               ST1Y32_TE2,ST1Y32_TPE3,ST1AD2_V,STAD2_I,ST1DA2_V,ST1DA1_I);

welchen ich als published anzeigen lasse (es handelt sich um einen komponenten)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
property    CardType: TCardType Read FCardType Write SetFCardTyp;
.
.
.
procedure TMitsuOPC.SetFCardTyp(o:TCardType);
begin
  if o <> FCardType then
  begin
    FCardType := o;
    Reference;
  end;
  AnalyseCard;
end;


nun erstelle ich diesen komponent dynamisch in einer anderen form und fülle anhand der mir gegebenen informationen also dem parameter TCardType aus, bzw würd ich gerne machen, genau hier ensteht das problem.


Delphi-Quelltext
1:
2:
3:
4:
5:
ACard           : array of TMitsuOPC;
.
.
.
ACard[n].CardType   := PIOsDef(LIOsDef.Items[n]).ModuleType;

in ACard habe ich meinen komponenten mit dem parameter CardType der den Type TCardType hat und auf der rechten seite habe ich die information des CardType aus einer Datenquelle welche jedoch im String format gespeichert ist.

Die frage ist nun gibt es eine möglichkeit einen String in einen "Set" (ka ob man das so nennt) komponenten um zuwandeln? also das ich dann den string mit TCardType vergleichen kann?

eine möglichkeit wäre ja ein Case zu basteln so in der art

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
case PIOsDef(LIOsDef.Items[n]).ModuleType of
'ST1PSD': ACard[n].CardType := ST1PSD;
'ST1PDD': ACard[n].CardType := ST1PDD;
'ST1X2_DE1': ACard[n].CardType := ST1X2_DE1;
.
.
.
ect


dies scheint mir jedoch ein bischen umständlich und man müsste das ganze abändern sollte sich etwas im TCardType ändern.

so hoffe ihr könnt mir weiter helfen besten dank imvoraus scho nur fürs lesen^^


Narses - Fr 20.07.07 14:20
Titel: Re: String mit einem Set(?) vergleichen
Moin!

Das hier:
user profile iconDarkpara hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
type
  TCardType = (ST1PSD, ST1PDD,ST1X2_DE1,ST1X4_DE1,ST1X16_DE1,ST1Y2_TE2,
               ST1Y2_TPE3,ST1Y16_TE2,ST1Y16_TPE3,ST1Y2_R2,ST1X1616_DE1_S1,
               ST1Y32_TE2,ST1Y32_TPE3,ST1AD2_V,STAD2_I,ST1DA2_V,ST1DA1_I);

nennt man Enumeration (=Aufzählungstyp, oder kurz: Enum). :idea: ;)

user profile iconDarkpara hat folgendes geschrieben:
eine möglichkeit wäre ja ein Case zu basteln so in der art

Delphi-Quelltext
1:
2:
3:
4:
5:
case PIOsDef(LIOsDef.Items[n]).ModuleType of
'ST1PSD': ACard[n].CardType := ST1PSD;
'ST1PDD': ACard[n].CardType := ST1PDD;
'ST1X2_DE1': ACard[n].CardType := ST1X2_DE1;
ect

dies scheint mir jedoch ein bischen umständlich und

...vor allem falsch ;) weil man bei case nur Ordinaltypen verwenden kann, keine Strings! :mahn:

user profile iconDarkpara hat folgendes geschrieben:
in ACard habe ich meinen komponenten mit dem parameter CardType der den Type TCardType hat und auf der rechten seite habe ich die information des CardType aus einer Datenquelle welche jedoch im String format gespeichert ist.

Die frage ist nun gibt es eine möglichkeit einen String in einen "Set" (ka ob man das so nennt) komponenten um zuwandeln? also das ich dann den string mit TCardType vergleichen kann?

Es gibt da IMO zwei Möglichkeiten:

a) Du deklarierst ein konstantes Konverter-Array:

Delphi-Quelltext
1:
2:
3:
4:
5:
const
  CardTypeStr: array[TCardType] of String = (
    "ST1PSD", "ST1PDD", "ST1X2_DE1", "ST1X4_DE1", "ST1X16_DE1", "ST1Y2_TE2",
    "ST1Y2_TPE3", "ST1Y16_TE2", "ST1Y16_TPE3", "ST1Y2_R2", "ST1X1616_DE1_S1",
    "ST1Y32_TE2", "ST1Y32_TPE3", "ST1AD2_V", "STAD2_I", "ST1DA2_V", "ST1DA1_I");

Dann kannst du über einen indizierten Zugriff vom Enum auf den String und über eine Schleife von String zu Enum. :idea: Kleiner Nachteil: du mußt auch das array pflegen, wenn du den Typ anpasst. :nixweiss:

b) Du verwendet die RTTI, das ist aber schon etwas schwerer: ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, TypInfo;

type
  TEnumTest = (
    etVal0 = 0,
    etVal1,
    etVal2
    );

  TForm1 = class(TForm)
    BtnListEnum: TButton;
    meEnumList: TMemo;
    edEnumStr: TEdit;
    BtnSearchEnum: TButton;
    procedure BtnListEnumClick(Sender: TObject);
    procedure BtnSearchEnumClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BtnListEnumClick(Sender: TObject);
  var
    i: TEnumTest;
begin
  meEnumList.Clear;
  for i := Low(TEnumTest) to High(TEnumTest) do
    meEnumList.Lines.Add(GetEnumName(TypeInfo(TEnumTest),Integer(i)));
end;

procedure TForm1.BtnSearchEnumClick(Sender: TObject);
begin
  meEnumList.Lines.Add(IntToStr(GetEnumValue(TypeInfo(TEnumTest),edEnumStr.Text)));
end;

end.

und hier noch das Formular:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
object Form1: TForm1
  Left = 212
  Top = 123
  Width = 256
  Height = 235
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  Position = poDesktopCenter
  PixelsPerInch = 96
  TextHeight = 13
  object BtnListEnum: TButton
    Left = 16
    Top = 8
    Width = 97
    Height = 25
    Caption = 'Enum ausgeben'
    TabOrder = 0
    OnClick = BtnListEnumClick
  end
  object meEnumList: TMemo
    Left = 16
    Top = 72
    Width = 217
    Height = 121
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
  object edEnumStr: TEdit
    Left = 120
    Top = 24
    Width = 113
    Height = 21
    TabOrder = 2
    Text = 'etVal1'
  end
  object BtnSearchEnum: TButton
    Left = 16
    Top = 40
    Width = 97
    Height = 25
    Caption = 'Wert suchen'
    TabOrder = 3
    OnClick = BtnSearchEnumClick
  end
end

cu
Narses


Darkpara - Fr 20.07.07 14:35

vielen dank für die schnelle antwort :)

da ich den nachteil der ersten methode umgehen will hab ich mich direkt der 2ten gewitmed

da treten jetzt aber weitere fragen auf..

dein

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
type
  TEnumTest = (
    etVal0 = 0,
    etVal1,
    etVal2
    );

wo mache ich das, in der form wo ich den komponenten erstelle oder direkt im komonenten drinne d.h. an der stelle wo mein alter TCardType war?


Narses - Fr 20.07.07 14:45

Moin!

user profile iconDarkpara hat folgendes geschrieben:
wo mache ich das, in der form wo ich den komponenten erstelle oder direkt im komonenten drinne d.h. an der stelle wo mein alter TCardType war?

Hä? :?!?: Wie, "in der Komponente drin"... :nixweiss:

Die Deklaration gehört in die Unit, in der auch die Komponente deklariert ist, und zwar logischerweise davor. Mit dem Instanziieren hat das nix zu tun. :mahn:

cu
Narses


Darkpara - Fr 20.07.07 14:54

hm also ich meinte das so:

ich hab ne Unit "A" in welcher ich einen Graphischen Komponenten "B" erstellt habe eine Art Bild+Led's
wenn ich nun in einer Unit "C" eine seite erstelle auf welcher ich den komponenten "B" einfügen möchte
muss ich dann deine änderungen in der unit A oder C vornehmen?


Narses - Fr 20.07.07 15:19

Moin!

user profile iconDarkpara hat folgendes geschrieben:
ich hab ne Unit "A" in welcher ich einen Graphischen Komponenten "B" erstellt habe

user profile iconNarses hat folgendes geschrieben:
Die Deklaration gehört in die Unit, in der auch die Komponente deklariert ist,

Wenn das für dich missverständlich klingt, dann ist die Variante a) vielleicht doch besser für dich geeignet. :?

cu
Narses


Darkpara - Fr 20.07.07 15:47

jo klingt es da es mein erster komponent ist^^ hab nun erstma variante 1 eingebaut, kcuke dann am ende wenns ums verbessern geht nochma wegen enum


BenBE - Fr 20.07.07 15:59

@Narses: Ganz falsch ist das mit den Strings in der Case nicht, bedarf aber 1. einer Compiler-Erweiterung (DLang Extension) und 2. einem zusätzlichen Schlüsselwort.

Außerdem ist deine Routinefür die Namensfindung IIRC nicht ganz korrekt:
Für den Fall:

Delphi-Quelltext
1:
TEnum = (a1 = 1, a2 = 2, a5 = 5);                    

liefert sie IMHO zwei zusätzliche, ungültige Einträge (3 und 4). Hab ich aber grad nicht getestet...