IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB 6 et antérieur Discussion :

Copier un objet en VB


Sujet :

VB 6 et antérieur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    753
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 753
    Par défaut Copier un objet en VB
    Bonjour.

    Je bosse sur un modèle objet complexe pour fabriquer une machine de guerre d'optimisation. J'ai réussi à pas mal me débrouiller avec l'aide interne de VB (qui explique pas très bien je trouve, surtout au niveau de la conception des objets justement), en lisant un ou deux tutos quelque part sur le web, et en utilisant ma patience de programmeur et mon expérience dans d'autres langages.

    Seulement là, je suis tombé sur un affreux problème: j'ai besoin de créer des copies de certains objets, mais je ne trouve pas de méthode "simple" qui me permette de faire cela. Je tiens à faire des copies et non pas des références pour que mon modèle objet fonctionne correctement.

    Je vous pose alors cette question: existe-t-il un gentil mot clé ou un truc pour faire une copie, ou alors est-ce que je vais devoir passer beaucoup de temps à implémenter des méthodes plus ou moins lourdes et complexes pour copier les attributs et sous-objets un à un?

    Merci à ceux qui vont me répondre.

    EDIT: et sinon j'ai remarqué qu'on a beau préciser qu'un objet doit être passé en ByVal à une procédure, elle travaille quand même avec la référence, ce qui est la source de mon problème. Ca c'est marqué nulle part dans l'aide de VB.

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Bonjour,

    Qu'est exactement (description précise, pour en connaître le type) ton objet à copier ?

  3. #3
    Membre Expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 72
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Par défaut
    Perso, je crée un nouvel objet et je copie les données une à une

    Pas vraiement glop, il y a probablement une thecnique possible avec une copie mémoire, mais j'ai jamais osé m'y attaquer

  4. #4
    Rédacteur
    Avatar de DarkVader
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    2 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 131
    Par défaut
    Je ne comprends pas bien le problème - une simple copie tient dans sa déclaration avec New.

    exemple de clonage d'un object (ici form1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        Dim copyObject As New Form1
     
        Debug.Print Form1.Caption, copyObject.Caption
        copyObject.Caption = "newCaption"
        Debug.Print Form1.Caption, copyObject.Caption
        Set copyObject = Nothing
    où alors je n'ai encore pas compris la question.

  5. #5
    Membre Expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 72
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Par défaut
    C'est exactement ce que je fais, on crée une nouvelle instance et on copie chaque propriété de la premiere instance sur la deuxieme instance.
    Je pense que ce que voudrait decondelite, c'est une methode qui permettrait une copie de toutes les propriétés de la premiere instance sur la deuxieme et ce, quelque soit l'objet. Quelque chose comme

    Copy PremInstance,DeuzInstance

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    753
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 753
    Par défaut
    EDIT: tu as posté pendant que je tapais mon looooong discours.
    Oui c'est exactement ce genre de fonctionnalité que je veux: qu'on puisse faire comme avec les variables classiques. C'est pas forcément une méthode, mais n'importe quoi qui fasse l'affaire: méthode, mot clé, fonction, [strike]procédure[/strike], ...



    J'avais pas osé le dire, mais "new" n'est pas du tout la réponse à mon problème.

    Ce que je veux, c'est créer une copie d'un objet déjà présent en mémoire, et non pas créer une nouvelle instance du type de mon objet.

    Mon objet à copier, à vrai dire il ne s'agit pas que d'un seul type d'objet. Je préférais dans un premier temps ne pas vous parler de mon modèle objet vu qu'il est plus ou moins complexe (en revanche il n'est pas dur à comprendre).
    Je travaille avec des classes que j'ai créé moi-même, et mon modèle est donc:

    -Un objet de type "BanqueGammes" contenant:
    -une référence à un objet Gammes
    -une référence à l'objet Gamme actif
    -une référence à l'objet Phase actif
    -Un objet de type "Gammes" contenant
    -un tableau dynamique de type Gamme
    -un attribut Entite de type Gamme qui renvoie donc une gamme selon son index dans le tableau (ou son attribut AffaireSousDossier)
    -un attribut Nombre (je suppose que vous devinez ce qu'il fait)
    -un attribut EstVide
    -un attribut Parent
    -méthodes Ajouter,Supprimer
    -Un objet de type "Gamme" contenant:
    -les infos générales de la gamme
    -une référence à un objet de type Phases
    -une référence à la phase active
    -un attribut Parent
    -méthodes Activer,Supprimer
    -Un objet de type "Phases" contenant:
    -un tableau dynamique de type Phase
    -attributs Entite, Nombre, EstVide, Parent
    -méthodes Ajouter,Supprimer
    -Et pour finir un objet de type "Phase" contenant:
    -les infos de la phase
    -un attribut Parent
    -méthodes Activer,Supprimer

    Vous devinez qu'il s'agit de tout un système pour mettre en mémoire des informations sur la production d'un certain nombre de produits. Il va me servir à travailler dessus sans me prendre la tête (enfin une fois que le modèle objet sera au point) et ainsi faire de l'optimisation de planning (un truc coriace étant donné qu'en plus des soucis de programmation le fonctionnement de la boîte en lui-même est lui aussi complexe).

    Vous me direz "pourquoi as-tu construit ça comme ça?". La réponse est assez simple: je tenais à ne pas utiliser d'objet de type Collection, car un de leurs défauts c'est qu'on peut pas déclarer d'attribut par défaut.

    Or je tiens à ce qu'une fois mes objets créés, je puisse faire dans mon code par exemple:
    -MaBanque.Gammes pour utiliser l'ensemble des gammes
    -MaBanque.Gammes(numero_de_gamme) pour une gamme en particulier
    Ca ça marche je l'ai mis au point

    Tout ce que je vous ai décrit fonctionne (il m'a fallu bien 4-5 jours de boulot pour mettre ça au point en tenant compte du fait que j'ai galéré pour comprendre comment VB gérait la création de types personnalisés), sauf 2-3 petits trucs bien gavants.

    J'ai un souci sur un point en particulier: c'est lors de l'ajout d'une gamme (ou phase) ou lors de l'activation d'une phase.
    J'utilise une méthode d'ajout de 2 manières différentes:
    -MaBanque.Gammes.Ajouter : ajoute une gamme vide (avec les infos par défaut et c'est là qu'intervient New)
    -MaBanque.Gammes.Ajouter(gamme_a_ajouter): ajoute le gamme renseignée

    C'est sur la deuxième que je pêche. Je compte utiliser une copie de la gamme renseignée (on peut la renseigner par son numero ou par la valeur d'un de ses attributs ou encore par la gamme elle-même) et non pas une référence à l'originale.
    Or le problème, comme je vous l'ai déjà dit, c'est que j'ai beau utiliser une gamme en ByVal comme argument optionnel (l'argument est de type variant pour permettre de donner le numero,l'attribut ou la gamme), cette saleté de méthode travaille quand même avec la référence (allez savoir pourquoi: moi je sais pas comment les concepteurs de VB on codé et ce n'est qu'un malheureux constat).

    Quand j'insère une nouvelle gamme, pas de souci je déclare l'argument comme étant une "Set nouvelle_gamme=New Gamme".
    Mais quand je travaille avec une gamme déjà existante, en gros ma nouvelle gamme devient une référence à la gamme déjà en mémoire. Et ça c'est pas bon puisque je veux une copie de la gamme renseignée, sinon dès que je touche à l'une fatalement je touche également à l'autre.

    Et j'ai le même problème avec les phases (le fonctionnement de l'objet Gamme et celui de l'objet Phase on beaucoup de similitudes: vive le copier/coller/adapter et le fonction rechercher/remplacer c'est fou le temps qu'on gagne).

    Pour d'éventuelles suggestions, voici la méthode pour ajouter une gamme:
    Code Code de la méthode d'ajout d'une gamme : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    ' Méthode ajoutant une gamme et renvoyant l'indice de la gamme ajoutée
    Public Function Ajouter(Optional ByVal nouvelle_gamme As Gamme) As Integer
        ' Création d'une nouvelle gamme si pas de gamme donnée
        If nouvelle_gamme Is Nothing Then
            Set nouvelle_gamme = New Gamme
        End If
        Ajouter = Nombre + 1
        ' Agrandissement du tableau des gammes d'une gamme
        ReDim Preserve gamme_gammes(Ajouter)
        ' Insertion de la nouvelle gamme
        Set gamme_gammes(Ajouter) = nouvelle_gamme
        ' Déclaration du parent
        Set gamme_gammes(Ajouter).Parent = Me
        ' Activation automatique de la gamme ajoutée
        gamme_gammes(Ajouter).Activer
    End Function
    J'ai mis pas mal de commentaires pour qu'une fois que j'aurai fini mon stage il ne reste pas incompréhensible (je leur ferai également une doc). Je vous rappelle que Nombre est un attribut donnant le nombre de gammes dans le tableau dynamique de gammes (qui est un champ privé de l'objet Gammes dans lequel se trouve la présente méthode).

    Voilà, si vous avez une autre solution que de créer des méthodes "Copie" dans un petit peu tous mes objets (vu que pour copier une gamme il faut copier ses attributs, mais aussi l'ensemble de phases et donc une copie de chacune des phases etc...), je suis entièrement ouvert à toutes propositions ça me permettrait de m'affranchir d'un jour de boulot inutile.

    Sachant que l'ajout d'une gamme active automatiquement la gamme ajoutée, pareil pour les phases, j'ai ce code qui déconne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    ' Ceci est un code me servant à tester mon modèle objet
    ' je vous propose pas de l'essayer sinon VB risque d'être déçu :P
    ' il va de 10 en 10 automatiquement à chaque création de phase
    Set banque_gammes = New BanqueGammes
        banque_gammes.Gammes.Ajouter
        banque_gammes.Gammes.Ajouter
        banque_gammes.Gammes(1).Phases.Ajouter
        banque_gammes.GammeActive.Phases.Ajouter
        banque_gammes.Gammes(1).Phases.Ajouter
        banque_gammes.Gammes(1).Phases.Ajouter
        banque_gammes.Gammes(1).Phases.Supprimer (20)
        banque_gammes.Gammes(2).Activer
        banque_gammes.GammeActive.Phases.Ajouter
        banque_gammes.GammeActive.Phases.Ajouter
        banque_gammes.GammeActive.Phases.Ajouter
        banque_gammes.GammeActive.Phases.Ajouter
        banque_gammes.GammeActive.Phases.Ajouter
        banque_gammes.GammeActive.Phases.Ajouter
        ' banque_gammes.GammeActive.PhaseActive.Numero = 13
        banque_gammes.GammeActive.Phases(40).Activer
        banque_gammes.GammeActive.PhaseActive.Numero = 35
        banque_gammes.Gammes(1).Activer
    ' Tout fonctionne bien jusqu'ici, en gros ce code m'a servi à tester "gentiment" mes méthodes et propriétés
    ' Mais avec cette ligne tordue qui suit (pour tester "méchament" comme un gros tordu) j'ai un souci de référence
    ' Ici, je cherche à ajouter le contenu de la phase active de la gamme 2 à une nouvelle phase de la gamme active qui est la gamme 1
        banque_gammes.GammeActive.Phases.Ajouter (banque_gammes.Gammes(2).PhaseActive)
        banque_gammes.PhaseActive.Numero = 25
        ' et à ce stade devinez quoi: je me retrouve avec la phase active de la gamme 2 qui se prend le numéro 25, alors que c'est pas ce que j'ai demandé à VB, et on a là une preuve que VB se contrefiche de ByVal quand l'argument est un objet

    Voilà. Désolé si c'est pas évident à avaler, mais quand on me demande "on peut savori comment c'est fait", je réponds pas à moitié. Si vous voulez je vous paye de l'aspirine pour vous aider.

    EDIT: finalement je me suis résigné à faire des méthodes de copie... encore heureux que ça ne m'aie pris qu'une demi-heure à toutes les programmer...

  7. #7
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Argentine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 173
    Par défaut
    salut

    j'ai enlevé le tag résolu car le problème n'est pas résolu, même si tu as trouvé un workaround.

    Par ailleurs, je ne comprends pas que personne n'aie réagit à "byval se comporte comme byref"

    Je n'ai jamais eu ce problème, tu as un souci quelque part.
    Vu l'usine à gaz, je suis certain qu'au niveau de ton "active" ou ailleurs y'a un problème, un mélange entre refs et nouveaux objects ...

Discussions similaires

  1. Réponses: 11
    Dernier message: 29/09/2008, 10h57
  2. copier un objet (instance ?)
    Par panthere_noire dans le forum Général Python
    Réponses: 16
    Dernier message: 20/09/2008, 23h32
  3. Copier un objet par valeur ?
    Par Totanne dans le forum VB.NET
    Réponses: 4
    Dernier message: 25/03/2008, 14h22
  4. [C#]Comment puis-je copier un objet ?
    Par lanuage dans le forum C#
    Réponses: 12
    Dernier message: 03/11/2006, 20h11
  5. Copier des objets d'un formulaire à un autre en VBA
    Par vincentdacol dans le forum Access
    Réponses: 1
    Dernier message: 24/04/2006, 14h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo