Base de conocimientos KB0070

¿Por qué mi macro de Excel se ralentiza al activar think-cell?

Un problema común que puede causar problemas de rendimiento en las macros de VBA es el uso de la función .Select. Cada vez que se selecciona una celda en Excel, se notifica a todos los complementos de Excel (incluido think-cell) este evento de cambio de selección, lo que ralentiza la macro de forma considerable. Las macros que se crean mediante la grabadora de macros son especialmente propensas a este tipo de problema.

Microsoft también recomienda evitar la instrucción .Select en el código VBA para mejorar el rendimiento:

Ejemplo: Cómo evitar el uso de la instrucción .Select

Echemos un vistazo a la siguiente macro sencilla AutoFillTable:

Sub AutoFillTable()
    Dim iRange As Excel.Range
    Set iRange = Application.InputBox(prompt:="Enter range", Type:=8)
    Dim nCount As Integer
    nCount = iRange.Cells.Count
    For i = 1 To nCount
        Selection.Copy
        If iRange.Cells.Item(i).Value = "" Then
            iRange.Cells.Item(i).Range("A1").Select
            ActiveSheet.Paste
        Else
            iRange.Cells.Item(i).Range("A1").Select
        End If
    Next
End Sub

Esta función abre un cuadro de entrada que pide al usuario que especifique un rango de celdas. La función pasa por todas las celdas del rango. Si encuentra una celda que no está vacía, copia su contenido en el portapapeles. La función pega el contenido del portapapeles en cada celda vacía posterior.

AutoFillTable utiliza el portapapeles para copiar el contenido de la celda. Por lo tanto, la función tiene que seleccionar cada celda manipulada para que Excel sepa qué celda debe copiar y en qué celda debe pegar. La solución recomendada se muestra en la siguiente función AutoFillTable2:

Sub AutoFillTable2() Dim iRange As Excel.Range Set iRange = Application.InputBox(prompt:="Enter range", Type:=8) Dim iCellMaster As Excel.Range For Each iCell In iRange.Cells If iCell.Value = "" Then If Not iCellMaster Is Nothing Then iCellMaster.Copy (iCell) End If Else Set iCellMaster = iCell End If Next iCell End Sub

AutoFillTable2 difiere en dos aspectos importantes de su predecesora:

  1. Pero más importante aún, ya no necesita seleccionar una celda. En lugar de ello, cuando se encuentra una celda que no está vacía, dicha celda se almacena en la variable iCellMaster. A partir de ese instante, cada vez que se encuentra una celda vacía, todo el contenido de iCellMaster se copia en iCell.
  2. Utiliza la característica de lenguaje Visual Basic For Each … Next para pasar por cada celda del rango. Esto ya supone una mejora de legibilidad.