Base de dados 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. 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 macro AutoFillTable usa a área de transferência para copiar o conteúdo das células. 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 seguinte função 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 difere em duas formas importantes da sua predecessora:

  1. Mais importante, já não é necessário selecionar uma célula. Em vez disso, quando é encontrada uma célula que não está vazia, essa célula é armazenada na variável iCellMaster. A partir daí, sempre que é encontrada uma célula vazia, todo o conteúdo de iCellMaster é copiado para iCell.
  2. Utiliza o recurso de linguagem Visual Basic para cada … Próximo para visitar cada célula na faixa. Isso já é uma melhoria para a legibilidade.