Knowledge base KB0070

Perché la macro Excel risulta lenta quando think-cell è attivato?

Un problema comune che può causare problemi di prestazioni in macro VBA, è l'uso della funzione .Seleziona. Ogni qualvolta viene selezionata una cella in Excel, ogni singolo componente aggiuntivo di Excel (compreso think-cell) riceve una notifica su questo evento di modifica della selezione che rallenta notevolmente macro. Specialmente le macro create utilizzando il registratore macro tendono a dare questo tipo di problema.

Per migliorare le prestazioni, Microsoft consiglia di non selezionare le istruzioni contenute nel codice VBA:

Esempio: Come evitare l'uso dell'istruzione .Seleziona

Diamo uno sguardo alla seguente semplice macro 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

Questa funzione apre una finestra di immissione che chiede all'utente di specificare un intervallo di celle. La funzione si sposta su tutte le celle dell'intervallo. Quando trova una cella che non è vuota, copia il contenuto della cella negli appunti. La funzione incolla quindi il contenuto degli appunti in ogni cella vuota successiva.

AutoFillTable utilizza gli appunti per copiare il contenuto della cella. Pertanto, la funzione ha bisogno di selezionare ogni cella che viene manipolata, in modo che Excel sappia da quale cella copiare e in quale cella incollare. La soluzione consigliata è illustrata nella seguente funzione 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 si differenzia, rispetto alla versione precedente, per due importanti aspetti:

  1. Cosa più importante, non richiede più di selezionare una cella. Al contrario, quando viene trovata una cella che non è vuota, questa viene memorizzata nella variabile iCellMaster. Successivamente, ogni qualvolta viene trovata una cella vuota, tutto il contenuto di iCellMaster viene copiato in iCell.
  2. Utilizza la funzione del linguaggio Visual Basic For Each… Next per visitare tutte le celle dell'intervallo. Ciò garantisce già un miglioramento della leggibilità.