Fallo de memoria insuficiente
Resuelto
Uryon
Mensajes publicados
77
Estado
Miembro
-
Uryon Mensajes publicados 77 Estado Miembro -
Uryon Mensajes publicados 77 Estado Miembro -
Hola a todos,
actualmente soy pasante y debo realizar un módulo de gestión de duplicados en la base de datos de mi empresa. Trabajo con Access 2007 y por ahora he avanzado bien en el proyecto (añado a una tabla Nomtable_doublon los duplicados de la tabla Nomtable, luego elimino los duplicados de NomTable antes de volver a añadir, tras el procesamiento, todos los duplicados unitarios en Nomtable desde Nomtable_doublon).
El programa funciona correctamente hasta que me aparece un error de memoria insuficiente; la base de datos podría estar dañada… Según lo que he podido recoger en Internet, podría deberse a que supero los 2 GB (a pesar de que compactuo la base de datos antes de todo tratamiento). Intenté fragmentar la base de datos, pero tras comprobarlo el tamaño de la base de datos que contiene los formularios no disminuyó. ¿Tendríais alguna idea de cómo resolver mi problema de memoria? ¿Estoy haciendo mal el procesamiento? ¿Podría aumentar la memoria máxima?
De antemano, gracias.
Uryon.
Configuración: Windows 7 / Chrome 26.0.1410.64
actualmente soy pasante y debo realizar un módulo de gestión de duplicados en la base de datos de mi empresa. Trabajo con Access 2007 y por ahora he avanzado bien en el proyecto (añado a una tabla Nomtable_doublon los duplicados de la tabla Nomtable, luego elimino los duplicados de NomTable antes de volver a añadir, tras el procesamiento, todos los duplicados unitarios en Nomtable desde Nomtable_doublon).
El programa funciona correctamente hasta que me aparece un error de memoria insuficiente; la base de datos podría estar dañada… Según lo que he podido recoger en Internet, podría deberse a que supero los 2 GB (a pesar de que compactuo la base de datos antes de todo tratamiento). Intenté fragmentar la base de datos, pero tras comprobarlo el tamaño de la base de datos que contiene los formularios no disminuyó. ¿Tendríais alguna idea de cómo resolver mi problema de memoria? ¿Estoy haciendo mal el procesamiento? ¿Podría aumentar la memoria máxima?
De antemano, gracias.
Uryon.
Configuración: Windows 7 / Chrome 26.0.1410.64
6 respuestas
-
-
Tengo dificultades para explicarlo: puedo iniciar Access sin problema, el problema ocurre cuando ejecuto el programa (después de cierto tiempo de procesamiento, concluí que es cuando el archivo supera los 2 GB)
-
-
Es la solución que estoy experimentando actualmente tras haber encontrado un post en este foro, pero confieso que no es muy limpio y que plantea un problema a nivel de apertura.
A menos que me equivoque, cada vez que Access ejecuta un programa relacionado con una tabla vinculada, abre y cierra la base vinculada, lo que añade tiempo de procesamiento, creo, y dado que el procesamiento ya es relativamente largo, me gustaría una mejor alternativa.
-
-
Hola,
Los tutoriales suelen decir que la capacidad máxima de Access es de 1 GB e incluso 750 MB. La única opción que te queda es dividir, por ejemplo, las tablas en una, las consultas, formularios, informes, etc. en la otra.
Bonne suite -
Actualmente he dividido la base en dos: una contiene las tablas básicas y la otra todas las tablas, consultas y formularios que contienen el procesamiento; veremos si funciona correctamente si me dicen que no hay otras soluciones.
Gracias a ustedes. -
Hola,
¿con qué método haces tus modificaciones: consultas estándar o consultas en VBA con/sin registro (commit/rollback)?
--
A+ blux"Los tontos se atreven a todo. Es precisamente eso lo que los distingue"
-
Lo siento, pero no soy más que un principiante, así que no conozco exactamente los términos...
Para realizar las modificaciones elegí recorrer un recordset que contiene todos los duplicados (con un identificador único para cada fila). Así que creo dos recordsets: Uno que contiene la primera ocurrencia del duplicado, el segundo la segunda. Paso a detallar la prioridad de los datos, pero explicado de forma clara, si un campo del primero es nulo, lo sustituyo por el valor del segundo. Por lo tanto, actualizo este primer duplicado antes de pasar al siguiente duplicado, actualizando el segundo recordset.
si el primero y el tercero son duplicados entonces volvemos a realizar la operación
si el primero y el tercero no son duplicados, entonces sustituyo el primero por el tercero y paso al siguiente
Así sucesivamente hasta el final del archivo.
Cuando se debe eliminar un duplicado (aquí por ejemplo el segundo), lo añado a una tabla; si debe conservarse (el primero), lo pongo en otra.
Al final del programa añado a la tabla de base los duplicados que he conservado.-
-
-
El commit sirve para garantizar la coherencia en las actualizaciones múltiples. Es la base de una transacción ACID.
Pondría un poco de commit pero antes volvería a dejar los objetos recordset a cero de vez en cuando.
De todos modos sería interesante que veamos tu código para hacernos una idea de qué es posible hacer para evitar este problema. -
Pongo el código justo después de este mensaje.
He logrado encontrar un sitio que me explica la utilidad de las transacciones.
El problema es que aquí, según ciertos criterios (Fecha de captura, ID más alta, valor de un campo) tengo que modificar ciertos campos (Si un campo está vacío, nulo o igual a 0 lo reemplazo por el otro para no perder datos) así que creo que no podré usar transacciones en este caso porque no me permitirían modificar solo una parte de la fila, ¿verdad? -
"
'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"
-