KB0070: Perché la macro di Excel è lenta quando thinkcell è attivato?

  1. Home
  2. Risorse
  3. Knowledge base
  4. KB0070

Un problema comune che può causare problemi di prestazioni nelle macro VBA è l'uso della funzione .Select. Ogni volta che una cella viene selezionata in Excel, ogni singolo componente aggiuntivo di Excel (incluso thinkcell) riceve una notifica di questo evento di modifica della selezione, rallentando notevolmente la macro. Le macro create usando il registratore di macro sono particolarmente soggette a questo tipo di problema.

Microsoft consiglia inoltre di evitare l'istruzione .Select nel codice VBA per migliorare le prestazioni:

Esempio: come evitare l'uso dell'istruzione .Select

Esaminiamo la 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 casella di input che chiede all'utente di specificare un intervallo di celle. La funzione scorre tutte le celle dell'intervallo. Se trova una cella non vuota, copia il contenuto della cella negli Appunti. La funzione incolla il contenuto degli Appunti in ogni cella vuota successiva.

AutoFillTable usa gli Appunti per copiare il contenuto della cella. Pertanto, la funzione deve selezionare ogni cella manipolata in modo che Excel sappia da quale cella copiare e in quale cella incollare. La soluzione consigliata è mostrata 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 differisce dal suo predecessore in due aspetti importanti:

  1. Soprattutto, non deve più selezionare una cella. Invece, quando viene trovata una cella non vuota, questa cella viene memorizzata nella variabile iCellMaster. Successivamente, ogni volta che viene trovata una cella vuota, tutto il contenuto di iCellMaster viene copiato in iCell.
  2. Usa la funzionalità del linguaggio Visual Basic For Each … Next per visitare ogni cella dell'intervallo. Questo rappresenta già un miglioramento della leggibilità.