Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - With + If


Sylvus - So 23.08.09 20:54
Titel: With + If
Hay Leute, ich hab ziemlich viel Code...dieser muss mehrmals ausgeführt werden.
Beim ersten Durchgang sehen die Sachen unegfähr so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
with abc do begin
lalala.acb[1]:=I+K;
lalala.acb[5]:=I+K;
lalala.acb[4]:=I+K;
lalala.acb[44]:=I+K;
end;


beim zweiten dann so


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
with DEF do begin
lalala.acb[1]:=I+K;
lalala.acb[5]:=I+K;
lalala.acb[4]:=I+K;
lalala.acb[44]:=I+K;
end;


Jetzt wollte ich das gerne zusammenfassen, aber ich kann den Bezeichner, der nach with kommt nicht als string deklarieren, sonst würd ich da ja eine variable hinsetzten und die bei jedem Durchgang ändern!
Jetzt hatte ich soetwas überlegt:

Delphi-Quelltext
1:
2:
3:
4:
if I=1 then   
  with Linien.LinienHorizontal1 do
else 
  with Linien.LinienHorizontal2 do

aber das geht natürlich nicht :P
Meine Frage, wie mach ich das jetzt am elegantesten, also auch mit wenig ressources, da das große ganze nen paar 1000x durchläuft... DANKE :)
Grüße Sylvus

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


jaenicke - So 23.08.09 21:29

Lass einfach das dämliche with weg und nimm ganz normal eine Zwischenvariable. ;-)

Aber genauso (mit Variable) geht es mit dem with auch. Aber da müsstest du schon sagen was da genau nicht funktioniert, sonst kann ich dazu nicht mehr sagen, normalerweise geht das problemlos. :nixweiss:


Sylvus - So 23.08.09 22:12

naja also ich hab ne Klasse und die will ich ja nicht immer mit davor schreiben!
Also wenn ich jetzt schreibe:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
a:string;

a:=MeineZuweisung1.Bla

with a do begin

...

end;

dann geht das nicht, weil a ein String ist :) Auf was müsste ich a da jetzt ändern?
Und ohne das with? Wie soll das gehen :)
Grüße Sylvus


//P.S.
Fehlermeldung sagt eigentlich alles:
[DCC Fehler] Unit2.pas(90): E2018 Record, Objekt oder Klassentyp erforderlich

also als was deklarier ich jetzt die variable? :D

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


jaenicke - So 23.08.09 22:16

Wenn es z.B. um ein Edit geht (du hättest ja einfach den konkreten Quelltext posten können...):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
  MyEdit: TEdit;
begin
  MyEdit := Edit1;
  with MyEdit do
  begin
    Text := '...';
  end;
Oder direkt:

Delphi-Quelltext
1:
2:
3:
4:
5:
var
  MyEdit: TEdit;
begin
  MyEdit := Edit1;
  MyEdit.Text := '...';
Oder als Prozedur:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure DoSomething(MyEdit: TEdit);
begin
  MyEdit.Text := '...';
end;

DoSomething(Edit1);
DoSomething(Edit2);
...
Dass im with kein String oder so stehen kann, ist ja klar, weil es ja dabei gerade darum geht auf eine Eigenschaft / Feld des angegebenen Objekts / Records zuzugreifen.


Sylvus - So 23.08.09 22:19

Naja Code ist nicht sauber aber ok:


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:
 temp:=Linien.LinienHorizontal1;
  for I := 1 to 2 do begin
   with temp  do
  begin
    if (current = Linien13[1]) or (current = Linien13[2]) or (current = Linien13[3]) then
    begin
      if Fertig1 then
        Fertig1 := Pruefe(Linien13, I, current);
    end;
    if (current = Linien14[1]) or (current = Linien14[2]) or (current = Linien14[3]) or (current = Linien14[4]) then
    begin
      if Fertig1 then
        Fertig1 := Pruefe(Linien14, I, current);
    end;
    if (current = Linien15[1]) or (current = Linien15[2]) or (current = Linien15[3]) or (current = Linien15[4])or (current = Linien15[5])then
    begin
      if Fertig1 then
        Fertig1 := Pruefe(Linien15, I, current);
    end;
    if (current = Linien24[1]) or (current = Linien24[2]) or (current = Linien24[3]) or (current = Linien24[4])then
    begin
      if Fertig1 then
        Fertig1 := Pruefe(Linien24, I, current);
    end;
    if (current = Linien23[1]) or (current = Linien23[2]) or (current = Linien23[3]) then
    begin
      if Fertig1 then
        Fertig1 := Pruefe(Linien23, I, current);
    end;
  end;
  temp:=Linien.LinienHorizontal2;
  end;


Der geht aber nicht :) Außerdem hier noch die deklaration von dem ganzen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  SubLinien = record
  public
    Linien13: array[1..3of Integer;
    Linien23: array[1..3of Integer;
    Linien14: array[1..4of Integer;
    Linien24: array[1..4of Integer;
    Linien15: array[1..5of Integer;
  end;

  MainLinien = record
  public
    LinienVertical: SubLinien;
    LinienHorizontal1: SubLinien;
    LinienHorizontal2: SubLinien;
  end;


jaenicke - So 23.08.09 22:27

Und temp ist als SubLinien deklariert? Da es sich leider um Records statt Klassen handelt, müsstest du da Pointer benutzen um auf den jeweiligen Record selbst zuzugreifen statt auf eine Kopie davon.

Ganz wichtig: Du solltest dich an Konventionen halten. So ist der Quelltext für Fremde kaum lesbar, weil du Typen ohne das führende T schreibst. TSubLinien und TMainLinien meine ich, denn an dem T sieht man sofort, dass es ein Typ und kein Feld oder Variable oder so ist.


Sylvus - So 23.08.09 22:35

ja ok werd ich ändern :)
Und zu temp, wie mach ich das jetzt, im Moment ist temp als string deklariert, aber das geht ja nicht :) Vielleicht ne kurze Hilfestellung, Pointer... und weiter :D

Grüße Sylvus


jaenicke - So 23.08.09 22:39


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  TSubLinien = record
  public
    Linien13: array[1..3of Integer;
  end;
  PSubLinien = ^TSubLinien;

...

var
  temp: PSubLinien;
begin
  temp := @Linien.LinienHorizontal1;
  with temp^ do // wobei das explizite Dereferenzieren nicht nötig ist, ist dann aber vielleicht klarer
    ...
Was passiert:
Du legst in temp nur einen Zeiger auf deinen Record und greifst dann auf den Record hinter dem Pointer zu.

Das alles könntest du dir sparen, wenn du Klassen benutzt, denn das sind bereits intern Pointer ohne dass du dich darum kümmern musst.


Sylvus - So 23.08.09 22:51

Super danke, geht soweit :)
Ich hab das ganze System jetzt schon von einzlenen Arrays zu records übertragen :) Aber ich denke wenn ich wieder Zeit habe, werd ich das mal mit klassen probieren :)
Danke dir!
Grüße Sylvus