Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VBA Classi e metodi oop - Esempi

481 views
Skip to first unread message

Pisinho

unread,
Apr 29, 2011, 4:57:55 AM4/29/11
to
Salve,
sto cercando esempi di Classi e metodi per imparare e capire soprattutto
cosa potrei fare realizzando delle classi di oggetti in VBA.

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

Popi - TheBadHabits

unread,
Apr 29, 2011, 5:05:43 AM4/29/11
to

Hai guardato sul sito di Alex?

www.alessandrobaraldi.it

Popi

Pisinho

unread,
Apr 29, 2011, 5:41:45 AM4/29/11
to

>
> Grazie a tutti e scusate se era già stato affrontato ma non trovo un
> granchè.

>Hai guardato sul sito di Alex?

>www.alessandrobaraldi.it

>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.

@Alex

unread,
Apr 29, 2011, 8:41:21 AM4/29/11
to

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

@Alex

unread,
Apr 29, 2011, 8:45:50 AM4/29/11
to
[Access] I Moduli di Classe

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

Alessandro Cara

unread,
Apr 29, 2011, 9:12:59 AM4/29/11
to
Il 29/04/2011 14.45, @Alex ha scritto:
[cut]

> Nello specifico però avremo HONDA, DUCATI ecc...
> Cosa differenzia l'Oggetto MOTOCICLETTA(Honda) dall'Oggetto
> MOTOCICLETTA(Ducati)...?

Sono uguali a meno del fatto che la prima la guida il "merda" e la
seconda "lamentino".

--

ac (x=y-1)

@Alex

unread,
Apr 29, 2011, 10:49:36 AM4/29/11
to
On 29 Apr, 15:12, Alessandro Cara <alessandro.c...@ay-1anetwork.it>
wrote:

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

AleC

unread,
May 3, 2011, 1:32:22 PM5/3/11
to
On 29 Apr, 16:49, "@Alex" <ik2...@libero.it> wrote:
> On 29 Apr, 15:12, Alessandro Cara <alessandro.c...@ay-1anetwork.it>
> wrote:
>
> > Il 29/04/2011 14.45, @Alex ha scritto:
> > [cut]
>
> > >      Nello specifico però avremo HONDA, DUCATI ecc...
> > >      Cosa differenzia l'OggettoMOTOCICLETTA(Honda) dall'Oggetto

> > > MOTOCICLETTA(Ducati)...?
>
> > 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

@Alex

unread,
May 3, 2011, 2:30:00 PM5/3/11
to
....

> 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

AleC

unread,
May 4, 2011, 9:59:36 AM5/4/11
to
Grazie @Alex
ci dò un'occhiata..

skipper

unread,
May 4, 2011, 10:18:32 AM5/4/11
to
"@Alex" <ik2...@libero.it> ha scritto nel messaggio
news:ce793252-8e11-4d92...@o26g2000vby.googlegroups.com...

> [Access] I Moduli di Classe
>

> 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...
:-)

0 new messages