Mémoire insuffisante

Résolu/Fermé
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015 - 29 avril 2013 à 10:42
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015 - 30 avril 2013 à 15:10
Bonjour à tous,

actuellement stagiaire je dois réaliser un module de gestion des doublons de la base de donnée de mon entreprise. Je travaille sous Access 2007 et j'ai pour le moment bien avancé dans le projet (J'ajoute à une table Nomtable_doublon les doublons de la table Nomtable puis je supprime les doublons de NomTable avant de réajouter après traitement tous les doublons unitaires dans Nomtable à partir de Nomtable_doublon).
Le programme fonctionne correctement jusqu'à ce qu'il m'affichage une erreur mémoire insuffisante la base de donnée est peut être endommagée...
De ce que j'ai pu récolter sur internet ça serait dû au fait que je dépasse les 2Go (malgré le fait que je compacte la base de donnée avant tout traitement), j'ai essayé de fractionner la base de données mais après vérification la taille de la base de donnée contenant les formulaires n'a pas diminuée.
Auriez-vous une idée de comment résoudre mon problème de mémoire ? Ferais-je mal le traitement? Pourrais-je augmenter la mémoire maximum ?

D'avance merci.
Uryon.

6 réponses

Sugel Messages postés 4070 Date d'inscription jeudi 18 août 2011 Statut Membre Dernière intervention 19 juin 2017 724
29 avril 2013 à 10:48
0
Sugel Messages postés 4070 Date d'inscription jeudi 18 août 2011 Statut Membre Dernière intervention 19 juin 2017 724
29 avril 2013 à 10:49
D'autres disent de créer une nouvelle base en important tout le contenu de l'ancienne.
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
29 avril 2013 à 11:16
J'ai du mal expliqué, je peux démarrer Access sans soucis, le problème a lieu lorsque j'éxécute le programme (au bout d'un certains temps de traitement, j'ai conclu que c'était quand le fichier dépassait les 2Go)
0
Sugel Messages postés 4070 Date d'inscription jeudi 18 août 2011 Statut Membre Dernière intervention 19 juin 2017 724
29 avril 2013 à 11:18
Je n'ai absolument aucune connaissance Access, mais ne peut-tu pas fragmenter ce programme ? Histoire de contourner cette limitation ?
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
29 avril 2013 à 11:28
C'est la solution que j'experimente actuellement en ayant trouvé un post sur ce forum mais j'avoue que ce n'est pas très propre et cela pose un problème au niveau de l'ouverture.
Sauf si je me trompe à chaque fois qu'Access éxécute un programme en rapport avec une table liée il ouvre et referme la base liée, ce qui rajoute du temps de traitement je crois et étant donné que le traitement est déjà relativement long j'aurais aimé une meilleure alternative.
0
Bonjour,
Les tutoriels disent habituellement que la capacité maxi de Access est de 1Go voire 750 Mo . Le seul moyen qui te reste est de fragmenter, par exemple les tables sur l'une, les requêtes, formulaires, états, etc sur l'autre.
Bonne suite
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
29 avril 2013 à 11:32
Actuellement j'ai fractioné la base en deux : L'une contient les tables de base et l'autre toutes les tables, requêtes et formulaires contenant le traitement, on verra si ça fonctionne correctement si vous me dites qu'il n'y a pas d'autre solutions.
Merci à vous.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
blux Messages postés 26000 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 3 289
29 avril 2013 à 11:39
Salut,

tu fais tes modifs avec quelle méthode : requêtes standard ou requêtes en VBA avec/sans journalisation (commit/rollback) ?
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
Modifié par Uryon le 29/04/2013 à 11:53
Alors excusez moi mais je ne suis que débutant donc je ne connais pas exactement les termes...
Pour effectuer les modifications j'ai choisi de parcourir un recordset contenant tous les doublons (Avec un identifiant unique pour chaque ligne), je crée alors deux recordsets : L'un contenant la première itération du doublon, le deuxième la seconde je passe les détails de priorité des données mais en clair si un champ du premier est nul alors je remplace par la valeur du deuxième. Je met donc à jour ce premier doublon avant de passer au doublon suivant, en mettant à jour le deuxieme recordset,
si le premier et le troisieme sont des doublons alors on recommence la manip
si le premier et le troisieme ne sont pas des doublons alors je remplace le premier par le troisieme et je passe au suivant
Ainsi de suite jusqu'à la fin du fichier.
Quand un doublon est à supprimer (ici ce serait le deuxieme par exemple) je l'ajoute à une table, si il est à garder (le premier) je le met dans une autre.
A la fin du programme j'ajoute à la table de base les doublons que j'ai conservé.
0
blux Messages postés 26000 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 3 289
29 avril 2013 à 12:28
Il est donc probable que les mises à jour multiples provoquent une inflation des pointeurs de gestion de la base.
Il serait intéressant de mettre quelques 'commit' pour voir si le comportement est le même...
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
29 avril 2013 à 12:32
Je suis allé fouiner un peu sur internet et j'ai trouvé que les "commit" avaient rapport à des transactions mais je ne sais pas ce que c'est et je n'ai pas trouvé...
De ce que j'ai pu comprendre le "commit" sert à effectuer les modifications désirées sur les enregistrement c'est ça?
0
blux Messages postés 26000 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 3 289
29 avril 2013 à 12:47
Le commit sert à garantir une cohérence dans les mises à jour multiples. C'est la base d'une transaction ACID.
Je mettrais un peu de commit mais avant je remettrais les objets recordset à zéro de temps en temps.
Il serait quand même intéressant qu'on voie ton code pour se faire une idée de ce qu'il est possible de faire pour éviter ce problème.
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
29 avril 2013 à 12:50
Je met le code juste après ce message.
J'ai réussi à trouver un site m'expliquant l'utilité des transactions.
Le problème c'est qu'ici, selon certains critères (Date de saisie, ID la plus élevée, valeur d'un champ) je dois modifier certains champs (Si un champ est vide, nulle ou égal à 0 on le remplace par l'autre afin de ne pas perdre de données) je pense donc ne pas pouvoir utiliser les transactions dans ce cas car elles ne me permettraient pas de modifier seulement une partie de la ligne non?
0
Uryon Messages postés 73 Date d'inscription lundi 29 avril 2013 Statut Membre Dernière intervention 21 janvier 2015
Modifié par Uryon le 29/04/2013 à 13:15
'Permet de supprimer les doublons en fonction du telephone_standard 
Private Sub dbl_telephone_Click() 
Dim db As Database 
Set db = CurrentDb() 
Dim idPrec As String 'ID de la societe qu'on gardera 
Dim IdActu As String 'ID de la societe qu'on supprimera 
Dim sql As String 
Dim rs As Recordset 
Dim rsPrec As Recordset 
Dim rsActu As Recordset 
Dim rsPostal As Recordset 
Dim rsSaisiePrec As Recordset 
Dim rsSaisieActu As Recordset 
Dim compteur As Long 
Dim modif As Boolean 
Dim i As Integer 
Dim signaprec As Integer 
DoCmd.SetWarnings False 'Permet de supprimer les avertissements lors de la modification, l'ajout, la suppression.... 


DoCmd.RunSQL ("Delete * from doublonagarder;") 
DoCmd.RunSQL ("Delete * from societe_doublon;") 
'Insert dans societe_doublon les doublons en fonction du telephone_standard 
DoCmd.RunSQL ("Insert INTO societe_doublon select * FROM societe WHERE (((societe.telephone_standard) In (SELECT [telephone_standard] FROM [societe] As Tmp GROUP BY [telephone_standard] HAVING Count(*)>1 ))) order by telephone_standard, id_societe DESC;") 

'Initialisation 
compteur = 0 
modif = False 

Set rs = db.OpenRecordset("Select * FROM societe_doublon order by telephone_standard, id_societe DESC") 
If rs.EOF = True Then 
    MsgBox ("Il n'y a pas de doublons de sociétés ") 
Else 
    rs.MoveFirst 
    idPrec = rs!id_societe 'On donne à idprec l'id_societe du premier enregistrement 
    rs.MoveNext 
    'Boucle qui parcourt toute la Base de données 
    Do While rs.EOF = False 
        IdActu = rs!id_societe 
        sql = "Select * FROM societe_doublon WHERE id_societe=" & idPrec & ";" 
        Set rsPrec = db.OpenRecordset(sql) 'Ligne qu'on gardera (idprec) 
        sql = "Select * FROM societe_doublon WHERE id_societe=" & IdActu & ";" 
       Set rsActu = db.OpenRecordset(sql) 'Ligne qu'on supprimera (idactu) 
       signaprec = rsPrec!signaletique_ok 
        'Si le telephone_standard est identique alors 
        If rsPrec!telephone_standard = rsActu!telephone_standard Then 
            'ETAPE 1 : RsPrec est la ligne qu'on gardera, si un de ses champs est vide on le remplace par celui de RsActu 
            rsPrec.Edit 
                For i = 1 To rsPrec.Fields.Count - 3 
                    If IsNull(rsPrec.Fields(i).Value) = True Or rsPrec.Fields(i).Value = "" Or rsPrec.Fields(i).Value = 0 Then 
                        rsPrec.Fields(i).Value = rsActu.Fields(i).Value 
                    End If 
                Next i 
            rsPrec!signaletique_ok = signaprec 
            rsPrec.Update 
            'FIN DE L'ETAPE 1 
             
            'ETAPE 2 : On vérifie les signaletique_ok 
            'On vérifie que signaletique_ok de rsActu est égal à 1, si c'est le cas et que celui de rsPrec est 0 alors on remplace les champs de rsPrec par ceux de rsActu 
            If rsPrec!signaletique_ok = 0 And rsActu!signaletique_ok = 1 Then 
                modif = True 
            End If 
             
            'Si signaletique_ok de rsprec et de rsActu ont la même valeur 
            If (rsPrec!signaletique_ok = 1 And rsActu!signaletique_ok = 1) Or (rsPrec!signaletique_ok = 0 And rsActu!signaletique_ok = 0) Then 
            Set rsSaisieActu = db.OpenRecordset("Select date_saisie FROM actions WHERE id_societe=" & IdActu & " ORDER BY date_saisie DESC;") 'Date de saisie de rsActu 
            Set rsSaisiePrec = db.OpenRecordset("Select date_saisie FROM actions WHERE id_societe=" & idPrec & " ORDER BY Date_saisie DESC;") 'Date de saisie de rsPrec 
            'On vérifie que rsprec et rsActu ont une date de saisie 
                If rsSaisiePrec.EOF = False And rsSaisieActu.EOF = False Then 
                rsSaisiePrec.MoveFirst 
                rsSaisieActu.MoveFirst 
                    'Si la date de saisie de RsActu est plus récente que celle de rsPrec alors on remplace les champs de rsprec par ceux de rsactu 
                    If rsSaisiePrec!date_saisie < rsSaisieActu!date_saisie Then 
                        modif = True 
                    End If 
                End If 
            rsSaisieActu.Close 
            rsSaisiePrec.Close 
            End If 
            'FIN DE L'ETAPE 2 
            'ETAPE 3 : On modifie les champs de rsPrec par ceux de rsActu si il le faut 
            If modif = True Then 
                rsPrec.Edit 
                    For i = 1 To rsPrec.Fields.Count - 3 
                        If IsNull(rsActu.Fields(i).Value) = False And rsActu.Fields(i).Value <> "" And rsPrec.Fields(i).Value <> 1 Then 
                            rsPrec.Fields(i).Value = rsActu.Fields(i).Value 
                        End If 
                    Next i 
                rsPrec.Update 
            End If 
            'FIN DE L'ETAPE 3 
            'ETAPE 4 : On vérifie que si le pays est la France, alors le code postal concorde avec les deux premiers numéros du telephone_standard 
            If rsActu!pays = "France" Then 
                sql = "Select * FROM TablePostal WHERE code_Postal='" & Left(rsPrec!code_postal, 2) & "';" 
                Set rsPostal = db.OpenRecordset(sql) 'Ligne contenant l'indice téléphonique pour le code postal du rsPrec 
                If rsPostal.EOF = False Then 
                    'Si l'indice du téléphone et le code postal ne correspondent pas alors on remplace le code postal de rsPrec par celui de rsActu 
                    If Left(rsPrec!tel2, 2) <> rsPostal!indice_tel Then 
                        rsPrec.Edit 
                            rsPrec!code_postal = rsActu!code_postal 
                            rsPrec!ville = rsActu!ville 
                        rsPrec.Update 
                        rsPostal.Close 
                    End If 
                'Si le code postal de rsPrec ne correspond à aucun indice de téléphone alors on remplace le code postal de rsPrec par celui de rsActu 
                Else 
                    rsPrec.Edit 
                        rsPrec!code_postal = rsActu!code_postal 
                        rsPrec!ville = rsActu!ville 
                    rsPrec.Update 
                    rsPostal.Close 
                End If 
            End If 
            'FIN DE L'ETAPE 4 
             
            rsPrec.Close 
            rsActu.Close 
            DoCmd.RunSQL ("Update societe_doublon SET doublon=1 WHERE id_societe=" & IdActu & ";") 
            DoCmd.RunSQL ("Update societe_doublon SET doublon=2 WHERE id_societe=" & idPrec & ";") 
            compteur = compteur + 1 
            DoCmd.RunSQL ("Insert INTO TableCorrespondance (ID_ancienne,ID_nouvelle) values (" & IdActu & "," & idPrec & ");") 
        Else 
            'Si ce n'est pas un doublon alors on donne à idprec la valeur d'idactu 
            rsPrec.Close 
            rsActu.Close 
            idPrec = IdActu 
        End If 
    rs.MoveNext 
    Loop 
End If 
rs.Close 
DoCmd.RunSQL ("Insert INTO DoublonAjeter Select * FROM societe_doublon WHERE doublon=1 AND id_societe NOT IN (Select ID_societe FROM doublonajeter);") 
DoCmd.RunSQL ("Insert INTO DoublonAgarder Select *  FROM societe_Doublon WHERE doublon=2 AND id_societe NOT IN (select id_societe FROM doublonagarder);") 
DoCmd.RunSQL ("Delete * from societe WHERE id_societe IN (Select id_societe FROM societe_doublon);") 
DoCmd.RunSQL ("Insert INTO societe select * from doublonagarder;") 
MsgBox ("Il y a eu " & compteur & " doublons supprimés") 

End Sub
0