Delphi-PRAXiS
Seite 2 von 5     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Routine mit Namen aufrufen (https://www.delphipraxis.net/184033-routine-mit-namen-aufrufen.html)

Sigi55 21. Feb 2015 09:23

AW: Routine mit Namen aufrufen
 
Moin Ha-Jö

Zitat:

Wenn ich das richtig verstehen dann gibt es keine "unbekannten" Prozeduren und Methoden sondern lediglich Objekte/Klassen die sich auf mehrere Units verteilen und die Du einheitlich aufrufen willst, Du weisst aber wo (in welcher Unit/Klasse) diese Funktionen ursprünglich definiert sind. Da du alle Methoden in Deinem Beispiel ohne Parameter aufrufen wolltest gehe ich davon aus das alle aufzurufenden Methoden paramterlos sind.
Richtig :-)

Zitat:

... machst, dann kannst Du es auch gleich richtig machen und entweder Interfaces verwenden oder Dir einen Wrapper je aufzurufender Klasse schreiben und dessen Instanzen / Objekte registrieren.
Interfaces, Wrapper, ?, da hört es bei mir auf, das kann ich nicht :-(

Ich glaub ich mach das mit den Fähnchen ...(Sparkasse) :-D

Ich bin eher so der "Auto-Zusammen-Schrauber", sprich, fertige Komponenten
zusammenbauen, aber wenn es dann (für mich) ins "Eingemachte" geht muss
ich passen.

Aber vielen Dank für Deine Mühe !

cu

Sigi

stahli 21. Feb 2015 10:19

AW: Routine mit Namen aufrufen
 
So wie ich das verstehe, liegt Dein Problem nicht bei "anderen Units" sondern bei "anderen Instanzen".
Zeig doch mal noch einen Auszug aus Deiner Datenbank, wie die Jobs definiert sind.

Wenn Du als JobNamen jetzt "DatensicherungStarten" ermittelst und dann in einem Objekt der Klasse TForm1 interpretierst um eine Methode "DatensicherungStarten" zu finden funktioniert das´, da Du Dich auf das Objekt "Self" beziehst.

Wenn Du aber mit einem anderen Objekt arbeiten willst, musst Du dessen Instanz mitgeben. Da reicht es nicht, eine Unit zu kennen.

Also ich denke, Du hast da noch einen Ansatz, der nicht ganz passt.

Versuch doch mal meinen oben genannten Ansatz. Offenbar hast Du ja nicht viele in Frage kommenden Möglichkeiten, welche Jobs aufgerufen werden können.
Dann könnte so ein "Übersetzer" schon Sinn machen. Du übergibst eine Objektinstanz und den Methodennamen und führst dann etwas passendes dazu aus.

Vom Prinzip könntest Du dann auch statt dem Methodennamen einen Code verwalten (42 = "DatensicherungStarten").

Dann siehst Du schon mal, dass Du eine Objektinstanz kennen musst, damit das funktionieren kann.

Ich denke, dass es derzeit bei Dir daran scheitert.


Zeig einfach noch ein bissl mehr, dann können wir das auch besser nachvollziehen.

BadenPower 21. Feb 2015 10:28

AW: Routine mit Namen aufrufen
 
Zitat:

Zitat von Sigi55 (Beitrag 1290823)
Moin erstmal,
Der "JobName" ist die Bezeichnung der aufzurufen Procedure den ich per Variable
übergebe.

Das klappt auch alles wunderbar, nur liegen nicht alle Proceduren auf der
Hauptform ...

Wenn Du das unbedingt so machen möchtest und 2 Variablen übergeben kannst und die Proceduren der 2. Unit auch in einer Form stecken dann kannst Du auch folgendes machen:

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
begin
  ExecuteRoutine(Application.FindComponent('Form2'), 'Hello_World');
end;

Sigi55 21. Feb 2015 11:39

AW: Routine mit Namen aufrufen
 
Hallo Stali,

Zitat:

Zitat von stahli (Beitrag 1290841)
Zeig einfach noch ein bissl mehr, dann können wir das auch besser nachvollziehen.

Da löppelt einfach nur ne Schleife ...

Delphi-Quellcode:
while not eof do
begin
  ExecuteRoutine(Form1,dmLOG.tbl_JobsLinkedPreUpdate.FieldByName('Command').AsString);
  next;
end;
Das können ein- oder mehrere Jobs sein die nacheinander abgearbeitet
werden, z.B.: Angebote ausdrucken und versenden, Datenbanken abgleichen, etc.

Das ist auch nicht wirklich ein Problem, so wie es jetzt ist, ist es eigentlich
OK, aber ich dachte halt, ich könnte mir den quasi "doppelt gemoppelten" Aufruf
einer Procedure sparen, wenn die Procedure in irgendeiner anderen unit liegt.

Gruß

Sigi

Sigi55 21. Feb 2015 11:46

AW: Routine mit Namen aufrufen
 
Hallo BadenPower,

Zitat:

Zitat von BadenPower (Beitrag 1290844)

... und die Proceduren der 2. Unit auch in einer Form stecken dann kannst Du auch folgendes machen:

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
begin
  ExecuteRoutine(Application.FindComponent('Form2'), 'Hello_World');
end;

Da liegt ja das Problem, die Procedure die ich aufrufen möchte liegt
in einer "formlosen" unit.

Vielen Dank und Gruß

Sigi

BadenPower 21. Feb 2015 12:20

AW: Routine mit Namen aufrufen
 
Zitat:

Zitat von Sigi55 (Beitrag 1290850)
Da liegt ja das Problem, die Procedure die ich aufrufen möchte liegt
in einer "formlosen" unit.

Dann zeig einmal die "formlose" Unit.
Vielleicht lässt sich das einfach umbiegen.

BadenPower 21. Feb 2015 12:31

AW: Routine mit Namen aufrufen
 
Oder Du machst aus der anderen Unit einfach eine "Form-Unit", welche Du nicht einmal anzeigen lassen musst.


kleines Copy-und-Paste Beispiel

MainForm
Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure Job1();
    procedure Job2();
    procedure Job3();
    procedure Button1Click(Sender: TObject);
  private
    procedure ExecuteJobs();
    procedure ExecuteRoutine(AInstance: TObject; AName: string);
  public
    Memo1: TMemo;
    Button1: TButton;
    ListBox1: TListBox;
    constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TExecute = procedure of object;

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  Position := poScreenCenter;
  Height := 500;
  Width := 600;
  Memo1 := TMemo.Create(Self);
  Memo1.Parent := Self;
  Memo1.Left := 300;
  Memo1.Top := 10;
  Memo1.Width := 280;
  Memo1.Height := 400;
  Button1 := TButton.Create(Self);
  Button1.Parent := Self;
  Button1.Left := 100;
  Button1.Top := 420;
  Button1.Width := 100;
  Button1.Height := 25;
  Button1.Caption := 'Jobs starten';
  Button1.OnClick := Button1Click;
  ListBox1 := TListBox.Create(Self);
  ListBox1.Parent := Self;
  ListBox1.Left := 10;
  ListBox1.Top := 10;
  ListBox1.Width := 280;
  ListBox1.Height := 400;
  ListBox1.Items.Add('Form1/Job1');
  ListBox1.Items.Add('Form1/Job2');
  ListBox1.Items.Add('Form1/Job3');
  ListBox1.Items.Add('Form2/Job1');
  ListBox1.Items.Add('Form2/Job2');
  ListBox1.Items.Add('Form2/Job3');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteJobs();
end;

procedure TForm1.ExecuteJobs();
var
  liZ1: Integer;
  lObjectName: String;
  lProcedureName: String;
  lPos: Integer;
begin

  for liZ1 := 0 to ListBox1.Count - 1 do
   begin
    if ListBox1.Items[liZ1] <> '' then
     begin
      lObjectName := '';
      lProcedureName := '';
      lPos := Pos('/', ListBox1.Items[liZ1]);
      lObjectName := Copy(ListBox1.Items[liZ1], 1, lPos - 1);
      lProcedureName := Copy(ListBox1.Items[liZ1], lPos + 1, MaxInt);
      if ((lObjectName <> '') and (lProcedureName <> '')) then
       begin
         Memo1.Lines.Add('Methode ' + lProcedureName + ' in ' + lObjectName + ' starten.');
         ExecuteRoutine(Application.FindComponent(lObjectName), lProcedureName);
         Memo1.Lines.Add('Methode ' + lProcedureName + ' in ' + lObjectName + ' beendet.');
       end;
     end;
   end;

end;

procedure TForm1.ExecuteRoutine(AInstance: TObject; AName: string);
var
  lRoutine: TMethod;
  lExecute: TExecute;
begin
  lRoutine.Data := Pointer(AInstance);
  lRoutine.Code := AInstance.MethodAddress(AName);
  if (lRoutine.Code = nil) then Exit;
  lExecute := TExecute(lRoutine);
  lExecute;
end;

procedure TForm1.Job1();
begin
  ShowMessage('Form1 - Job1');
end;

procedure TForm1.Job2();
begin
  ShowMessage('Form1 - Job2');
end;

procedure TForm1.Job3();
begin
  ShowMessage('Form1 - Job3');
end;

end.
Unit2
Delphi-Quellcode:
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    procedure Job1();
    procedure Job2();
    procedure Job3();
  private
  public
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Job1();
begin
  ShowMessage('Form2 - Job1');
end;

procedure TForm2.Job2();
begin
  ShowMessage('Form2 - Job2');
end;

procedure TForm2.Job3();
begin
  ShowMessage('Form2 - Job3');
end;

end.

Sigi55 21. Feb 2015 13:01

AW: Routine mit Namen aufrufen
 
Hallo BadenPower,

Zitat:

Zitat von BadenPower (Beitrag 1290852)
Oder Du machst aus der anderen Unit einfach eine "Form-Unit", welche Du nicht einmal anzeigen lassen musst.

Mensch, geil, klappt wie blöd :-)

Vielen Dank für Deine Mühe, euch anderen auch.
Hier wird man echt geholfen.

Meistens kann ich ja meine Wissenslücken in Bezug auf Delphi über
Google oder durch Suche hier im Forum auffüllen, aber in diesem Fall
....

Danke nochmal und

Gruß

Sigi

himitsu 21. Feb 2015 13:08

AW: Routine mit Namen aufrufen
 
Zitat:

Zitat von BadenPower (Beitrag 1290852)
Oder Du machst aus der anderen Unit einfach eine "Form-Unit", welche Du nicht einmal anzeigen lassen musst.

Ich brauch nur eine String-Variable und nehm dafür ein TRichEdit? :wall:

Es wurde doch genau gesagt, was man braucht.
> Published und/oder {$M+} (also TPersistent/TComponent)

BadenPower 21. Feb 2015 13:15

AW: Routine mit Namen aufrufen
 
Zitat:

Zitat von himitsu (Beitrag 1290855)
Ich brauch nur eine String-Variable und nehm dafür ein TRichEdit? :wall:

Mach einmal bitte eine Unit2 mit Deinem Ansatz.
Ich steh' grad' auf dem Schlauch.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:12 Uhr.
Seite 2 von 5     12 34     Letzte »    

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