Newsgroup: it.comp.appl.access
Titolo: Intercettazione di eventi tramite i moduli di classe

Ciao, mi chiamo Fausto
Utilizzo assiduamente Access e VBA e avrei un questo quesito da porre:
Ho letto recentemente il manuale di Balena ("Programmare Visual Basic 6 - Ma
ho la versione ridotta quella dei "Portatili - Miti Informatica"- costa
meno!!)  e in un paragrafo relativo all'utilizzo dei moduli di classe ho
letto una cosa molto interessante circa la possibilità di intercettare,
tramite detti moduli, gli eventi per conto dei form.
Mi spiego meglio:
Ipotizziamo di avere un form di Access con una decina di controlli (per
esempio dei textbox). Il mio obbiettivo, è (banalizzo), ottenere che quando
un textbox perda il focus, lo sfondo della casella di testo diventi giallo.
Fino a qui nulla di difficile, è sufficiente impostare una procedura evento
per ciascun controllo sul rispettivo evento LostFocus e, nella routine
evento (che Access preimposta), scrivere il codice.
La rottura di scatole è che devo scrivere necessariamente la stessa cosa
dieci volte, quando potrei benissimo risparmiare tempo e scriverla una volta
sola.
In Visual Basic è sufficiente creare un modulo di classe, dichiarando una
variabile pubblica (per esempio Textbox) di tipo WithEvents. Per testare la
classe sarà poi sufficiente creare un form, una serie di controlli textbox,
creare nel modulo di form un oggetto che punta alla classe e assegnare alla
sua proprietà TextBox un riferimento a controlli del form. Il modulo di
classe, di conseguenza, consente di gestire gli eventi per conto dei form
intercettandoli. La logica di convalida dei miei textbox sarà così
incapsulata nel mio modulo di classe. Il vantaggio è che tale codice è
riutilizzabile anche in altri progetti.
Sebbene io utilizzi assiduamente Access e in particolar modo  VBA, non VB, e
consapevole del fatto che esistano sostanziali differenze tra i contesti di
applicazione dei due linguaggi (padre e figliastro) ho provato ad applicare
quanto riportato nel manuale di Balena con i seguenti risultati:
1) ho creato un modulo di classe cTextBox il cui codice è il seguente
Option Compare Database
'class module
Public WithEvents TextBox As TextBox
Private Sub TextBox_LostFocus()
    MsgBox "Ciao"
End Sub
2) nel modulo di Form
Option Compare Database
Dim t As cTextBox
Private Sub Form_Load()
   Set t = New cTextBox
   Set t.TextBox = Me.Testo1
End Sub
Il risultato è che il modulo di classe non intercetta gli eventi per conto
del form (al contrario che in Visual Basic versione standard, che, da me
testato, funziona)
3 ) Al contrario, se nel modulo di form imposto il seguente codice, la
classe intercetta gli eventi
Option Compare Database
Dim t As Classe2
Private Sub Form_Load()
   Set t = New Classe2
   Set t.TextBox = Me.Testo1
End Sub
Private Sub Testo1_LostFocus()
'
End Sub
Riflessione:
Il motivo per cui non scatta l'evento credo sia in linea con il
funzionamento di Access: il codice (del modulo di classe) non viene eseguito
in modo automatico quando scatta un evento; il codice (del modulo di classe)
vive in un mondo parallelo rispetto all'interfaccia (maschere e report)
tanto è vero che quando per esempio voglio creare un pulsante su una
maschera, access chiede all'utente se vuole creare codice o macro tramite
una creazione guidata!
Il codice al punto 3, pertanto, funziona esclusivamente settando la
proprietà del textbox a [Procedura Evento] (in questo caso LostFocus) senza
scrivere codice specifico (solo l'apostrofo). Conseguentemente Access
pensando che esista del codice associato all'evento, passa il controllo a
VBA il quale fa scattare l'evento e quindi lo passa alla classe....
Tutta questa brodaglia che ho scritto è per porre una domanda che mi sta
ossessionando da tempo:
Esiste un modo, in ACCESS,  per associare i textbox (o qualsiasi altro tipo
di controllo standard) alle classi personalizzate per gestirne gli
eventi??????????????????????????
Mi dicono di sì ma non vogliono darmi la soluzione, perchè dicono che devo
capirla da solo (un mio amico programmatore bastardone)...... ma purtroppo
sono ancora un pollo......
Grazie in anticipo!
Versione di Access: A00/W98
Ciao Fausto

 Ciao Fausto
Fausto ciao ben sentito
.
Prima di tutto un Controllo va dichiarato non tramite una Sub, ma tramite un
Property SET txt as Access.TextBox nel Modulo di Classe
poi gestisci l'Evento nel Modulo di Classe sull'Oggetto txt.
Dim WithEvents txt as Access.TextBox
Property Set Control(ctl as Access.TextBox)
    set txt=ctl
End Property
Dalla Form devi settarlo
Dim nc as New NomeClasse
set nc.Control=Me.NomeTextBox
Nella Classe gestisci:
Private Sub txt_OnFocus()
'..........
End Sub
In ogni caso quello che vuoi fare tu č BANALMENTE ottenibile impostando
in Struttura il Colore di Sfondo(es. ROSSO, poi impostandolo Trasparente)
In questo modo quando il Controllo prende il FOCUS diventa Rosso.
Spesso si cercano soluzioni DIFFICILI(come nel tuo caso) ma la soluzione
č molto piů vicina...!!!!!!!!!!!!
Ciao.
@Alex.

 ha scritto nel messaggio
news:c8tkno$k23$1...@lacerta.tiscalinet.it...

lo so ma volevo proprio quella difficile! ora provo, intanto grazie mille!
Ciao

 lo so ma volevo proprio quella difficile! ora provo, intanto grazie mille!
Comunque non scordarti di google:  "Access" + "withEvents"  produce
parecchia robetta ... e il primo link che vedo:
http://accessadvisor.net/doc/13276
E' semplice e abbastanza completo per capir bene come intercettare eventi in
Access.
Ti saluto.


Scusa se mi permetto, sono ancora qui a rompere le scatole, ma non riesco a
far funzionare il codice che mi hai indicato. Probabilmente sbaglio io, o
non ho capito qualcosa. Mi è venuto anche un grattacapo:  Innanzitutto
mentre io utilizzavo una variabile pubblica withevents, tu ne usi una
privata, ma non credo (nel mio piccolo) che ci sia differenza poichè, se si
utilizza una variabile privata  in un modulo di classe (al contrario che con
quelle pubbliche), ai fini della assegnazione di valori di proprietà o
proprietà oggetto, bisogna per forza utilizzare le sintassi property
let/get/set, (e la routine property get qui manca) Tali routine
irrobustiscono la classe e la proteggono da eventuali assegnazioni non
valide (per esempio stringhe vuote, e blablabla). Comunque, bando alla
filosofia, puoi verificare se sbaglio io o, al contrario, riverificare il
codice?
Ciao grazie ancora
Riscrivo il codice che ho scritto:
Nel modulo di classe "NomeClasse"
Option Compare Database
Option explicit
Dim WithEvents txt As Access.TextBox
__________________________________
Property Set Control(ctl As Access.TextBox)
    Set txt = ctl
End Property
__________________________________
Private Sub txt_LostFocus()
    MsgBox "Ciao"
End Sub
Nel modulo di form:
Option Compare Database
Option explicit
Dim nc As New NomeClasse
____________________________
Private Sub Form_Load()
Set nc.Control = Me.NomeTextBox
End Sub
____________________________

 Nel modulo di form:
.........
Se non dichiari anche il Callback dell'evento non
può funzionare.
Prova ad inserire il tutto, ma un'aiuto ulteriore può
dartelo il Link che ti ha indicato SS.
Ciao.
@Alex.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 ha scritto nel messaggio
news:72f039f8b9c7374c45...@mygate.mailgate.org...

Ok, ora funziona, grazie mille dell'aiuto a te e a S.Savoldi
Ciao!