Qualcuno può postare degli esempi (qualsiasi tipo), link, etc per apprendere
meglio queste tecniche?
Fino ad ora ho realizzato tutto senza farne uso ma credo sia importante
conoscere anche queste tecniche per migliorare i programmi e renderli il più
possibile riutilizzabili in altre occasioni.
Grazie a tutti e scusate se era già stato affrontato ma non trovo un
granchè.
Saluti
>
> Grazie a tutti e scusate se era già stato affrontato ma non trovo un
> granchè.
>Hai guardato sul sito di Alex?
>Popi
SI, ma mi occorre roba da Dummies , anche se oggi a causa di Aruba non posso
accedere al sito di @Alex.
Essendo autodidatta per capire certi argomenti ci metto più tempo o è un
problema mio di ragionamento... forse sono davvero Dummie.....boh
Grazie lo stesso.
Questo è un tutorial per Dummie:
http://www.alessandrobaraldi.it/DettaglioFaq.asp?IdFAQ=286
Poi nel mio sito trovi, senza false modestie, veramente moltissimo di
alto livello... ovvio che sono esempi anche BANALI, ma servono
per capire molto bene proprio perchè incentrati su concetti Grafici
che per i meno addetti alla programmazione OOP rendono meglio...
Ciao
@Alex
INDICE:
PREMESSA
COSA SONO LE CLASSI
AGGIUNGERE AL PROGETTO UN MODULO DI CLASSE
ISTANZIARE UNA CLASSE
PROPRIETA'
METODI
EVENTI
ESEMPIO
CONCLUSIONI
PREMESSA
Questo breve articolo espone i concetti base per comprendere l'uso
dei Moduli di Classe.
Sono richieste conoscenze di base per la comprensione dei concetti
iniziali.
COSA SONO LE CLASSI
I Moduli di Classe sono sostanzialmente OGGETTI, contenitori con i
quali è possibile crearsi una struttura personalizzata
di Proprietà, Metodi ed Eventi.
Il vantaggio di questi oggetti è la riusabilità, vale a dire che
possono essere considerati Oggetti standard dei quali è
possibile creare molteplici copie in memoria(si chiamano ISTANZE)
e per ognuna di esse è possibile ridefinirne Proprietà e
sfruttarne Metodi ed Eventi.
Pensiamo all'Oggetto MOTOCICLETTA.
L'oggetto in sè è generico, si tratta di un veicolo a motore con 2
ruote.
Nello specifico però avremo HONDA, DUCATI ecc...
Cosa differenzia l'Oggetto MOTOCICLETTA(Honda) dall'Oggetto
MOTOCICLETTA(Ducati)...?
Le proprietà intrinseche del modello di cui la marca è già una di
queste [Honda/Ducati...].
Detto questo se noi ci creiamo un Contenitore MOTOCICLETTA e gli
associamo delle proprietà definibili, riusciremo,
personalizzandole a differenziare l'Oggetto MOTOCICLETTA(Honda) da
quello MOTOCICLETTA(Ducati).
In informatica il concetto di Oggetto è fondamentale da quando lo
sviluppo è Programmazione ad OGGETTI.
Avendo definito un Oggetto generico e, avendolo strutturato con
tutte le proprietà necessarie, non dovremo crearci
un oggetto per ogni Costruttore(Honda/Ducati...), ci basterà
aprire 2(n) volte lo stesso oggetto e per ognuno di questi
definire le proprietà in modo da differenziarli.
Abbiamo non solo risparmiato oggetti, ma abbiamo reso flessibile
il nostro lavoro, poichè se dovessimo aggiungere [Yamaha]
dovremo solo aprire un 3° oggetto...!
AGGIUNGERE AL PROGETTO UN MODULO DI CLASSE
La creazione vera e propria di una classe oggetti, avviene
aggiungendo un nuovo modulo classe al proprio database, a tale
scopo basta aprire l’editor di Visual Basic e selezionare dal menu
Inserisci la voce Modulo di classe.
Ogni modulo di classe VBA incorpora la proprietà Name che è parte
integrante della definizione di una classe oggetto,
proprio in quanto determina il nome stesso della classe.
L’associazione di un nome alla classe, avviene specificando il
nome della classe quando si salva per la prima volta il
modulo, oppure specificandolo nella finestra delle proprietà di
VBA.
ISTANZIARE UNA CLASSE
Per poter creare l’istanza di una nuova classe, bisogna dichiarare
la variabile oggetto basata sulla classe che verrà
utilizzata per la memorizzazione di un riferimento all’istanza di
una nuova classe.
Questo verrà eseguito per semplicità da una Maschera:
Codice:
Dim Moto as MOTOCICLETTA
Set Moto = New MOTOCICLETTA
Ora nella mia variabile [Moto] ho il riferimento all'istanza di
MOTOCICLETTA.
Per ora non ci posso fare nulla perchè non ho definito cosa questo
Oggetto può fare.
PROPRIETA'
Come dicevamo una Classe necessita di poter essere personalizzata,
questo si rende fattibile se la classe ha delle proprietà, ovvero
attributi dell'Oggetto.
Per esempio usiamo sempre la nostra MOTOCICLETTA, avrà come
proprietà:
- Marca
- Modello
- Cilindrata
- Diametro Cerchi
- Immatricolazione
Come facciamo a fare in modo di dotare la nostra classe di
Proprietà...?
Tramite le routine [Public\Private] Property Get e Property Let.
Con [Property Get] posso LEGGERE il valore della proprietà.
Con [Property Let] posso IMPOSTARE il valore della proprietà.
C'è anche una terza opzione [Property Set], che si usa quando la
proprietà
è un'oggetto complesso, ma è un concetto più avanzato.
Codice:
Option Compare Database
Option Explicit
' Definisco un Oggetto LABEL
Private m_Label As Access.Label
' Questo è il modo per passare un riferimento ad un’OGGETTO
Public Property Set ControlLabel(Lb As Access.Label)
Set btn = Lb
End Property
Inseriamo la Classe come spiegato e salviamola chiamandola
MOTOCICLETTA
Codice:
Option Compare Database
Option Explicit
Private m_Marca As String
Private m_Cilindrata As Integer
Private m_Immatricolazione As Date
Public Property Get Marca () as String
Marca= m_Marca
End Property
Public Property Let Marca (value as String)
m_Marca = value
End Property
Public Property Get Immatricolazione () As Date
Immatricolazione = m_Immatricolazione
End Property
Public Property Let Immatricolazione (value As Date)
m_Immatricolazione = value
End Property
Public Property Get Cilindrata() As Integer
Immatricolazione = m_Cilindrata
End Property
Public Property Let Cilindrata(value As Integer)
m_Cilindrata= value
End Property
Ora dalla nostra Form, nella quale abbiamo inserito l'ISTANZA
possiamo vedere lavorare l'INTELLISENSE sulle proprietà dell'oggetto:
Codice:
Option Compare Database
Option Explicit
Private Sub Prova()
Dim Moto1 as MOTOCICLETTA
Set Moto1 = New MOTOCICLETTA
' Scriviamo le proprietà dell'Oggetto Moto1
Moto1.Marca="HONDA"
Moto1.Immatricolazione=#01/01/2007#
Moto1.Cilindrata=1000
' Leggiamo le proprietà appena scritte
MsgBox "Marca = " & Moto1.Marca & vbcrlf & _
"Immatricolazione = " & Moto1.Immatricolazione & vbcrlf & _
"Cilindrata = " & Moto1.Cilindrata
End Sub
Se avessimo 2 moto dovremmo fare così:
Codice:
Option Compare Database
Option Explicit
Private Sub Prova()
Dim Moto1 as MOTOCICLETTA
Set Moto1 = New MOTOCICLETTA
Dim Moto2 as MOTOCICLETTA
Set Moto2 = New MOTOCICLETTA
' Scriviamo le proprietà dell'Oggetto Moto1
Moto1.Marca="HONDA"
Moto1.Immatricolazione=#01/01/2007#
Moto1.Cilindrata=1000
' Scriviamo le proprietà dell'Oggetto Moto2
Moto2.Marca="DUCATI"
Moto2.Immatricolazione=#01/05/2006#
Moto2.Cilindrata=990
End Sub
METODI
I metodi sono azioni che l'oggetto può compiere.
Per esempio, il nostro Oggetto MOTOCICLETTA potrà avere come
metodo:
- ACCELERA
- FRENA
I metodi sono espressamente rappresentati da Sub/Function, quindi
nel caso di Function avremo la possibilità di ricevere come valore di
ritorno una proprietà dell'oggetto, nel nostro caso, potrebbe
benissimo restituire la Velocità istantanea.
Modifichiamo la Classe:
Codice:
Option Compare Database
Option Explicit
Private m_Speed As Integer
Public Property Get Speed() As Integer
Speed= m_Speed
End Property
Public Property Let Speed(value as Integer)
m_Speed = value
End Property
Public Function Accelera() as Integer
m_Speed=m_Speed+1
' eseguiremo l'azione di accelerazione
' ......
Accelera=m_speed
End Function
Public Function Frena() as Integer
m_Speed=m_Speed-1
' eseguiremo l'azione di Frenata
' ......
Accelera=m_speed
End Function
Stessa cosa avremo per il metodo FRENA.
Dalla nostra Form avremo:
Codice:
Option Compare Database
Option Explicit
Private Sub Prova()
Dim Moto1 as MOTOCICLETTA
Set Moto1 = New MOTOCICLETTA
' Scriviamo le proprietà dell'Oggetto Moto1
Moto1.Marca="HONDA"
Moto1.Immatricolazione=#01/01/2007#
Moto1.Cilindrata=1000
' Ora eseguiamo l'azione e stampiamo il risultato
Debug.Print "VElocità = " & Moto1.Accelera
End Sub
EVENTI
I moduli di classe, definiscono solo due eventi, Initialize e
Terminate, rispettivamente associati alla creazione e alla distruzione
dell’istanza di una classe.
Codice:
Option Compare Database
Option Explicit
Private Sub Class_Initialize()
' Codice di Inizializzazione
' Normalmente si caricano i valori di DEFAULT
End Sub
Private Sub Class_Terminate()
' Codice di distruzione
' Normalmente si cancellano gli Oggetti interni
End Sub
Ricordiamo che la Creazione ha luogo solo con la definizione di
NEW [nomeClasse], e la distruzione quando impostiamo a Nothing
l'oggetto:
Codice:
Dim Moto1 as MOTOCICLETTA
' Ora ha origine l'EVENTO Initialize
Set Moto1 = New MOTOCICLETTA
Un concetto utile da ricordare è che tutti gli OGGETTI che si
istanziano è bene DISTRUGGERLI per liberare area di lavoro.
Le classi possono esporre, oltre che i 2 EVENTI nativi descritti
anche EVENTI personalizzati.
Pur non essendo esattamente una parte del modello di
programmazione degli oggetti, gli eventi sono un utile strumento che
permette a un oggetto di scambiare informazioni con il programma che
ha creato l’oggetto.
In altri termini, un evento è una subroutine residente nel
programma che ha crea-to l’oggetto, ed è chiamata dall’oggetto.
Un evento è una tecnica utile che elimina la necessità del
programma di monitorare costantemente le modifiche di un oggetto.
In questo modo, l’oggetto chiama l’evento per informare il
programma di una modifica allo stato dell’oggetto.
Modifichiamo la Classe:
Codice:
Option Compare Database
Option Explicit
Public Event Accelerazione(ByVal Speed As Integer)
Private m_Speed As Integer
Public Property Get Speed() As Integer
Speed= m_Speed
End Property
Public Property Let Speed(value as Integer)
m_Speed = value
End Property
Public Function Accelera() as Integer
m_Speed=m_Speed+1
' eseguiremo l'azione di accelerazione
' .....
RaiseEvent Accelerazione(m_Speed)
Accelera=m_speed
End Function
Come facciamo dalla nostra Maschera ad ereditare gli eventi
personalizzati...?
Innanzitutto l'oggetto dovrà essere dichiarato a livello di Modulo
nella Form e non di Routine, quindi inseriamo un CommandButton e su
Evento Click richiamiamo il METODO Accelera....:
Codice:
Option Compare Database
Option Explicit
Private WithEvents Moto1 as MOTOCICLETTA
' Ora magari su EVENTO LOAD generiamo l'ISTANZA
Private Sub Form_Load()
Set Moto1 = New MOTOCICLETTA
End Sub
Private Sub cmdAccelera_Click()
' Appena chiamato il METODO verrà scatenato l’EVENTO
' e riceveremo il MSGBOX
Moto1.Accelera
End Sub
Private Sub Moto1_Accelerazione(ByVal Speed As Integer)
MsgBox "Attento stai andando a " & speed & " Km/h"
End Sub
ESEMPIO
Per capire meglio il concetto facciamo un Esempio semplice.
Reallizziamo una Classe che, passando come riferimento una LABEL
mi gestisca l’effetto RILIEVO al passaggio del MOUSE.
Ovviamente costruiamo la Classe in modo che sia usabile da N Label
contemporaneamente.
Creiamo un NUOVO MODULO DI CLASSE chiamiamolo “clsLABEL”
Codice:
Option Compare Database
Option Explicit
' Tramite WithEvents eredito anche gli EVENTI dell’OGGETTO
Private WithEvents btn As Access.Label
Private Sub btn_MouseMove(Button As Integer, _
Shift As Integer, _
X As Single, _
Y As Single)
btn.SpecialEffect = 1
btn.FontWeight = 700
End Sub
Public Property Set ControlLabel(Lb As Label)
Set btn = Lb
' Siccome ho ereditato gli EVENTI devo ABILITARE quello che
' vogliamo usare: MOUSEMOVE
btn.OnMouseMove = "[Event Procedure]"
End Property
Property Get ControlLabel() As Access.Label
Set ControlLabel = btn
End Property
Ora nella nostra FORM creaiamo 2 LABEL chiamate Label1 e Label2.
Su Evento LOAD della Form creaiamo le 2 ISTANZE.
Codice:
Option Compare Database
Option Explicit
' Tramite WithEvents eredito anche gli EVENTI dell’OGGETTO
Private mc1 As clsLabelEffect
Private mc2 As clsLabelEffect
' Sfrutto l’Evento MOUSEMOVE del corpo per RESETTARE l’effetto
' sulle LABEL
Private Sub Corpo_MouseMove(Button As Integer, _
Shift As Integer, _
X As Single, _
Y As Single)
' Ripristino l’aspetto originale
mc1.ControlLabel.SpecialEffect = 0
mc1.ControlLabel.FontWeight = 400
mc2.ControlLabel.SpecialEffect = 0
mc2.ControlLabel.FontWeight = 400
End Sub
Private Sub Form_Load()
' Creo l’ISTANZA delle 2 Classi
Set mc1 = New clsLabelEffect
Set mc2 = New clsLabelEffect
Set mc1.ControlLabel = Me!Label1
Set mc2.ControlLabel = Me!Label2
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set mc1 = Nothing
Set mc2 = Nothing
End Sub
Salviamo la FORM ed apriamola provando a passare con il MOUSE
sulle LABEL.
Chiaramente questo è un esempio molto semplice e banale, ma
pensando alla flessibilità della tecnica probabilmente ora sarà più
facile intuirne i vantaggi.
CONCLUSIONI
Sono sicuro che risulterà discretamente incomprensibile a molti
l'utilità di quanto detto, proprio perchè i concetti sono un pò
sfuggevoli.
Per il resto valgono gli esempi del mio sito.
@Alex
Sono uguali a meno del fatto che la prima la guida il "merda" e la
seconda "lamentino".
--
ac (x=y-1)
Non sò chi sia il "merda" nè il "lamentino"... una volta il ruolo di
"lamentino" era di Biagi... ora non lo darai a Rossi...?
Tutto sommato mi pare che non si comporti male...
Con l'operazione alla spalla che ha avuto, ed io ne so qualche cosa in
quanto abbiamo avuto un intervento molto simile anche se lui ha 10
anni in meno, e ti assicuro che
anche andare in bicicletta non è banale...
@Alex
Ciao.....
questo thread mi capita a proposito........ stavo cercando appunto sul
web (non trovandolo) un modo per elencare le proprietà di un oggetto
creato da una classe.....
qualcosa del tipo
dim prp as property
dim cls as MyClass
set cls = New MyClass
for each prp in cls
debug.print prp.name & ": " & prp.value
next
si può fare ?
Avevo pensato ad una routine (visibile come metodo/funzione che
restituisce un array) che analizza il modulo e trova tutte le routine
Property Get e restituisce il nome e un metodo che restituisce ogni
valore delle proprietà, ma è un lavoro che spero sia inutile perché
c'è già qualcosa per fare la stessa cosa....
Ciao..
AleC
Si si può fare ma va implementato nella Classe un Metodo che attiva
una varType nascosta.
Guarda uno dei demo sulle classi che ho già suggerito, e che trovi nel
mio sito e vedi come fare...
In pratica va implementata questa:
Public Function NewEnum() As IUnknown
On Error GoTo Proc_Err
Set NewEnum = NomeClasse.[_NewEnum]
Proc_Exit:
Exit Function
Proc_Err:
Set NewEnum = Nothing
End Function
Ciao
@Alex
> Cosa differenzia l'Oggetto MOTOCICLETTA(Honda) dall'Oggetto
> MOTOCICLETTA(Ducati)...?
Che l'Oggetto MOTOCICLETTA(Honda) a fine procedura è come nuovo mentre
l'Oggetto MOTOCICLETTA(Ducati) ha perso molti byte ed è da riparare a caro
prezzo...
SKIPPER(Honda) dixit...
:-)