La sapete l'ultima del Ministero degli Interni di Gambas?
Per rientrare nel budget di spesa indicato nella fianaz-Memory bisogna apportare un taglio deciso all'impiego di variabili globali nei programmi comunitari. :rotfl: :rotfl:
Perciò sto cercando di uniformarmi alle disposizioni e, attraverso i vari metodi su cui sto impegnando la mia mente in questo momento, operando un taglio di qua ed un taglio di là, sto diminuendo drasticamente la presenza di variabili globali nel mio programma.
Sono però di fronte ad una tabella che attualmente corrisponde alla Mesi.List (ComboBox) contenuta nella Form1, per cui fino ad ora ho sempre fatto riferimento alla Lista tramite istruzioni del tipo
Adesso la Form1 viene richiamata con la metodologia "Metodi nascosti" e l'istruzione appena citata non funziona più, perciò ho bisogno di costituire un'array specifico che prima non mi serviva e, piuttosto, che crearlo come variabile globale, vorrei definirlo dentro la Form FMain con
STATIC PUBLIC TabMesi AS String[12] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
Così facendo potrei interrogare sempre l'array con la mia vecchia istruzione dopo averlas adeguata --> FMain.Mesi[i_Mese] ed eviterei una vera e propria variabile globale.
Secondo la vostra maggiore esperienza, riesco nell'intento, oppure esiste un'altro procedimento più efficace ed a risparmio energetico? ;D
Ciao
La tabella specificata, in definitiva credo non cambi mai... Detto questo puoi trasformarla in costante, aggiungendo appunto la clausola CONST.
...............................
Una volta che la variabile assume la forma di costante, questa non può essere referenziata ovvero, non c'è bisogno di creare la classe per potervi accedere, perchè creata automaticamente all'avvio dell'applicazione (è un elemento statico, ovvero sempre presente in memoria).
Dal nuovo spunto che mi hai dato ho ripreso la mia variabile definita in FMain:
STATIC PUBLIC TabMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
provata e funzionante, e l'ho modificata così:
PUBLIC CONST TabMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
ma evidentemente non ho capito, perché così come l'ho scritta fornisce l'errore Bad constant type alla line xx in FMain.class
, come se Gambas non accetti una constante stringa strutturata sotto forma di array.
Ho anche cercato un esempio simile nel Forum, nel Beginner Guide, nel wiki, ma non sono stato capace di trovarlo. Eppure la modifica mi sembrava semplice. Dove ho sbagliato?
Ciao
Ti faccio un esempio al volo, dato che ho sempre delle difficoltà a reperirti codice funzionante dal posto in cui sono...
STATIC PUBLIC FUNCTION TabMesi() AS String[]
DIM tbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
RETURN tbMesi
END
Dato che la funzione TabMesi è dichiarata statica, puoi chiamarla direttamente, anche se è inclusa in una classe:
quindi allo stesso modo di un modulo.
Ti faccio un esempio al volo, dato che ho sempre delle difficoltà a reperirti codice funzionante dal posto in cui sono...
STATIC PUBLIC FUNCTION TabMesi() AS String[]
DIM tbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
RETURN tbMesi
END
Dato che la funzione TabMesi è dichiarata statica, puoi chiamarla direttamente, anche se è inclusa in una classe:
quindi allo stesso modo di un modulo.
Mmmmmmmh :danger:
Se ho finalmente capito, tu dici: dichiaro un modulo contenente la funzione public in cui costruisco la famosa stringa TabMesi, valorizzata coi mesi in chiaro:
' Gambas class file
'----------------------------------- Modulo TableMesi --------------------------------------------------------------------------------------------------------------------------------------------------
STATIC PUBLIC FUNCTION TabMesi() AS String[]
DIM tbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
RETURN tbMesi
END
.; poi per richiamare uno degli elementi, per Es. "Settembre", in qualsiasi procedura del progetto, scrivo:
Mese = TableMesi.TabMesi[8]
print Mese
Però non discosta molto dal mio utilizzo attuale:
STATIC PUBLIC $TabMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
che richiamo con:
$Mese = FMain.$TabMesi[8]
Print $Mese
Il modulo é effettivamente sempre presente in memoria, ma il mio Fmain che utilizzo per richiamare tutte le Form del Progetto con i vari richiami di tipo showmodal, tramite metodo _new, credo che sia sempre in memoria.
O no ? :-[
Aggiungo poi un'altra riflessione: La dichiarazione di una variabile globale é Public, mentre quella dichiarata nel modulo "TableMesi" é DIM, però quest'ultima appartiene ad una Function di tipo STATIC PUBLIC. Ma in pratica non occupa sempre una posizione di memoria, così come una variabile globale?
Insomma: Non é mollica, ma briciola. :)
Ciao
......, visto che hai accennato ad un esempio, invialo e lo vediamo... :ok:
Se proprio insisti, anche se ne abbiamo già parlato ampiamente nella discussione http://www.gambas-it.org/smf/index.php?topic=1259.0#lastPost (http://www.gambas-it.org/smf/index.php?topic=1259.0#lastPost), cerco di riassumere al meglio la mia messa in pratica dei tuoi preziosi consigli:
Dalla FMain chiamo la Form2 con:
DIM Frm2 AS Form2
DIM $_FrmParam AS NEW String[]
DIM i_SwReturn AS Integer
.................................
Frm2 = NEW Form2($_FrmParam)
i_SwReturn = Frm2.ShowModal()
La form2 prevede una serie di inserimenti di dati, alla fine di quali richiama ulteriormente la Form3 per le operazioni di chiusura con:
DIM i_SwReturn AS Integer
DIM $_FrmParam AS NEW String[]
DIM Frm3 AS Form3
'------------------------------------- CHIAMATA della Form3 col metodo nascoto -new ---------------------------------------------------
$_FrmParam.add(f_TotEntrOggi) 'cioé: $_FrmParam[0]
$_FrmParam.add(f_TotUscOggi) 'cioé: $_FrmParam[1]
$_FrmParam.add(Str(i_dataCont)) 'cioé: $_FrmParam[2]
Frm3 = NEW Form3($_FrmParam)
i_SwReturn = Frm3.ShowModal()
SELECT CASE i_SwReturn
CASE 1 'La giornata é stata chiusa con lo stato di "GIORNATA APERTA"
b_SwCloGG = TRUE 'La giornata contabile corrente é stata chiusa (bilanciata o non)
ME.Close(0)
CASE (99) 'Si é verificato un ERRORE dentro la Form3 - Il programma deve essere chiuso
ME.Close(99)
END SELECT
La form3 svolge il suo compito e, a seconda del risultato ottenuto, il controllo viene restituito alla Form2, oppure viene predisposto un ritorno direttamente alla FMain:
SELECT CASE Message.Error("TOTALI DI QUADRATURA ERRATI" & Chr(10) & Chr(10) & "Cosa vuoi fare ?", "Correggo e Ripeto la Chiusura", "Finisco, ma lascio la giornata 'APERTA'")
CASE 2
b_SwFrm3Clo = TRUE
ME.Close(1)
END SELECT
oppure:
ME.Close(0) 'chiude la Form senza compromettere quanto già digitato. Il controllo ritorna alla Form2.
oppure ancora:
ME.CLOSE(99) 'l'elaborazione viene interrotta a causa di della manifestazione di un ERRORE
Perciò al ritorno nella Form2, dopo una delle ME.Close(xx) della Form3, sopra accennate, la Form2 riprende il controllo ed a seconda del contenuto di i_SwReturn (vedi riga 09)
il controllo può:
a. rimanere alla Form2 (i_SwReturn = 0)
b. essere immediatamente restituito alla FMain (i_SwReturn = 1)
c. essere immediatamente restituito alla FMain che, a sua volta, con lo stesso procedimento di riconoscimento visto nella Form2, riconosce la presenza dell'anomalia e procede alla chiusura del programma (i_SwReturn = 99).
In tutto quello che ho riportato sopra, come avrai certamente notato, non ho assolutamente utilizzato variabili globali.
Che ne dici? Ho ben capito qualcosa sul taglio delle variabili globali? ;) :D :D
Ciao.
azz...complimenti...non ho capito ma apprezzo
In effetti nel codice che ho riportato manca un passaggio, cioé la presa in carico dei parametri passati da una Form all'altra, compito che viene svolto nel metodo _new della Form chiamata, ma non l'ho scritto per sintetizzare il più possibile l'esposizione a md9327.
Per ricondurre il concetto ad un livello di maggiore dettaglio, conviene abbandonare il riferimento alla chiamata in successione di due Form, che fa pensare alle scatole cinesi, e concentrarci sul concetto di passaggio di informazioni da una form ad un'altra e successivo ritorno.
Supponiamo che la FMain abbia bisogno di conoscere una data da una tabella di DB, per passarla poi ad un'altra Form. Guardiamo solamente il primo passaggio: per fare ciò viene richiesto il lavoro alla Form1, attraversdo il passaggio di un parametro, la presenza del crt "A" in una delle colonne della tabella del nostro DB.
La procedura scatenante la chiamata nella FMain dispone di:
DIM i_SwReturn AS Integer 'é il campo integer da interrogare subito dopo il ritorno del controllo-programma alla FMain, a fine lavoro della Form3.
DIM $_FrmParam AS NEW String[] 'é l'array che viene utilizzato per il passaggio delle informazioni alla Form chiamata e dove eventualmente vengono aggiunte altre informazioni di ritorno.
DIM Frm3 AS Form3
'-----bla-----bla-----bla-----
$FrmParam.add("A") 'cioé: $FrmParam[2]
Frm3 = NEW Form3($FrmParam)
iSwReturn = Frm3.ShowModal() 'modalità obbligatoria di chiamata del metodo _new della Form3.class
L'entrata nella Form3.Class avviene tramite il metodo new, con l'esecuzione della procedura _new. Essa contiene anche il seguente codice:
PUBLIC SUB _new($_TbParF3 AS String[])
Dim $_TabParF3 AS String[]
Dim $Como AS String
'<<<<<<<< Estrazione parametri passati dalla FMain >>>>>>>>
$TabParF3 = $TbParF3 'presa in carico dei parametri forniti da FMain
$Como = $TbParF3[0]
'<<<<<<<<<<<<<<< ° >>>>>>>>>>>
'-----bla-----bla-----bla-----
A fine lavoro la Form3 restituisce sia la data trovata che l'esito della ricerca, oppure se non trova la data, restituisce solamente l'esito negativo della ricerca:
-----bla-----bla-----bla-----
RecTab = DB_Connection.Exec(sql)
IF RecTab.Available THEN
$TabParF3.add(RecTab!Data) 'cioé $TabParF3[1]
Me.close(0)
else
Me.close(1)
endif
A questo punto la FMain riprende il controllo del programma e vengono eseguite le istruzioni poste subito dopo la chiamata della Form3, che non ho riportate sopra per dare la giusta sequenza logica delle istruzioni
-----bla-----bla-----bla-----
-----bla-----bla-----bla-----
-----bla-----bla-----bla-----
-----bla-----bla-----bla-----
-----bla-----bla-----bla-----
-----bla-----bla-----bla-----
-----bla-----bla-----bla-----
IF i_SwReturn = 0 THEN
$DataTabella = $FrmParam[1]
else
Message.Info("Data cercata non trovata")
endif
-----bla-----bla-----bla-----
Spero di essere riuscito nell'impresa. Descrivere un argomento appena conosciuto non é cosa facile.
Se non ci sono riuscito, ti chiedo scusa per la mia scarsa capacità; sicuramente ci sarà chi saprà ben illuminarci. :)
Ciao.
@md9327
Variabili array definite in <classe>.Tabella(), costanti definite in <classe>.Nome_costante! Quante begli strumenti ho scoperto oggi!
Mi spiego meglio dopo il tuo suggerimento sulla definizione di un array in una classe per rintracciarlo sempre senza impegnare memoria "globale", oggi guardando questo tuo post http://www.gambas-it.org/smf/index.php?topic=1356.msg15332#msg15332 (http://www.gambas-it.org/smf/index.php?topic=1356.msg15332#msg15332), mi sono deciso a fare una piccola prova, gridando: Abbasso le variabili globali. :D
Ho così affrontato uno alla volta i due temi:
1) per la definizione dell'array, ho:
- definito una classe che ho chiamato <Costanti>; in essa ho inserito la funzione che mi hai indicato più sopra, in questa discussione:
STATIC PUBLIC FUNCTION $TabMesi() AS String[]
DIM $TbMesi AS String[] = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
RETURN $TbMesi
END
Nel corpo del programma, ho prelevato il mese interessato con:
Costanti.$TabMesi()
$_Mese = Costanti.$TabMesi()[i_Mese]
E' vero che ho dovuto fare qualche prova, ma alla fine ce l'ho fatta, ed stato magnifico. ;D ;D
2) per la definizione delle costanti, ho cominciato con un piccolo, timido tentativo, definendo nella stessa classe di prima, <Costanti>, la mia prima costante non globale:
STATIC PUBLIC CONST $Prova AS String = "Io sono la costante $Prova"
che ho richiamato dentro la FMain.class con:
Ebbene, anche questa volta é stato un trionfo! ;D ;D
Grazie, md, ce l'hai fatta: sei riuscito a farmi capire anche l'uso dei suddetti strumenti. É stata dura ma hai vinto, quindi:
puoi stare tranquillo ed asciugarti il sudore per la fatica fatta. :rotfl: :rotfl:
Ciao.