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

VBA Access Discussion :

Problème de désassignation en mémoire ? Des idées ?


Sujet :

VBA Access

  1. #1
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut Problème de désassignation en mémoire ? Des idées ?
    Bonjour à tous et merci de votre temps et de votre aide.

    J'ai un problème assez bizare sur une de mes applications.
    J'ai un sous-formulaire que affiche 6 images parmis une liste d'images.
    Cette liste peut contenir de 0 à environ 500 images actuellement.
    Ces images sont associées à une référence et j'ai environ 30 000 références.
    Le but est de permettre à l'utilisateur de visualiser ses images par pages de 6 une fois la référence choisie.

    Ceci est pour remplacer la librarie de arkham46 :
    Le contrôle Liste d'images - CtrlImageList
    https://arkham46.developpez.com/arti...ctrlimagelist/
    qui fait bien plus que ce dont j'ai besoin et qui nécessite l'utilisation d'un fichier externe et qui est plus lente à l'affchage que ma solution.

    Au départ j'utilisais une collection de modules de classe (objet en VBA) pour stoker en mémoire cette liste.
    Ensuite, à cause de bugs, j'en suis venu à utiliser un recordset ADO déconnecté.
    Et comme cela bugait aussi, j'ai finalement utiliser 4 tableaux en parallèles.

    Dans toutes les solutions, je ne stocke que le chemin d'accès à l'image qui est ensuite chargée dans un contrôle image.
    Donc à un momment données je n'ai "physiquement" au maximum que 6 images.

    Dans tous les cas j'ai eu des bugs très étranges après "certain nombre" d'affichages, les pires ont été avec le recordset ADO.
    Le certain temps semble relié à la taille des images. Si mes images sont grosses, il survient plus tôt, sinon plus tard mais jamais toujours au même endrois.

    Dans ma 1ère solutons avec la collection, Access mélange joyeusement les images entre les références. Ex, il m'affiche 3 images d'une référence, 4 d'une autre et parfois certaines de la référence choisie.

    Dans la 2nd solution avec le recordser, Access retourne des informations incohérentes comme le fait que le recordset est fermé alors que mon code demande de l'ouvrir 2 ligne plus tôt.

    Dans la 3ième, Access semble ignorer ou ne pas compléter mes redimentionnement de tableau.
    Ex : je demande un redim de 1 à 4 et Access ne redimensionne que de 1 à 2.
    Si je passe en mode débug, et que je ramène l'execution en arrière puis exécute pas à pas, la redimension se fait bien, donc pas de bugs dans le code lui-même.

    Bref on dirait que Access "sous-traite" la gestion de la mémoire à Windows mais qu'il n'attend pas que cette gestion soit complétée pour continuer ce qui fait que le code et l'objet en mémoire ne sont pas synchrone.
    Note qu'ajouter un après les redim DoEvent ne change rien.

    J'aimerai savoir si quelqu'un a déjà rencontré et solutionné ce genre de problème.

    à toute fin utilise voici un extrait du code que j'utilise.

    Les variables de module :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Option Compare Database
    Option Explicit
     
    Private m_ListeImage_Support() As String
    Private m_ListeImage_Repertoire() As String
    Private m_ListeImage_Nom() As String
    Private m_ListeImage_Extension() As String
     
    Const NUM_IMAGE_PAGE As Long = 6
    Zone du bug :
    C'est dans cette portion de code que le bug se manifeste, au moment du chargement après les redim.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    Public Sub ChargerImage(prmRImage As dao.Recordset)
        'Attention cette procédure modifie ses paramètres
     
        '=== Détermine le nombre d'images
        Dim nbImage As Long
     
        If Not prmRImage.EOF Then
            prmRImage.MoveLast
        End If
     
        nbImage = prmRImage.RecordCount
     
        If prmRImage.RecordCount <> 0 Then
            prmRImage.MoveFirst
        End If
        '--- Détermine le nombre d'images
     
        '=== Dimentionne les tableaux pour y stocker les chemins d'accès.
        If nbImage <> 0 Then
                ReDim m_ListeImage_Support(1 To nbImage)
                ReDim m_ListeImage_Repertoire(1 To nbImage)
                ReDim m_ListeImage_Nom(1 To nbImage)
                ReDim m_ListeImage_Extension(1 To nbImage)
            Else
                ReDim m_ListeImage_Support(0)
                ReDim m_ListeImage_Repertoire(0)
                ReDim m_ListeImage_Nom(0)
                ReDim m_ListeImage_Extension(0)
        End If
        '--- Dimentionne les tableaux pour y stocker les chemins d'accès.
     
        Call EffacerPage 'Vide les contrôles images utilisés pour l'affichage.
        Me.NumPage = 0
        Me.NumMaxPage = 0
     
        Dim infoImage As CInfoFichier
     
        '=== Charge les images
        Dim numSequence As Long: numSequence = 0
     
        Do While Not prmRImage.EOF
            Set infoImage = New CInfoFichier
            infoImage.SupportRepertoire = prmRImage![RepertoireImage]
            infoImage.NomExtension = prmRImage![Image]
     
            numSequence = numSequence + 1
            m_ListeImage_Support(numSequence) = infoImage.Support
            m_ListeImage_Repertoire(numSequence) = infoImage.repertoire
            m_ListeImage_Nom(numSequence) = infoImage.Nom
            m_ListeImage_Extension(numSequence) = infoImage.Extension
     
            Set infoImage = Nothing
            prmRImage.MoveNext
        Loop
        '--- Charge les images
     
        '=== Calcul le nombre de pages
        ' Arrondi au dessus
        If numSequence Mod NUM_IMAGE_PAGE = 0 Then
                Me.NumMaxPage = numSequence \ NUM_IMAGE_PAGE
            Else
                Me.NumMaxPage = (numSequence \ NUM_IMAGE_PAGE) + 1
        End If
        '--- Calcul le nombre de pages
     
        If Me.EstAvecImage Then
            Me.NumPage = 1
        End If
     
        Call NumPage_AfterUpdate
     
    Exit_ChargerImage:
        Exit Sub
     
    End Sub
    Si vous avez de question n'hésitez pas.

    Bonne année.
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  2. #2
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Meilleurs voeux pour 2019, Marot

    une idée parmi d'autres : fais-tu un .Close du recordset utilisé prImage car apparemment c'est lui qui libére la mémoire du recordset (plus que le SET .. = Nothing) ?

    CDLT
    "Always look at the bright side of life." Monty Python.

  3. #3
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour micniv et merci de ta suggestion.

    Le recordset prmRImage fourni les données et reste ouvert car je m'en ressert au niveau du dessus.

    Mon problème se situe avec la copie locale en mémoire des données du recordset.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur VBA Access
    Inscrit en
    Avril 2006
    Messages
    1 109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur VBA Access

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 109
    Points : 1 535
    Points
    1 535
    Par défaut
    Bonjour,

    as-tu essayé de voir ce qui se passe avec la fonction EffacerPage() ?

  5. #5
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    EffacerPage() se contente de remettre les infos des contrôle image à 0 (propriété Picture à "" et Visible false).

    Elle ne touche pas la source de donnés.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Mon problème se situe avec la copie locale en mémoire des données du recordset.
    Je ne vois pas la recopie en local du recordset vue que par défaut les objets passés en paramètres à une méthode ce font par références.

    Un objet passé par recopie de valeur n'a pas besoin d'être détruire vue que sa durée de vie etc...

    Public Sub ChargerImage(Byval prmRImage As dao.Recordset l) 'Attention avec Byval cette procédure ne modifie pas ses paramètres
    Dernière modification par Invité ; 05/01/2019 à 15h33.

  7. #7
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Un objet ByVal ?!
    Je suis dubitatif : pour moi un objet n'est passé que par référence.

    Pour débugger ce genre de truc, je mets des debug.print, moins intrusifs que des points d'arrêt qui déclenchent beaucoup de choses.

  8. #8
    Invité
    Invité(e)
    Par défaut
    ByRef par référence, ByVal par valeur.

    https://social.msdn.microsoft.com/fo...byval-et-byref

  9. #9
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Citation Envoyé par dysorthographie Voir le message
    ByRef par référence, ByVal par valeur.

    https://social.msdn.microsoft.com/fo...byval-et-byref
    Oui mais un lien vb.net ne m'intéresse guère.
    Je ne comprends pas l'intérêt ici de passer en byVal.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Problème de désassignation en mémoire
    C'est pas grave peut-être que marot_r comprendra et si ce n'est pas le cas oublié ce que j'ai dit!

    Mais de ce que j'ai crue comprendre marot_r pense faire une recopie de son RecordSet alors qu'il le passe en ByRef implicite et pas en recopie de valeur ByVal!
    Vba vb.net c'est pareil pour ce qui concerne ByVal, Byref.
    Dernière modification par Invité ; 06/01/2019 à 10h38.

  11. #11
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Citation Envoyé par dysorthographie Voir le message
    Mais de ce que j'ai crue comprendre marot_r pense faire une recopie de son RecordSet alors qu'il le passe en ByRef implicite et pas en recopie de valeur ByVal!
    C'est justement là mon interrogation.
    Un objet byVal c'est quoi ? VBA fait-il un clone de l'objet ? J'ai un doute.

  12. #12
    Invité
    Invité(e)
    Par défaut
    Fais un test.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Sub test()
    Dim t as integer
    t=1
    ParRef t
    Msgbox t
    ParVal t
    Msgbox t
    End sub
    Sub ParRef(ByRef I as integer)
    I=I+1
    End sub
    Sub ParVal(ByVal I as integer)
    I=I+1
    End sub

  13. #13
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Oui mais là c'est un integer, ce n'est pas un objet.

  14. #14
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Bonjour Marot,
    Je me suis permis de récrire le début de ton code et de rassembler les declarations au début, c'est plus lisible.
    Je ne vois rien de problematique sinon que je me méfierais de redim avec des 1 to N , car redim ne modie que les dimensions supérieures

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    Public Sub ChargerImage(prmRImage As DAO.Recordset)
        'Attention cette procédure modifie ses paramètres
     
        Dim nbImage As Long    '  nombre d'images
        Dim infoImage As CInfoFichier
        Dim i As Long
     
        If prmRImage.Recordset = 0 Then
            Exit Sub
        Else
            prmRImage.MoveLast
            prmRImage.MoveFirst
            nbImage = prmRImage.RecordCount
     
            '=== Dimensionne les tableaux pour y stocker les chemins d'accès.
            ReDim m_ListeImage_Support(1 To nbImage)
            ReDim m_ListeImage_Repertoire(1 To nbImage)
            ReDim m_ListeImage_Nom(1 To nbImage)
            ReDim m_ListeImage_Extension(1 To nbImage)
     
            Call EffacerPage    'Vide les contrôles images utilisés pour l'affichage.
            Me.NumPage = 0
            Me.NumMaxPage = 0
     
            '=== Charge les images
            For i = 1 To nbImage
                Set infoImage = New CInfoFichier
                infoImage.SupportRepertoire = prmRImage![RepertoireImage]
                infoImage.NomExtension = prmRImage![Image]
     
                m_ListeImage_Support(i) = infoImage.Support
                m_ListeImage_Repertoire(i) = infoImage.repertoire
                m_ListeImage_Nom(i) = infoImage.Nom
                m_ListeImage_Extension(i) = infoImage.Extension
     
                Set infoImage = Nothing
                prmRImage.MoveNext
           Next i
     
            '---  Calcul le nombre de pages
            ' Arrondi au dessus
            If nbImage Mod NUM_IMAGE_PAGE = 0 Then
                Me.NumMaxPage = nbImage \ NUM_IMAGE_PAGE
            Else
                Me.NumMaxPage = (nbImage \ NUM_IMAGE_PAGE) + 1
            End If
     
            If Me.EstAvecImage Then
                Me.NumPage = 1
            End If
            Call NumPage_AfterUpdate
     
        End If
     
    Exit_ChargerImage:
        Exit Sub
     
    End Sub
    CDLT
    "Always look at the bright side of life." Monty Python.

  15. #15
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Arkham46 Voir le message
    Oui mais là c'est un integer, ce n'est pas un objet.
    En fait ici on est confronté au théorème de retour vers le future. Puis je modifier le continuum espace temps?

    Un Recordset comme dans la problématique de marot_r fait référence via une requête à une table.

    Si dans ma méthode je fais un update de la copie de mon recordset, je ne modifie pas le recordset de la fonction appelante mais la table et par ricoché la RS appelant.

    Mais un movenext n'interagi.

  16. #16
    Responsable Access

    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Points : 14 524
    Points
    14 524
    Par défaut
    Citation Envoyé par dysorthographie Voir le message
    En fait ici on est confronté au théorème de retour vers le future. Puis je modifier le continuum espace temps?
    Je passe.
    Bon courage.

  17. #17
    Invité
    Invité(e)
    Par défaut
    Ok mais une dernière chose.

    Si tu fais à partir d'un module de classe,pour le coup on est en objet, tu verras qu'il n'y à pas d'interaction entre les deux objet.

    En résumé ByVal ne modifie pas la variable passé en paramètres quelque soit sont type Objet ou pas.

    Mais peut modifier les données sources des objets fournir en paramètres.
    Dernière modification par Invité ; 06/01/2019 à 13h19.

  18. #18
    Invité
    Invité(e)
    Par défaut
    En suivant l'idée de dysortho, je plussoie une conjecture entre le problème de Marot_r et l'expérience du chat de Schrödinger

  19. #19
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par galoir Voir le message
    En suivant l'idée de dysortho, je plussoie une conjecture entre le problème de Marot_r et l'expérience du chat de Schrödinger
    J'avais pris retour vers le future mais c'est exactement ça!

  20. #20
    Membre expérimenté
    Homme Profil pro
    Développeur VBA Access
    Inscrit en
    Avril 2006
    Messages
    1 109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur VBA Access

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 109
    Points : 1 535
    Points
    1 535
    Par défaut
    Bonjour,

    J'ai oublié de vous souhaitez une joyeuse nouvelle année à tous.

    Que se passe-t-il quand tu redimensionnes le tableau par un Redim Preserve dans la boucle de chargement ?

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/12/2013, 16h39
  2. Réponses: 2
    Dernier message: 20/08/2004, 17h10
  3. Réponses: 9
    Dernier message: 17/01/2004, 10h51
  4. Gestion mémoire des Meshes (LPD3DXMESH)
    Par [Hideki] dans le forum DirectX
    Réponses: 1
    Dernier message: 08/07/2003, 20h34

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