Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Wie wird aus einem String eine Anweisung? (https://www.delphipraxis.net/186334-wie-wird-aus-einem-string-eine-anweisung.html)

Sel2012 25. Aug 2015 05:15

Wie wird aus einem String eine Anweisung?
 
Hallo liebe Spezialisten,
ich möchte mit FireMonkeyMobile eine variable Anzahl von Kreisen darstellen.
Natürlich kann ich für jede Situation mit ButtonXClick jeden gewünschten Kreis einzeln mit visible ansprechen (Siehe script 1).
Delphi-Quellcode:
procedure TForm4.Button1Click(Sender: TObject);
begin
 circle2a.visible:=false;
 circle3a.visible:=false;
 circle4a.visible:=false;
 circle5a.visible:=false;
 circle6a.visible:=false;
 circle7a.visible:=false;
 circle8a.visible:=false;
 circle9a.visible:=false;
 circle10a.visible:=false;
 circle1a.visible:=true;
end;

procedure TForm4.Button2Click(Sender: TObject);
begin
 circle3a.visible:=false;
 circle4a.visible:=false;
 circle5a.visible:=false;
 circle6a.visible:=false;
 circle7a.visible:=false;
 circle8a.visible:=false;
 circle9a.visible:=false;
 circle10a.visible:=false;
 circle1a.visible:=true;
 circle2a.visible:=true;
end;
Eleganter und flexibler müsste das aber wie folgt gehen:

Delphi-Quellcode:
procedure TForm4.Button11Click(Sender: TObject);
var i,erg:integer;
kurz:array[1..10] of string;

begin
  i:=1;
erg:=9;
repeat
kurz[i]:= ('circle'+inttostr(i)+'a.visible:=true;');
 Application.ProcessMessages;
sleep(1000); //zum Verfolgen der "automatisierten" Befehlszeilen
label4.Text:= kurz[i];
inc(i);
until i=erg+1;

{circle10a.visible:=false;
 circle1a.visible:=true;
 circle2a.visible:=true;
 circle3a.visible:=true;
 circle4a.visible:=true;
 circle5a.visible:=true;
 circle6a.visible:=true;
 circle7a.visible:=true;
 circle8a.visible:=true;
 circle9a.visible:=true; }

end;
Im Label werden die Befehlszeilen aus dem vorherigen Code alle 1:1 abgebildet. Die Strings sehen optisch genauso aus wie
die Befehlszeilen (von Hand geschrieben). Wie mache ich nun aus den Strings Anweisungszeilen?

'kurz[i];' funktioniert jedenfalls nicht.

hoika 25. Aug 2015 05:22

AW: Wie wird aus einem String eine Anweisung?
 
Hallo,
FindComponent benutzen?

Heiko

mkinzler 25. Aug 2015 05:24

AW: Wie wird aus einem String eine Anweisung?
 
Entweder die Circles in einem Array verwalten oder sich zur Laufzeit Referenzen auf die Objekte holen, in der VCL würde man das mit FindComponent bzw. FindControl machen.

Dejan Vu 25. Aug 2015 06:47

AW: Wie wird aus einem String eine Anweisung?
 
Wenn ich zur Laufzeit Controls erzeuge, werde ich sie mit Sicherheit nicht hinterher mühselig mit 'FindComponent' suchen, sondern mir eher merken.

Und wenn ich sonst Controls bzw. Komponenten verwalten will, dann habe ich ihren Bezeichnernamen und kann den direkt ansprechen. Und wenn ich eine Gruppe von Controls erreichen will, dann kopiere ich mir die Referenzen in ein Array.

FindComponent ist genauso überflüssig wie 'with'. Und eigentlich genauso 'böse' (*). Also lasst doch endlich mal den Tipp mit diesem FindComponent.

(*) Wenn ich den Namen der Komponente ändere, funktioniert mein Programm nicht mehr.

Blup 25. Aug 2015 08:20

AW: Wie wird aus einem String eine Anweisung?
 
Erstellt man die Komponenten zur Laufzeit selbst, ist ein Array sicher die beste Lösung.
Andernfalls bietet sich auch diese Alternative an:
Delphi-Quellcode:
function TForm4.GetCircle(AIndex: Integer): TShape;
begin
  case AIndex of
    1: Result := circle1a;
    2: Result := circle2a;
    3: Result := circle3a;
    4: Result := circle4a;
    5: Result := circle5a;
    6: Result := circle6a;
    7: Result := circle7a;
    8: Result := circle8a;
    9: Result := circle9a;
   10: Result := circle10a;
  else Result := nil; // oder Exception auslösen
  end;
end;

procedure TForm4.SetCircleVisible(ACount: Integer);
var
  i: Integer;
begin
  for i := 1 to 10 do
  begin
    GetCircle(i).Visible := (i <= ACount);
  end;
end;

RoadR69 25. Aug 2015 08:28

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1313371)
(*) Wenn ich den Namen der Komponente ändere, funktioniert mein Programm nicht mehr.

Ist für mich nicht wirklich das KO-Kriterium dafür. Aber der Würgereiz ist doch kaum zu unterdrücken, wenn man bedenkt, dass man ein schnelles, sichereres, elegantes Pointer-Merken durch ein String-Suchgewühl ersetzt ...

Sel2012 25. Aug 2015 10:22

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Blup (Beitrag 1313379)
Erstellt man die Komponenten zur Laufzeit selbst, ist ein Array sicher die beste Lösung.
Andernfalls bietet sich auch diese Alternative an:
Delphi-Quellcode:
function TForm4.GetCircle(AIndex: Integer): TShape;
begin
  case AIndex of
    1: Result := circle1a;
    2: Result := circle2a;
  ...
...
   10: Result := circle10a;
  else Result := nil; // oder Exception auslösen
  end;
end;

procedure TForm4.SetCircleVisible(ACount: Integer);
var
  i: Integer;
begin
  for i := 1 to 10 do
  begin
    GetCircle(i).Visible := (i <= ACount);
  end;
end;

Hallo Blup, vielend Dank für den Vorschlag. Hast du ihn getestet? Bei mir bleibt nämlich das alte Problem, dass ein String ein
String bleibt und keine Anweisung wird. Als optische Darstellung, z.B. im Label, etc. ist das kein Problem. Aber ich benötige ja eine Anweisung.

baumina 25. Aug 2015 10:26

AW: Wie wird aus einem String eine Anweisung?
 
Nur Interpreter können zur Laufzeit erzeugte Kommandozeilen verarbeiten. Du arbeitest mit einem Compiler, deswegen musst du hier einen anderen Weg gehen.

EDIT: Blup hat in seinem Beispiel keine Strings, deswegen müsste das so schon funktionieren.

Mavarik 25. Aug 2015 10:37

AW: Wie wird aus einem String eine Anweisung?
 
Abgesehen vom "<=" Fehler

Zitat:

Zitat von Sel2012 (Beitrag 1313405)
Bei mir bleibt nämlich das alte Problem, dass ein String ein String bleibt und keine Anweisung wird. Als optische Darstellung, z.B. im Label, etc. ist das kein Problem. Aber ich benötige ja eine Anweisung.

Wovon redest Du? Du wolltest doch "nur" Kreis ein- und ausblenden. Wo ist den da ein String?

Jumpy 25. Aug 2015 10:49

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

kurz[i]:= ('circle'+inttostr(i)+'a.visible:=true;')
Er hat nicht den Namen einer Komponente im String, wo er dann die Komponente such um einen Befehl auszuführen. Er baut den ganzen Befehl in einen String ein und möchte den dann ausführen:

sString:='circle4a.visible:=true';
FühreBefehlAus(sString);

Nur das das nicht funktionieren wird. Deswegen nochmal Blups-Variante anschauen.

frankyboy1974 25. Aug 2015 11:36

AW: Wie wird aus einem String eine Anweisung?
 
Hallo,

also ich würde sagen, in dem du einen Compiler / Interpreter programmierst.:shock:

mfg

p80286 25. Aug 2015 11:51

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von frankyboy1974 (Beitrag 1313421)
Hallo,

also ich würde sagen, in dem du einen Compiler / Interpreter programmierst.:shock:

mfg

Na nicht ganz sooo schlimm. Bei einem Makro-Assembler werden die eigentlich numerischen Befehle ja auch durch Buchstabenkombinationen repräsentiert. Du mußt also für jeden Kreis und für jede Funktion eine entsprechende Kombination definieren, und die wird dann übersetzt.
ungefähr so:
Delphi-Quellcode:
if Befehl='exit' then Application.Terminate;
oder
Delphi-Quellcode:
if Befehl='exit' then Befehlnum:=99;
case Befehlnum of
   99 : Application.Terminate;
end;{case --------------------}
Ein paar Grundkenntnisse im Parser bzw. Compilerbau schaden da allerdings auch nicht.

Gruß
K-H

frankyboy1974 25. Aug 2015 11:59

AW: Wie wird aus einem String eine Anweisung?
 
Hallo,

also gut, zumindesten einen Assembler.

mfg

Sel2012 25. Aug 2015 12:29

AW: Wie wird aus einem String eine Anweisung?
 
Mit If...Then geht es im Prinzip ganz einfach:

Delphi-Quellcode:
procedure TForm4.Button11Click(Sender: TObject);
var i:integer;

begin
erg:=strtoint(edit1.text)+zahl1;

 circle1a.visible:=false;
 circle2a.visible:=false;
 circle3a.visible:=false;
 circle4a.visible:=false;
 circle5a.visible:=false;
 circle6a.visible:=false;
 circle7a.visible:=false;
 circle8a.visible:=false;
 circle9a.visible:=false;
 circle10a.visible:=false;

for i := 1 to erg do

 if i=1 then circle1a.visible:=true
else if i=2 then circle2a.visible:=true
else if i=3 then circle3a.visible:=true
else if i=4 then circle4a.visible:=true
else if i=5 then circle5a.visible:=true
else if i=6 then circle6a.visible:=true
else if i=7 then circle7a.visible:=true
else if i=8 then circle8a.visible:=true
else if i=9 then circle9a.Visible:=true
else if i=10 then circle10a.Visible:=true
end;
Damit kann ich ohne viel Schreibarbeit viele Varianten erstellen, indem nur der Start- und Endwert der For-Schleife geändert wird.

Mavarik 25. Aug 2015 12:31

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Sel2012 (Beitrag 1313432)
Mit If...Then geht es im Prinzip ganz einfach:

OMG liest Du eigentlich auch die Antworten? (#5)

baumina 25. Aug 2015 12:41

AW: Wie wird aus einem String eine Anweisung?
 
else if else if else if ... :kotz:

Sir Rufo 25. Aug 2015 13:00

AW: Wie wird aus einem String eine Anweisung?
 
Oder man schreibt es noch kürzer
Delphi-Quellcode:
procedure TForm4.Button11Click(Sender: TObject);
begin
  erg := strtoint(edit1.text)+zahl1;

  circle1a.visible := Between(erg,1,1);
  circle2a.visible := Between(erg,1,2);
  circle3a.visible := Between(erg,1,3);
  circle4a.visible := Between(erg,1,4);
  circle5a.visible := Between(erg,1,5);
  circle6a.visible := Between(erg,1,6);
  circle7a.visible := Between(erg,1,7);
  circle8a.visible := Between(erg,1,8);
  circle9a.visible := Between(erg,1,9);
  circle10a.visible:= Between(erg,1,10);
end;

Blup 25. Aug 2015 13:05

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Mavarik (Beitrag 1313412)
Abgesehen vom "<=" Fehler

So wie ich den ursprünglichen Quelltext verstanden habe, möchte er schrittweise alle Kreise einblenden, also zuerst einen, dann zwei, usw. bis alle Kreise sichtbar sind.
Deshalb habe ich den Parameter auch "ACount" genannt.
Soll natürlich nur immer ein Kreis zur selben Zeit sichtbar sein, währe der Vergleich mit "=" erforderlich.
Dann würde ich den Parameter "AIndex" nennen.

Mavarik 25. Aug 2015 13:09

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Blup (Beitrag 1313445)

So wie ich den ursprünglichen Quelltext verstanden habe, möchte er schrittweise alle Kreise einblenden

Ah ok... hatte ich nicht so verstanden...

Sel2012 26. Aug 2015 22:50

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Mavarik (Beitrag 1313434)
Zitat:

Zitat von Sel2012 (Beitrag 1313432)
Mit If...Then geht es im Prinzip ganz einfach:

OMG liest Du eigentlich auch die Antworten? (#5)

Hallo Mavarik, hast du auch die Antwort (#7) gelesen? Vielleicht bin ich ja zu doof, aber bei mir klappt das leider nicht.
Daraus wird keine funktionierende Anweisung, sondern das Ding bleibt ein tatenloser string.:-D

implementation 26. Aug 2015 23:05

AW: Wie wird aus einem String eine Anweisung?
 
Zitat:

Zitat von Sel2012 (Beitrag 1313647)
Hallo Mavarik, hast du auch die Antwort (#7) gelesen? Vielleicht bin ich ja zu doof, aber bei mir klappt das leider nicht.
Daraus wird keine funktionierende Anweisung, sondern das Ding bleibt ein tatenloser string.:-D

Ich weiß ja nicht, wo du deinen String herzauberst. In dem Vorschlag kommt nämlich gar keiner vor. Also red keinen Scheibenkleister.

stahli 26. Aug 2015 23:34

AW: Wie wird aus einem String eine Anweisung?
 
Für so etwas brauchst Du halt einen Interpreter (oder einen Compiler, der den text auch interpretiert und daraus eine Exe baut).

Einen Compiler wirst Du nicht bauen können. Das kannst Du gleich vergessen.

Aber Du kannst ggf. einfache Texte interpretieren. Dazu musst Du sie zerlegen und den Sinn ermitteln.
Wenn es eine begrenzte Anzahl von Kombinationen gibt, dann geht so etwas, aber es ist aufwendig.

Wenn Du z.B. einen Text in 3 Teile zerlegst, kannst Du z.B. so etwas machen:

Delphi-Quellcode:
if S1 = 'Close' then Close;

if (S1 = 'Panel1') and (S2 = 'Visible') and (S3 = 'True') then
  Panel1.Visible := True;

if S1 = 'Klose' then Close;

if (S1 = 'Tafel') and (S2 = 'Sichtbar') and (S3 = 'Ja') then
  Panel1.Visible := True;
Also Du gibst dem Programm vor, was es bei bestimmten Texten tun soll.
Das ist aber dann kein wirklicher Pascal-Quelltext, der dynamisch compiliert wird.

Bei Delphi muss der Quelltext komplett vorher kompiliert werden. In der Exe steht dann der komplette ausführbare Maschinencode.
Dynamische Texte zur Laufzeit "nachzuübersetzen" geht halt nicht.

hoika 27. Aug 2015 04:43

AW: Wie wird aus einem String eine Anweisung?
 
Hallo,
an den Threadersteller.

Bitte noch mal den neuen Quellcode zeigen.

PS:
Warum so negativ zu FindComponent?
Wenn ich verschiedene Arten von Komponenten habe,
fange ich doch nicht an, mir mehrere Arrays zu basteln,
aber hier geht es erst mal um Circles, also OK.

PS2:
Von RemObjects gibt es PascalScript,
da wäre unser Interpreter.


Heiko

Sir Rufo 27. Aug 2015 09:11

AW: Wie wird aus einem String eine Anweisung?
 
Mit FindComponent verlässt man ein wenig den OOP Pfad und CleanCode ist sowieso schon Geschichte.

Wir kennen die Beweggründe nicht, aber ich vermute mal so etwas wie eine Aussteuerungsanzeige. Anyway, dafür gibt es Klassen (hier wäre wohl ein Frame angesagt) um etwas Komplexeres zusammenzufassen und dadurch in der Handhabung einfacher zu machen.

Wer keine Frames verwenden möchte und auch keine neue Komponente dafür erstellen möchte, der schreibt sich eine einfache Klasse, die dann diese x Controls entgegennimmt und entsprechend ansteuert.

FindComponent ist wie "Schauen wir mal", die Verwendung von Klassen schafft Tatsachen.

Jeder entscheidet selber, ob er mit Tatsachen oder mit Weissagungen programmieren möchte. Ich kann mit Tatsachen allerdings erheblich besser umgehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz