Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Access > VBA Access
VBA Access Le forum pour les questions relatives au code VBA sous Access, et à son environnement de développement VBE.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 09/05/2011, 16h56   #1
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 124
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 124
Points : 26
Points : 26
Par défaut instanciation d'objet en vba

bonjour voici mon code
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
Do While Not sql.EOF
        Dim adsa As New adh_sal
        adsa.matsalarie = sql!matriculeSalarie
        adsa.mattiers = sql!matriculeTiers
        collec.Add adsa
        sql.MoveNext
    Loop
    sql.Close
    Set sql = Nothing
    For cpt = 1 To collec.Count
        MsgBox collec(cpt).matsalarie & " " & collec(cpt).mattiers & " " & cpt
        str = "select * from journee where matriculeSalarie = " & collec(cpt).matsalarie & " and matriculeTiers = ' & collec(cpt).mattiers & ' and jourPeriode>=#" & Format(d_deb, "MM/dd/yyyy") & "#And jourPeriode<=#" & Format(d_fini, "MM/dd/yyyy") & "#;"
        Set sql = CurrentDb().OpenRecordset(str)
        MsgBox sql.RecordCount
        Do While Not sql.EOF
            MsgBox sql!valeur & " " & sql!codeRubrique
            sql.MoveNext
        Loop
    Next cpt
mon problème c'est que lorsque je parcours ma liste je retrouve toujours les meme valeures dans ma msgbox "MsgBox collec(cpt).matsalarie & " " & collec(cpt).mattiers & " " & cpt" sauf que le compteur lui s'incrémente (normal ) . est ce que le problème viens d'une mauvaise instanciation ???
rominous41 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 17h35   #2
pgz
Expert Confirmé Sénior
 
Avatar de pgz
 
Homme Pierre GONZALEZ
Développeur Office VBA
Inscription : août 2005
Messages : 3 412
Détails du profil
Informations personnelles :
Nom : Homme Pierre GONZALEZ
Âge : 58
Localisation : France

Informations professionnelles :
Activité : Développeur Office VBA
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 412
Points : 5 934
Points : 5 934
Bonjour.

Tu as combien d'éléments dans collec? Collec.count vaut combien?


PGZ
__________________
pluritas non est ponenda sine necessitate - Le rasoir d'Okham
Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon
pgz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 18h00   #3
Rédacteur/Modérateur
 
Avatar de User
 
Homme Denis
Développeur informatique
Inscription : août 2004
Messages : 3 205
Détails du profil
Informations personnelles :
Nom : Homme Denis
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2004
Messages : 3 205
Points : 5 256
Points : 5 256
Salut Rominou et Pgz,

Il me semble qu'il te faut libérer ta variable après chaque passage de boucle :

Code :
1
2
3
4
5
6
7
8
9
10
11
 
Do While Not sql.EOF
    Dim adsa As New adh_sal
    adsa.matsalarie = sql!matriculeSalarie
    adsa.mattiers = sql!matriculeTiers
    collec.Add adsa
    sql.MoveNext
 
    Set adsa = Nothing
 
Loop
A+
__________________
Merci de ne pas poster sur mon profil pour des problèmes techniques. Pour celà vous pouvez utiliser le forum ou m'envoyer un mp.

Bon développement !


Mes tutoriels et contributions sur ma page perso:
Ma page personnelle
User est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 20h01   #4
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 124
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 124
Points : 26
Points : 26
mon collec.count vaut 68
rominous41 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 20h37   #5
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Bonsoir,

Tu n'as pas de ligne
dans ta boucle.

Donc dans ta collection tu ajoutes 68 fois la même référence (pointeur) au même objet.

Moi, j'écris plutôt de cette façon :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
' Déclaration de la variable objet
Dim adsa As adh_sal
'
Do While Not sql.EOF
        ' Instanciation d'un nouvel objet de type adh_sal et
        ' affectation d'une référence à ce nouvel objet
        ' à la variable objet adsa.
        Set adsa = New adh_sal
        '
        adsa.matsalarie = sql!matriculeSalarie
        adsa.mattiers = sql!matriculeTiers
        collec.Add adsa
        sql.MoveNext
Loop
A+
LedZeppII est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 20h43   #6
Expert Confirmé Sénior
 
Développeur informatique
Inscription : novembre 2006
Messages : 4 215
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : novembre 2006
Messages : 4 215
Points : 5 291
Points : 5 291
Bonjour,

Citation:
Envoyé par LedZeppII Voir le message
Moi, j'écris plutôt de cette façon :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
' Déclaration de la variable objet
Dim adsa As adh_sal
'
Do While Not sql.EOF
        ' Instanciation d'un nouvel objet de type adh_sal et
        ' affectation d'une référence à ce nouvel objet
        ' à la variable objet adsa.
        Set adsa = New adh_sal
        '
        adsa.matsalarie = sql!matriculeSalarie
        adsa.mattiers = sql!matriculeTiers
        collec.Add adsa
        sql.MoveNext
Loop
A+
Il ne faut pas oublier de faire set adsa=nothing avant le Loop sinon on va allouer de la mémoire inutilement.
Sur une boucle de 100 éléments ça peut passer par contre sur 100 000 d'une grosse bdd commerciale ça risque de poser des problèmes.
__________________
Alea Jacta Est
Mat.M est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 20h46   #7
Expert Confirmé Sénior
 
Développeur informatique
Inscription : novembre 2006
Messages : 4 215
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : novembre 2006
Messages : 4 215
Points : 5 291
Points : 5 291
Citation:
Envoyé par rominous41 Voir le message

mon problème c'est que lorsque je parcours ma liste je retrouve toujours les meme valeures dans ma msgbox "MsgBox collec(cpt).matsalarie & " " & collec(cpt).mattiers & " " & cpt" sauf que le compteur lui s'incrémente (normal ) . est ce que le problème viens d'une mauvaise instanciation ???
ton code est incroyablement compliqué il y a 2 boucles imbriquées.
D'abord éviter MsgBox et utiliser debug.print chaine_de_caracteres.

Ensuite si utilises des boucles imbriquées avec des recordset c'est que l'analyse du problème n'est pas optimale.
As-tu entendu parler des jointures en SQL pour un SELECT ?
Avec une bonne jointure tu n'utilises qu'un recordset.
__________________
Alea Jacta Est
Mat.M est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 21h33   #8
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Citation:
Envoyé par Mat.M Voir le message
Il ne faut pas oublier de faire set adsa=nothing avant le Loop sinon on va allouer de la mémoire inutilement.
C'est un peu le but de la boucle ... on veut allouer de la mémoire pour construire une Collection.

De plus set adsa=nothing avant Loop ne libère rien, puisqu'avant on a collec.Add adsa.

A+
LedZeppII est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 22h21   #9
Rédacteur/Modérateur
 
Avatar de User
 
Homme Denis
Développeur informatique
Inscription : août 2004
Messages : 3 205
Détails du profil
Informations personnelles :
Nom : Homme Denis
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2004
Messages : 3 205
Points : 5 256
Points : 5 256
Salut Christophe,

Dans l'aide Access ils parlent de supprimer la référence en cours :

Citation:
Add, méthode, exemple
Cet exemple utilise la méthode Add pour ajouter des objets Inst (instances d'une classe nommée Class1 contenant une variable Public InstanceName) à une collection nommée MyClasses. Pour voir comment fonctionne cette méthode, insérez un module de classe et déclarez une variable Public nommée InstanceName, au niveau du module de Class1 (tapez : Public InstanceName), qui contiendra les noms de chaque instance. Conservez Class1 comme nom par défaut. Copiez et collez le code suivant dans la procédure d'événement Form_Load du module de la feuille.
Code :
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
 
Dim MyClasses As New Collection    ' Crée un objet Collection.
Dim Num As Integer    ' Compteur destiné à individualiser les clés.
Dim Msg
Dim TheName    ' Variable contenant les noms que l'utilisateur spécifie.
Do
    Dim Inst As New Class1    ' Crée une nouvelle instance de Class1.
    Num = Num + 1    ' Incrémente Num d'une unité, puis insère un nom.
    Msg = "Veuillez affecter un nom à cet objet." & Chr (13) _
            & "Appuyez sur Annuler pour afficher les noms dans la " _
            & "collection."
    TheName = InputBox(Msg, "Nommez les éléments de la collection ")
    ' Affecte le nom à l'instance de l'objet.
    Inst.InstanceName = TheName
    ' Si l'utilisateur a tapé un nom, ajoute celui-ci à la collection.
    If Inst.InstanceName <> "" Then
        ' Ajoute l'objet nommé à la collection.
        MyClasses.Add item := Inst, key := CStr(Num)
    End If
    ' Supprime la référence en cours en prévision de la prochaine.
    Set Inst = Nothing
Loop Until TheName = ""
For Each x In MyClasses
    MsgBox x.instancename, , "Nom de l'instance"
Next
A+
__________________
Merci de ne pas poster sur mon profil pour des problèmes techniques. Pour celà vous pouvez utiliser le forum ou m'envoyer un mp.

Bon développement !


Mes tutoriels et contributions sur ma page perso:
Ma page personnelle
User est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 04h57   #10
Expert Confirmé Sénior
 
Développeur informatique
Inscription : novembre 2006
Messages : 4 215
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : novembre 2006
Messages : 4 215
Points : 5 291
Points : 5 291
Citation:
Envoyé par LedZeppII Voir le message
De plus set adsa=nothing avant Loop ne libère rien, puisqu'avant on a collec.Add adsa.

A+
ehhh non tu fais une erreur ;
le fait de déclare une variable de type classe quelconque avec une instruction Dim n'alloue pas du tout une instance de classe.
Sauf si tu déclare Dim nom_class as New ...comme le montre Denis.
Il faut faire new ensuite pour l'instancier.
Lorsque tu fais set nom_variable avec un new on incrémente une sorte de compteur de référence.

On peut omettre le set nom_variable=nothing parce que VBA détruit automatiquement les objets instanciés mais il est recommendé de le faire soi-même
__________________
Alea Jacta Est
Mat.M est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 09h09   #11
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 124
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 124
Points : 26
Points : 26
merci beaucoup c'est bien le set adsa = new adh_sal qu'il me manqué
rominous41 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 15h03   #12
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Salut Denis,

Citation:
Envoyé par User Voir le message
Dans l'aide Access ils parlent de supprimer la référence en cours :
Oui, c'est à cause du mot-clé optionnel New dans la déclaration de la variable objet.
Lorsque New est dans la déclaration, l'instanciation se fait de manière implicite.
C'est à dire que lorsque la variable objet (Inst) est utilisée, si elle ne pointe sur aucun objet (Nothing),
un Set Inst = New Class1 est fait de manière transparente.
C'est dans l'aide en ligne du mot-clé Dim.
L'exemple de l'aide Access exploite cette sorte de "régénération automatique" (ou instanciation automatique).

Dans mon code, la variable est déclarée sans le mot-clé New.
De ce fait, j'instancie de manière explicite avec Set MaVariable = New ClasseObjet .
A noter, qu'au passage suivant dans la boucle, cette même ligne de code ...
- crée un nouvel objet
- affecte la référence (pointeur) à ce nouvel objet à la variable objet.
- entraine la destruction de l'objet qui était précédemment référencé par la variable objet, à la condition que plus aucune référence à cet objet existe.
Dans le cas de rominous41, l'objet précédemment référencé n'est pas détruit car la Collection possède un élément avec une référence à cet objet.

D'une manière générale, je ne déclare jamais mes variables objets avec As New TypeObjet,
car cela m'empêche d'effectuer le test If MaVariableObjet Is Nothing .
Le fait de tester la variable objet instancie un nouvel objet si la variable est à Nothing.

A+
LedZeppII est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 16h34   #13
Rédacteur/Modérateur
 
Avatar de User
 
Homme Denis
Développeur informatique
Inscription : août 2004
Messages : 3 205
Détails du profil
Informations personnelles :
Nom : Homme Denis
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2004
Messages : 3 205
Points : 5 256
Points : 5 256
ok, merci,

Je ne connaissais pas toutes ces subtilités
__________________
Merci de ne pas poster sur mon profil pour des problèmes techniques. Pour celà vous pouvez utiliser le forum ou m'envoyer un mp.

Bon développement !


Mes tutoriels et contributions sur ma page perso:
Ma page personnelle
User est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 14h32   #14
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Salut Denis,

Tiens, je te mets un lien sur une discussion où Tofalu donne son avis et des explications sur la différence entre le New utilisé avec Dim ou avec Set.
A la base je voulais te répondre par ce lien, mais j'ai mis deux jours pour le retrouver.
Ce qui me rassure c'est que mon explication a l'air correcte.

Le lien vers la citation de Tofalu : Compare the speed of using Dim versus Dim As New.
Et un, vers une discussion sur Dim As New versus Set = New
Les deux méthodes ont leurs avantages et leur inconvénients, et c'est aussi fonction des préférences du programmeur.

Au fait, ton code était bon.
La différence avec le mien est que tu utilises l'instanciation implicite et moi l'instanciation explicite.

A+
LedZeppII est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 20h51   #15
Rédacteur/Modérateur
 
Avatar de User
 
Homme Denis
Développeur informatique
Inscription : août 2004
Messages : 3 205
Détails du profil
Informations personnelles :
Nom : Homme Denis
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2004
Messages : 3 205
Points : 5 256
Points : 5 256
Salut Christophe,

Donc d'après Tofalu la solution avec set serait plus rapide en terme d'exécution.

Citation:
Envoyé par LedZeppII Voir le message

Au fait, ton code était bon.
La différence avec le mien est que tu utilises l'instanciation implicite et moi l'instanciation explicite.

A+
Habituellement j'utilise la méthode explicite qui ai tout de même plus commune,
d'autant que comme tu le dis une nouvelle instanciation entraine la destruction de l'objet qui était précédemment référencé par la variable objet.

Mais là pour répondre à la discussion j'ai voulu me baser sur l'exemple de l'aide.
__________________
Merci de ne pas poster sur mon profil pour des problèmes techniques. Pour celà vous pouvez utiliser le forum ou m'envoyer un mp.

Bon développement !


Mes tutoriels et contributions sur ma page perso:
Ma page personnelle
User est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h03.


 
 
 
 
Partenaires

Hébergement Web