Ieri ho ricevuto un augurio di Buon divertimento.
Sembra però che io debba divertirmi passando da un tipo di Errore ad un altro.
Dopo l'ultima correzione ed il completamento della compilazione, mi si presenta per la prima volta un Errore a me completamente sconosciuto ed assolutamente nuovo, durante l'esecuzione di una riga di codice che funzionava eccellentemente fino a prima dell'ultima modifica
l'istruzione è l'ultima della serie seguente:
procedure TForm1.Panel1Enter(Sender: TObject);
var
. . .
begin
Menu2.Enabled:= False;
if not FileExists(dbOrig) then // l'ASSENZA del file ContabFamdb, potrebbe significare che il programma sta lavorando per la prima volta e bisogna dare vita al DB
begin
ShowMessage('DB ' + dbOrig + ' INESISTENTE - il Programma verra'' chiuso');
Halt; // Halt interrompe BRUTALMENTE l'esecuzione del programma e restituisce il controllo al chiamante
end;
i:= 0;
sql:= 'select * from (select "causalifreq" AS nomeTbx, count(*) AS totRecTbx from causalifreq';
sql:= sql + ' UNION select "ggaperte" as nomeTbx, count(*) as totRecTbx from ggaperte';
sql:= sql + ' UNION select "movimgg" as nomeTbx, count(*) as totRecTbx from movimgg';
sql:= sql + ' UNION select "partmovv" as nomeTbx, count(*) as totRecTbx from partmovv';
sql:= sql + ' UNION select "piancont" as nomeTbx, count(*) as totRecTbx from piancont';
sql:= sql + ' UNION select "prestmom" as nomeTbx, count(*) as totRecTbx from prestmom';
sql:= sql + ' UNION select "racodvoci" as nomeTbx, count(*) as totRecTbx from racodvoci';
sql:= sql + ' UNION select "restacassagg" as nomeTbx, count(*) as totRecTbx from restacassagg';
sql:= sql + ' UNION select "riepmovg" as nomeTbx, count(*) as totRecTbx from riepmovg';
sql:= sql + ' UNION select "componfam" as nomeTbx, count(*) AS totRecTbx from componfam';
sql:= sql + ' UNION select "riepnewrecdb" as nomeTbx, count(*) as totRecTbx from riepnewrecdb) as contaRecDB';
DataModule1.ZConnection1.Database:= dbOrig;
Questa volta non so pproprio da dove cominciare. Ho provato a togliere l'ultima modifica, ma non è cambiato niente.
L'errore 216 è un errore abbastanza comune e l'indicazione così come è stata data è troppo generica.
E' necessario identificare il blocco di codice dove avviene ciò.
Il fatto che avvenga in una Form o in un'altra non toglie che le ultime modifiche non ne siano la causa. Una variabile globale, un evento, o altro possono essere influenzati anche da altri componenti / classi / moduli.
Metti diversi Breakpoint per delimitare la zona di ricerca, in alternativa occorre leggere i "map files" per vedere a cosa corrisponde l'indirizzo incriminato.
Fino a quando parliamo di mettere sotto controllo l'esecuzione del programma per capire qual'è l'istruzione che provoca l'Errore, ti seguo. É un metodo di ricerca usato sempre quando voglio individuare un Errore. L'ho fatto anche questa volta e l'istruzione incriminata è proprio quella segnalata nel messaggio d'Errore. Allego il messaggio
Ho provato il programma in 3 S.O. diversi: Ubuntu, LinuxMint e Manjaro. Tutti danno lo stesso Errore. L'immagine allegata è proprio quella generata dal mio programma in ambiente Manjaro, quello su cui sto orientando recentemente.
L'istruzione in cui si genera l'Errore fa parte del seguente gruppo:
begin
Menu2.Enabled:= False;
if not FileExists(dbOrig) then // l'ASSENZA del file ContabFamdb, potrebbe significare che il programma sta lavorando per la prima volta e bisogna dare vita al DB
begin
ShowMessage('DB ' + dbOrig + ' INESISTENTE - il Programma verra'' chiuso');
Halt; // Halt interrompe BRUTALMENTE l'esecuzione del programma e restituisce il controllo al chiamante
end;
i:= 0;
sql:= 'select * from (select "causalifreq" AS nomeTbx, count(*) AS totRecTbx from causalifreq';
sql:= sql + ' UNION select "ggaperte" as nomeTbx, count(*) as totRecTbx from ggaperte';
sql:= sql + ' UNION select "movimgg" as nomeTbx, count(*) as totRecTbx from movimgg';
sql:= sql + ' UNION select "partmovv" as nomeTbx, count(*) as totRecTbx from partmovv';
sql:= sql + ' UNION select "piancont" as nomeTbx, count(*) as totRecTbx from piancont';
sql:= sql + ' UNION select "prestmom" as nomeTbx, count(*) as totRecTbx from prestmom';
sql:= sql + ' UNION select "racodvoci" as nomeTbx, count(*) as totRecTbx from racodvoci';
sql:= sql + ' UNION select "restacassagg" as nomeTbx, count(*) as totRecTbx from restacassagg';
sql:= sql + ' UNION select "riepmovg" as nomeTbx, count(*) as totRecTbx from riepmovg';
sql:= sql + ' UNION select "componfam" as nomeTbx, count(*) AS totRecTbx from componfam';
sql:= sql + ' UNION select "riepnewrecdb" as nomeTbx, count(*) as totRecTbx from riepnewrecdb) as contaRecDB';
// WriteLn('sql= |' + sql + '|');
WriteLn('dbOrig= |' + dbOrig + '|');
DataModule1.ZConnection1.Database:= dbOrig; <-- riga 337
DataModule1.ZConnection1.Connected:= True;
DataModule1.ZReadOnlyQuery1.Active:= False;
DataModule1.ZReadOnlyQuery1.SQL.Text:= sql;
DataModule1.ZReadOnlyQuery1.Active:= True;
DataModule1.ZReadOnlyQuery1.First;
map files è un termine per me assolutamente nuovo. Non lo conosco. Ci strudio su e vi faccio sapere.
La risposta è in un mio post nel tuo precedente topic, ma te lo ripeto con qualche chiarimento in più.
La FORM la puoi chiamare come vuoi, ma ciò che tu chiami nome della form dovrebbe essere il valore dell'attributo NAME del componente a desgin time.
Quello è il nome della Form, e quando la cambi l'IDE automaticamente aggiorna i riferimenti della classe (non però i riferimenti usati nel codice fatto da te).
Quindi se una Form la chiami FormMia, verrà creato il seguente codice::
type
TFormMia := Class(TForm)
.......
......
end;
Var FormMia: TFormMia;
Alterare quel codice a mano si può fare ma richiede attenzione.
Altra cosa è il nome della UNIT che contiene la FORM, ossia il file ".pas": il file lo salvi eseguendo il "SALVA COME" dal menu dell'IDE, e solo da li lo puoi rinominare.
L'operazione "SALVA COME" genera i riferimenti nel progetto (file .LPR e .LPI) e il file ".pas" e eventualmente il file ".lfr".
IL NOME DELLA FORM e i suoi antenati diretti, quindi ad esempio FormMia e TFormMia NON DEVONO ESSERE USATI COME NOME DELL'UNITA': non devono esserci file "FormMia.pas" o "TFormMia.pas".
Spero di essere stato più chiaro e d'aiuto.
Un pò sono andati avanti, ma molto poco, perchè il compilatore mi da sempre Errore:
Impostazione nome per la nuova Form (Form8) e pa corrispondente Unit
unit FrmAttendi;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs;
type
TFormAttendi = class(TForm)
private
public
end;
var
FormAttendi: TFormAttendi;
implementation
{$R *.lfm}
end.
Impostazioni dentro il file .lpr
program DomusRatio;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, datetimectrls, memdslaz, runtimetypeinfocontrols, lazreportpdfexport,
zcomponent, zcore, pack_powerpdf, FrmMain, Frm2, Frm3, Frm4, Frm5, utilmie,
Frm7, Frm6, UModuloDatiDB, Frm9, Frm10, FrmAttendi;
{$R *.res}
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TDataModule1, DataModule1);
Application.Run;
end.
chiamata della Form dentro la Form9
Application.CreateForm(TFormAttendi, FormAttendi);
FormAttendi.msg:= 'Ricerca MOVIMENTI AMMORTIZZABILI in corso' + lineending + lineending + '----- A T T E N D I -----';
FormAttendi.Show;
Ed ecco i messagi di Errore relativi alle tre suddette righe
Application.CreateForm(TFormAttendi, FormAttendi);
FormAttendi.msg:= 'Ricerca MOVIMENTI AMMORTIZZABILI in corso' + lineending + lineending + '----- A T T E N D I -----';
FormAttendi.Show;
Per dirla alla carlona: BO?
Credo tu abbia sbagliato a copiare i messaggi di errore. Se crei l'istanza di una form da un qualsiasi punto del tuo codice, mi sentirei di consigliarti di essere più metodico ed avere maggiore controllo sulla tua istanza.
myform := TfrmAttendi.Create
try
//usa
finally
myform.free //oppure freeandnil(myform)
end;
Volendo potresti cancellare solo quei due file.
Se il compilatore ti indica form8 e quella variabile non esiste più, magari è un'altra la unit che non viene aggiornata. Per il "refactory" in genere si usa il Crtl+Shift+E . Ci pensa lazarus a cambiare i nomi delle classi/variabili per te e le dovrebbe modificare tutte.
Non ho eseguito il Crtl+Shift+E, perchè ho capito che quello si occupa solamente della ricostruzione, mentre io dovevo ripulire e ricostruire.
Sono entrato dall'IDE in Esegui -> Ripulire e costruire e dentro le finestre "Cartelle sorgenti del pacchetto" ho selezionato solamente "*.ppu;*.o;", quindi ho premuto il pulsante "Ripulisci e Costruisci".
dopo la ricostruzione è partita in automatico la compilazione e:
L'Errore sulla Form8 è scomparso, mentre erano rimasti gli altri.
Guardando meglio dentro la Form9, in cui si trovano le righe:
Application.CreateForm(TFormAttendi, FormAttendi);
FormAttendi.msg:= 'Ricerca MOVIMENTI AMMORTIZZABILI in corso' + lineending + lineending + '----- A T T E N D I -----';
FormAttendi.Show;
e mi sono accorto che fra gli uses mancava il nome del file FrmAttendi. Ho provveduto allora ad inserirlo ed a ricompilare.
La compilazione si è completata senza errori. Ora, però è l'esecuzione a segnalare un Errore, quello riportato come allegato.
Sembra che debba usare il costruttore CreateNew, ma io non trovato niente del genere.
E' inutile, NON riesco ad andare avanti, se non supero l'ostacolo..
Ho trovato un'altra soluzione: La Form dinamica.
Ho allora costruito la Form via codice, senza quindi passare dal Designer.
FormAvviso:=TForm.Create(nil);
with FormAvviso do
begin
Height:= 130;
Left:= 500;
Top:= 50;
Width:= 400;
Position:= poScreenCenter;
Caption:= 'MOVIMENTI AMMORTIZZABILI';
end;
Lmsg := TLabel.Create(FormAvviso);
with Lmsg do
begin
Parent := FormAvviso;
Height:= 80;
Left:= 10;
Top:= 20;
Width:= 300;
Caption:= 'Ricerca in corso' + lineending + ' ' + lineending + Space(30) + ' A T T E N D I';
AutoSize:= False;
Enabled:= True;
Visible:= True;
end;
FormAvviso.Show;
Sleep(200); // Attendi 200 millesecondi (= 1/5 di secondo)
Application.ProcessMessages;
Funziona tutto perfettamente, ma fino ad un certo punto, infatti la Form viene creata e visualizzata, ma al suo interno non sono riuscito a mostrare la Label col messaggio di Attesa.
Ho cercato in tutti i modi a me noti di venirne a capo, ma ancora una volta ho perso la battaglia.
@petrusic
A me funziona.
Dove è che usi quel codice ? In un evento ? Quale ?
Io eseguo il create e l'emissione della mia Form dinamica dentro una routine.
Però, Udite, Udite: Ora ce l'ho fatta!
Ho inserito le righe enabled e visible nel codice del gruppo di istruzioni TForm.Create ed ha funzionato.
procedure AmmortamentoCespiti();
type
TtbGrupCespiti = array [0..10, 0..1] of string;
. . .
var
FormAvviso: TForm;
Lmsg: TLabel;
swFine: Boolean = False;
. . .
begin
. . .
FormAvviso:=TForm.Create(nil);
with FormAvviso do
begin
Height:= 130;
Left:= 500;
Top:= 50;
Width:= 400;
Position:= poScreenCenter;
Caption:= 'MOVIMENTI AMMORTIZZABILI';
Enabled:= True; <-- NUOVA
Visible:= True; <-- NUOVA
end;
Lmsg := TLabel.Create(FormAvviso);
with Lmsg do
begin
Parent:= FormAvviso;
Height:= 80;
Left:= 10;
Top:= 20;
Width:= 300;
Caption:= 'Ricerca in corso' + lineending + ' ' + lineending + Space(30) + ' A T T E N D I';
AutoSize:= False;
Enabled:= True;
Visible:= True;
ParentColor:= False;
end;
FormAvviso.Show;
Sleep(200);
Application.ProcessMessages;
Finalmente ho finito. Grazie.