Mi trovo di fronte alla necessità di richiamare dalla Form9 una procedura che è dichiarata all'interno diella Form8.
Ho letto questo (https://www.lazaruspascal.it/index.php?topic=573.msg4482#msg4482) ed ho provato a riportare il conecetto nel mio programma, ma non riesco ma completare la compilazione per via di un ERRORE incontrato dal compilartore.
Riporto le porzioni di codice inserite:
Nella Fom8 (dove si trova la procedura da richiamare):
unit Frm8;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Grids,
StdCtrls,
UModuloDatiDB, utilmie, Types;
type
{ TForm8 }
TForm8 = class(TForm)
BPulsNoAmmort: TButton;
BPulsAmmortOk: TButton;
GridPreAmmort: TStringGrid;
procedure BPulsNoAmmortClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure GridPreAmmortDrawCell(Sender: TObject; aCol, aRow: Integer;
aRect: TRect; aState: TGridDrawState);
procedure GridPreAmmortEnter(Sender: TObject);
public
procedure ScriMovGridPreAmmort(voceCesp, coVoCesp, dtMovim, impMovim, descrMovim, voceSotCtoCas, coVoceSotCtoCas: String);
var
striAmmortMan: AnsiString;
private
var
// bla bla
end;
var
Form8: TForm8;
implementation
uses
Frmmain, Frm9;
{$R *.lfm}
{ TForm8 }
// bla bla
Nella Fom9 (dove richiamo la procedura della Form8):
unit Frm9;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, DB, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls, Grids, LCLType, Math, memds, LR_Class, LR_DBSet, lr_e_pdf, Types,
Frm8, Frm12, UModuloDatiDB, utilmie;
type
{ TForm9 }
TForm9 = class(TForm)
BPulsAvanti: TButton;
// bla bla
private
FAltraForm: TForm8;
procedure SetAltraForm(AValue: TForm8);
public
property AltraForm: TForm8 read FAltraForm write SetAltraForm;
var
dataFin, segnoIniFinAn: String;
end;
var
Form9: TForm9;
// bla bla
implementation
// bla bla
Form8.AltraForm.scriMovGridPreAmmort(voCespite, coCespite, dtMov, impMov, descrMov, voSotCtoCas, coSotCtoCas); //<--- ERRORE in compilazione
L'ERRORE segnalato dal compilatore è: frm9.pas(2305,15) Error: identifier idents no member "AltraForm"
???
Form8.AltraForm.scriMovGridPreAmmort(voCespite, coCespite, dtMov, impMov, descrMov, voSotCtoCas, coSotCtoCas); //<--- ERRORE in compilazione
L'ERRORE segnalato dal compilatore è: frm9.pas(2305,15) Error: identifier idents no member "AltraForm"
???
"AltraForm" è definita in TForm9, non in TForm8. Quindi togli il Form8 davanti alla chiamata di "AltraForm":
AltraForm.scriMovGridPreAmmort(voCespite, coCespite, dtMov, impMov, descrMov, voSotCtoCas, coSotCtoCas);
@ DragoRosso
Ho cominciato a familiarizzare con la tecnica di passaggio dati fra due Form facendoli transitare da una Classe di variabili.
Dall'ultimo esempio che mi hai girato, ho capito che la Unit1 è la Form cedente dati, mentre la Unit2 è la Form ricevente. La Unit3 è la Classe "daticomuni".
Quest'ultima viene inizializzata col comando "DatiComuni.Init(5, 2)" , inserito all'interno della Unit1.
La Unit2 con la sua Form2, contenente la StringGRid da riempire coi dati provenienti dalla Unit1, contiene una sola procedura
procedure TForm2.FormShow(Sender: TObject);
var row, col: integer;
begin
//Legge il record e lo inserisce nella griglia
for row := 0 to DatiComuni.NumRow-1 do
for col := 0 to DatiComuni.NumCol-1 do
StringGrid1.Cells[col+1, row+1] := DatiComuni.Dati[row, col];
end;
che si occupa del riempimento delle celle della StringGrid1.
Non ho trovato la
procedure FormCreate
così come non ho trovato la
Application.CreateForm(TForm2, Form2);
nella Unit1.
Ho provato ad eseguire il programmino di esempio che mi hai girato e funziona perfettamente.
Ma come può funzionare se manca il Create della Form2 ?
La Unit3 è la Classe "daticomuni".
Non è proprio una classe, bensì un record. I record "avanzati" possono agire similmente alle classi, ma sono più .... snelli .... ad esempio non bisogna istanziarli. Puoi leggere qui: https://www.lazaruspascal.it/index.php?page=145 (https://www.lazaruspascal.it/index.php?page=145)
Gli advanced record implementano delle funzionalità che le classi non hanno: ad esempio si possono sostituire gli operatori ... cioè posso ad esempio eseguire una somma tra due record o una moltiplicazione, o altro (operator overloading).
Non ho trovato la
procedure FormCreate
così come non ho trovato la
Application.CreateForm(TForm2, Form2);
nella Unit1.
In Lazarus, per impostazione predefinita, le FORM e i DATAMODULE (e solo questi due oggetti) vengono "autoistanziati" all'avvio dell'applicazione.
E' possibile evitare ciò andando nelle opzioni di progetto / FORM (vedi allegato).
Quando si modifica quella opzione (quindi si inserisce una FORM in AUTOCREAZIONE o meno), viene cambiato automaticamente il file di progetto .lpr (in questo caso Project2.lpr) inserendo o togliendo la riga Application.CreateForm corrispondente.
Per quello che riguarda l'evento "FormCreate", esso non è obbligatorio e serve solo se hai delle attività da svolgere immediatamente dopo la creazione della Form stessa.
Nel caso della Form1 (in unit1.pas), viene eseguita l'inizializzazione di DatiComuni (ossia l'allocazione dello spazio per righe e colonne volute) ... è solo per quello che nella Form1 esiste quell'evento.
Ciao
P.S.: se vuoi inserire la procedura Clear questo è il suggerimento (devi inserire la dichiarazione anche nella definizione del record):
procedure TDatiCoumni.Clear;
var tempRow, tempCol: integer;
begin
tempRow := Length(fDati);
tempCol := Length(fDati[0]);
//Questo azzera l'array
SetLength(fDati, 0, 0);
//Questo risetta l'array ponendo a default (per le stringhe vale "") il contenuto
SetLength(fDati, tempCol, tempRow);
end;