En este grupo En todos

Foro de Excel



Memoria recargada al correr macro

willan
Curso de baterias: acumuladores eléctr...
Escrito por Willan Villamil Salcedo
el 11/06/2012

Hola amigos del foro:

Nuevamente recurriendo a ustedes para que alumbren mi camino con la luz de su entendimiento.

Tengo una aplicación bastante grande en las cuales corren muchas macros. Todo va bien hasta ahí. Pero hay una macro en especial que genera un reporte muy útil, la cual el usuario puede ejecutarla en más de una ocasión en el transcurso de la sesión. La ejecución de esta macro, que dicho sea de paso, es muy grande, dura alrededor de 3 minutos. Creo haber depurando y perfeccionado el código dentro de lo razonable; es decir desactivé el recálculo automático, la actualización de pantalla, desactivé los eventos, etc.

Que dure 3 ó 5 minutos no es el problema, lo consideramos razonable y lo aceptamos. El problema es que al parecer la memoria RAM queda recargada para cuando se vuelva a ejecutar la misma macro y tarda para la segunada vez el doble de tiempo que la primera, y si se la ejecuta una tercera vez tarda el doble de tiempo que la segunda vez y así sucesivamente en progresión geométrica. He vaciando el portapapeles al final del procedimiento y no mejora ni un ápice. Tengo que reinicial Excel para que todo vuelva a la normalidad.

¿Alguien tiene alguna idea de cómo descargar la memoria después de ejecutar una macro grande?


Cacho Rodríguez
Ingeniería electrónica universidad nac...
Escrito por Cacho Rodríguez
el 15/06/2012

Evidentemente los códigos desarrollados no alcanzan a liberar memoria eficientemente.

Habría que ver si utilizas los:
- Erase
- Set XXX = Nothing
- Si sólo utilizas las fórmulas necesarias en lugar de llenar de fórmulas las hojas.
- Si no tienes más formatos condicionales que los estrictamente necesarios, y no los tengas en celdas vacías.
- Si tus fórmulas solo refieren a los rangos necesarios en lugar de referir a toda una columna (y/o fila).
- Si no tienes "enganchados" (conectados y/o vinculados) tus libros entre sí en exceso.
- Etc etc etc...

Willan Villamil Salcedo
Curso de baterias: acumuladores eléctr...
Escrito por Willan Villamil Salcedo
el 16/06/2012

Gracias por contestar Cacho:

La verdad no hay nada de lo que mecionas:


La macro de marras es una que utiliza muchas subrutinas que son parte de un bucle que puede repetirse 100 veces y precisamente en la que ocurre el problema es la siguiente:

Sub BloqueCostosIndirectos()
Dim tt
tt = 1
Range("a1"). Select
Application. Calculation = xlCalculationManual
Do Until ActiveCell. Row = Range("a30000"). End(xlUp). Row + 300

If ActiveCell. Value = "E)" Then
Application. StatusBar = "Configurando Costos indirectos. ítem: " & tt

'Gastos generales
Selection.EntireRow.Insert
With ActiveCell
. Offset(0, 6). Value = "COSTO TOTAL"
. Offset(-1, 0). Value = "4. GASTOS GENERALES Y ADMINISTRATIVOS"
. Offset(-1, 0). HorizontalAlignment = xlLeft
. Offset(-1, 1). Range("a1:f1"). Clear
End With

Call Encuadrar

With ActiveCell
. Offset(1, 0). Range("a1:b1"). ClearContents
. Offset(1, 3). Cut Destination:=ActiveCell. Offset(1, 5)
. Offset(1, 0). Range("a1:e1"). Borders(xlInsideVertical). LineStyle = xlNone
. Offset(1, 0). Range("a1:e1"). Borders(xlEdgeBottom). Weight = xlThin
. Offset(1, 4). Value = "GASTOS GENERALES (1+2+3)"
. Offset(1, 4). HorizontalAlignment = xlRight
. Offset(2, 0). Range("a1:a2"). EntireRow. Insert
. Offset(2, 6). Value = ActiveCell. Offset(1, 6). Value
. Offset(2, 5). Value = "TOTAL GASTOS GENERALES Y ADMINISTRATIVOS: "
. Offset(2, 5). HorizontalAlignment = xlRight
. Offset(2, 5). Range("a1:b1"). Font. Bold = True

. Offset(2, 0). Select
. Offset(1, 0). EntireRow. Insert
. Offset(1, 0). RowHeight = 3
End With

Call Descruadricular

Call Grisear

ActiveCell. Offset(-3, 0). Select
Call Grisear
ActiveCell. Offset(6, 0). Select

'Utilidad
Selection.EntireRow.Insert
With ActiveCell
. Offset(0, 6). Value = "COSTO TOTAL"
. Offset(-1, 0). Value = "5. UTILIDAD"
. Offset(-1, 0). HorizontalAlignment = xlLeft
. Offset(-1, 1). Range("a1:f1"). Clear
End With
Call Encuadrar
With ActiveCell
. Offset(1, 0). Range("a1:b1"). ClearContents
. Offset(1, 3). Cut Destination:=ActiveCell. Offset(1, 5)
. Offset(1, 0). Range("a1:e1"). Borders(xlInsideVertical). LineStyle = xlNone
. Offset(1, 0). Range("a1:e1"). Borders(xlEdgeBottom). Weight = xlThin
. Offset(1, 4). Value = "UTILIDAD (1+2+3+4)"
. Offset(1, 4). HorizontalAlignment = xlRight
. Offset(2, 0). Range("a1:a2"). EntireRow. Insert
. Offset(2, 6). Value = ActiveCell. Offset(1, 6). Value
. Offset(2, 5). Value = "TOTAL UTILIDAD: "
. Offset(2, 5). HorizontalAlignment = xlRight
. Offset(2, 5). Range("a1:b1"). Font. Bold = True

. Offset(2, 0). Select
. Offset(1, 0). EntireRow. Insert
. Offset(1, 0). RowHeight = 3
End With

Call Descruadricular

Call Grisear
ActiveCell. Offset(-3, 0). Select
Call Grisear
ActiveCell. Offset(6, 0). Select

'Impuestos
Selection.EntireRow.Insert
With ActiveCell
. Offset(0, 6). Value = "COSTO TOTAL"
. Offset(-1, 0). Value = "6. IMPUESTOS"
. Offset(-1, 0). HorizontalAlignment = xlLeft
. Offset(-1, 1). Range("a1:f1"). Clear
End With
Call Encuadrar
With ActiveCell
. Offset(1, 0). Range("a1:b1"). ClearContents
. Offset(1, 3). Cut Destination:=ActiveCell. Offset(1, 5)
. Offset(1, 0). Range("a1:e1"). Borders(xlInsideVertical). LineStyle = xlNone
. Offset(1, 0). Range("a1:e1"). Borders(xlEdgeBottom). Weight = xlThin
. Offset(1, 4). Value = "IMPUESTOS IT (1+2+3+4+5)"
. Offset(1, 4). HorizontalAlignment = xlRight
. Offset(2, 0). Range("a1:a2"). EntireRow. Insert
. Offset(2, 6). Value = ActiveCell. Offset(1, 6). Value
. Offset(2, 5). Value = "TOTAL IMPUESTOS: "
. Offset(2, 5). HorizontalAlignment = xlRight
. Offset(2, 5). Range("a1:b1"). Font. Bold = True

. Offset(2, 0). Select
. Offset(1, 0). EntireRow. Insert
. Offset(1, 0). RowHeight = 3
End With
Call Descruadricular
Call Grisear
ActiveCell. Offset(-3, 0). Select
Call Grisear
ActiveCell. Offset(5, 0). Select
ActiveCell. Range("a1:a2"). EntireRow. Delete
Call Encuadrar
With ActiveCell
. Range("a1:b1"). ClearContents
. Offset(0, 5). Value = "TOTAL PRECIO UNITARIO (1+2+3+4+5+6): "
. Offset(1, 0). EntireRow. Delete
. Offset(1, 0). Select
End With
Call Encuadrar
With ActiveCell
. Offset(2, 0). Range("A1:A2"). EntireRow. Insert
. Offset(3, 3). Value = "NNN"
. Offset(4, 3). Value = "REPRESENTANTE LEGAL"

. Offset(3, 3). HorizontalAlignment = xlCenter
. Offset(4, 3). HorizontalAlignment = xlCenter

. Offset(10, 0). Select
End With
tt = tt + 1

End If
ActiveCell. Offset(1, 0). Select
Application. CutCopyMode = False
Loop
End Sub

La línes con el prefijo Call son pequeñas subrutinas de unas 5 líneas. No tienen mayor incidencia en el tema.

Cuando desactivo la la subrutina BloqueCostosIndirectos, la memoria no se recarga.

Cacho Rodríguez
Ingeniería electrónica universidad nac...
Escrito por Cacho Rodríguez
el 17/06/2012

Sin ver esta macro actuando en la propia hoja no es mucho lo que te puedo decir.

Sin embargo hay "cosas":

- Si querés que una macro sea lenta, pues utiliza algo como:

Application. StatusBar = "Configurando Costos indirectos. ítem: " & tt

- Hay demasiados EntireRow. Insert y algún EntireRow. Delete (son generadores de demoras)

- No sé que hacen Call Encuadrar, Call Grisear, Call Descruadricular... Pero, ciertamente: ¡Hay demasiados temas de formato dando vueltas en tu código! , y todos son generadores de mucha demora.

Daría la sensación que en un determinado punto de la hoja procedes a "armar" un conjunto de celdas con una estructura fija de títulos y formatos.
De ser así -me parece- que has elegido una línea muy "morosa".

¿Sabes que es mucho mejor?...
Pues tener en una hoja auxiliar ya armado el conjunto de celdas con formato, y -simplemente- copiarlo y pegarlo donde lo necesites: ¿Entiendes la idea?

Willan Villamil Salcedo
Curso de baterias: acumuladores eléctr...
Escrito por Willan Villamil Salcedo
el 18/06/2012

Gracias Cacho por la respuesta.
Lamentablemente no es posible crear una hoja plantilla porque cada ítem tiene diferentes medidas dependiendo de varios factores
... Aunque... Se me está ocurriendo algo...
De todos modos lo ideal será encontrar un procedimiento de descarga de memoria RAM, de manera tal que cada vez que se ejecute la macro tarde lo mismo y no que cada vez vaya haciéndose más perezosa.
He desarrollado muchas aplicaciones en excel y es la primera vez que me tropiezo con este problema.

Te enviaré el dato del resultado que obtenga con la idea brutal que se me acaba de ocurrir ;-)

Cacho Rodríguez
Ingeniería electrónica universidad nac...
Escrito por Cacho Rodríguez
el 18/06/2012

Veremos...