IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Pierre Fauconnier

Copier un objet perso en VBA, pas si simple!

Noter ce billet
par , 25/10/2021 à 20h32 (1130 Affichages)
Copier une variable object en VBA revient à créer un clone de cet objet, mais encore faut-il qu'il le permette



Salut

- Pierre, j'ai passé un objet ByVal à une procédure, mais quand je modifie la variable copiée, l'original est aussi modifié... Au secours!!
- Toi, tu as essayé de copier un objet...
- Ben oui, Y a rien dans le VBA pour copier un objet, faut bien se débrouiller, mais là, on dirait que mon code se fout du byVal
- Et tu sais pourquoi?
- ...
- Parce qu'effectivement, le VBA se fout de ByVal lorsque tu l'utilises pour un objet. Autrement dit, ByRef ou ByVal, c'est kif pour un objet
- Ok. Et comment je fais pour copier l'objet, moi?



Deux variables, un même objet

imaginons une classe perso très simple, oTest:
Code vba : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
Option Explicit
 
Public Color As String

Examinons l'exécution du code suivant:

Nom : 2021-10-25_192843.png
Affichages : 277
Taille : 12,7 Ko


Que va-t-il se passer après l'exécution de la ligne en jaune? Quelle sera la couleur myObject? "Bleu" ou "Rouge"? La réponse est "Rouge"!

Nom : 2021-10-25_193101.png
Affichages : 233
Taille : 11,9 Ko

Explications

Lorsque l'on affecte une variable objet à une variable, on ne crée pas de copie, mais bien un "pointeur" vers le même objet, c'est-à-dire le même emplacement mémoire.

Nom : 2021-10-25_193813.png
Affichages : 231
Taille : 77,3 Ko


Copie via une fonction avec argument ByVal

Dans l'intro, mon pote me disait avoir essayé un ByVal pour passer une "copie" de l'objet. En effet, passage d'argument à une fonction est ByRef par défaut, ce qui signifie que l'on passe la variable à la fonction. Si l'on passe l'argument par ByVal, on passe en fait une copie. Si vous examinez le code ci-dessous, vous voyez que a a été modifié, mais pas b, passée en ByVal.

Nom : 2021-10-25_194658.png
Affichages : 260
Taille : 35,8 Ko


Ce fonctionnement n'est cependant valide que pour des variables primaires. Pour les objets, le passage d'arguments est toujours ByRef, même si vous le spécifiez ByVal.

Nom : 2021-10-25_195051.png
Affichages : 231
Taille : 43,5 Ko


Conclusion provisoire

VBA n'expose pas d'outil pour copier un objet. si l'on veut copier un objet, il faudra écrire une procédure qui s'en chargera.


Clonage procédural

On comprendra ici que j'ai volontairement simplifié l'objet. Un objet informatique contiendra souvent plusieurs propriétés qu'il faudra copier. J'ai à peine complexifié la classe pour attribuer un nom à l'objet qui sera "en lecture seule", afin de modéliser les cas qui pourront se présenter à vous. Voici le code adapté de notre classe oTest

Code vba : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
Option Explicit
 
Public Color As String
 
Private mName As String
 
Sub Init(Name As String)
  mName = Name
End Sub
 
Property Get Name() As String
  Name = mName
End Property

Voici l'exécution d'une procédure de copie de l'objet

Nom : 2021-10-25_200030.png
Affichages : 241
Taille : 69,8 Ko

On constate donc ici qu'il y a bien eu copie, la ligne Set Copy = New oTest ayant créé un objet vide qui a été valorisé. MyObject est resté bleu alors myObject2 est devenu rouge.


Copie "orientée objet"

Tant qu'à créer une classe perso, autant y intégrer la procédure de copie, qui est souvent nommée Clone. Elle procédera de la même façon que la procédure vue plus haut

Nom : 2021-10-25_202525.png
Affichages : 217
Taille : 60,3 Ko


Dans la mesure ou Name ne peut être adapté que via Init, on pourrait imaginer que le clone recoive un nouveau nom
Code vba : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
Property Get Clone(Optional Name As String) As oTest
  Set Clone = New oTest
  With Clone
    .Init IIf(Name = "", mName, Name)
    .Color = Color
  End With
End Property

Nom : 2021-10-25_202907.png
Affichages : 213
Taille : 54,3 Ko


Conclusions

Comme on le voit, la copie d'un objet doit être pensée et sera normalement prévue au sein de l'objet pour respecter l'orientation objet d'une part, et rendre le module de classe autonome par rapport à une procédure de copie externe.

Bon travail avec vos classes perso

Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Viadeo Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Twitter Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Google Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Facebook Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Digg Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Delicious Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog MySpace Envoyer le billet « Copier un objet perso en VBA, pas si simple! » dans le blog Yahoo

Mis à jour 26/10/2021 à 05h35 par Pierre Fauconnier

Catégories
VBA , MS Office

Commentaires