Base de conhecimento KB0070

Por que minha macro do Excel fica lenta quando o think-cell está ativado?

Um problema comum que pode causar falhas de desempenho em macros VBA é o uso da função .Select. Sempre que uma célula é selecionada no Excel, todos os suplementos do Excel (incluindo o think-cell) são notificados sobre esse evento de alteração da seleção, o que desacelera a macro consideravelmente. Especialmente as macros criadas usando o gravador de macros são propícias a esse tipo de problema.

A Microsoft também recomenda evitar a declaração .Selecione no código VBA para melhorar o desempenho:

Exemplo: Como evitar o uso da declaração .Select

Vejamos a seguinte macro simples 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

Essa função abre uma caixa de entrada que pede ao usuário que especifique um intervalo de células. A função move todas as células no intervalo. Se encontrar uma célula que não está vazia, ela copia o conteúdo da célula para a área de transferência. A função cola o conteúdo da área de transferência para todas as células vazias subsequentes.

A AutoFillTable usa a área de transferência para copiar o conteúdo da célula. Assim, a função precisa selecionar cada célula que é manipulada, para que o Excel saiba a partir de que célula deve copiar e para que célula deve colar. A solução recomendada é mostrada na função AutoFillTable2 a seguir:

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

A AutoFillTable2 difere de sua predecessora em duas formas importantes:

  1. Mais importante, já não é necessário selecionar uma célula. Em vez disso, quando uma célula é encontrada não estando vazia, essa célula é armazenada na variável iCellMaster. Portanto, sempre que uma célula vazia é encontrada, todo o conteúdo da iCellMaster é copiado na iCell.
  2. Ela utiliza o recurso da linguagem Visual Basic For Each … Next para visitar cada célula na faixa. Isso já é uma melhoria para a legibilidade.

Compartilhar