Ricerca…


Riferimenti qualificanti

Quando ci si riferisce a un worksheet , un range o singole cells , è importante qualificare completamente il riferimento.

Per esempio:

ThisWorkbook.Worksheets("Sheet1").Range(Cells(1, 2), Cells(2, 3)).Copy

Non è completamente qualificato: i riferimenti di Cells non hanno una cartella di lavoro e un foglio di lavoro associati. Senza un riferimento esplicito, Cells fa riferimento a ActiveSheet per impostazione predefinita. Quindi questo codice fallirà (produrrà risultati errati) se un foglio di lavoro diverso da Sheet1 è il ActiveSheet corrente.

Il modo più semplice per correggere ciò è utilizzare un'istruzione With come segue:

With ThisWorkbook.Worksheets("Sheet1")
    .Range(.Cells(1, 2), .Cells(2, 3)).Copy
End With

In alternativa, è possibile utilizzare una variabile del foglio di lavoro. (Questo sarà probabilmente il metodo preferito se il tuo codice deve fare riferimento a più fogli di lavoro, come copiare i dati da un foglio a un altro.)

Dim ws1 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
ws1.Range(ws1.Cells(1, 2), ws1.Cells(2, 3)).Copy

Un altro problema frequente è fare riferimento alla raccolta dei fogli di lavoro senza qualificare la cartella di lavoro. Per esempio:

Worksheets("Sheet1").Copy

Il foglio di lavoro Sheet1 non è completo e manca di una cartella di lavoro. Questo potrebbe fallire se nel codice vengono referenziate più cartelle di lavoro. Invece, utilizzare uno dei seguenti:

ThisWorkbook.Worksheets("Sheet1")       '<--ThisWorkbook refers to the workbook containing 
                                        'the running VBA code
Workbooks("Book1").Worksheets("Sheet1") '<--Where Book1 is the workbook containing Sheet1

Tuttavia, evitare di utilizzare quanto segue:

ActiveWorkbook.Worksheets("Sheet1")     '<--Valid, but if another workbook is activated
                                        'the reference will be changed

Allo stesso modo per gli oggetti range , se non esplicitamente qualificato, l' range si riferirà al foglio attualmente attivo:

Range("a1")

Equivale a:

ActiveSheet.Range("a1")

Eliminazione di righe o colonne in un ciclo

Se vuoi eliminare righe (o colonne) in un ciclo, dovresti sempre eseguire il ciclo partendo dalla fine dell'intervallo e tornare indietro in ogni passaggio. In caso di utilizzo del codice:

Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 1 To 4
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With

Perderai alcune righe. Ad esempio, se il codice cancella la riga 3, la riga 4 diventa la riga 3. Tuttavia, la variabile i cambierà in 4. Quindi, in questo caso il codice mancherà di una riga e ne controllerà un'altra, che non era nell'intervallo in precedenza.

Il codice giusto sarebbe

Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 4 To 1 Step -1
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With

ActiveWorkbook vs. ThisWorkbook

ActiveWorkbook e ThisWorkbook volte vengono utilizzati in modo intercambiabile dai nuovi utenti di VBA senza comprendere appieno a che cosa si riferisce ogni oggetto, questo può causare un comportamento indesiderato in fase di esecuzione. Entrambi questi oggetti appartengono all'oggetto dell'applicazione


L'oggetto ActiveWorkbook fa riferimento alla cartella di lavoro attualmente nella vista più in alto dell'oggetto dell'applicazione Excel al momento dell'esecuzione. (es. La cartella di lavoro che puoi vedere e interagire con il punto in cui viene fatto riferimento a questo oggetto)

Sub ActiveWorkbookExample()

'// Let's assume that 'Other Workbook.xlsx' has "Bar" written in A1.

    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Foo"
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Foo"

    Workbooks.Open("C:\Users\BloggsJ\Other Workbook.xlsx")
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"

    Workbooks.Add 1
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints nothing

End Sub

L'oggetto ThisWorkbook fa riferimento alla cartella di lavoro a cui appartiene il codice nel momento in cui viene eseguita.

Sub ThisWorkbookExample()

'// Let's assume to begin that this code is in the same workbook that is currently active

    ActiveWorkbook.Sheet1.Range("A1").Value = "Foo"
    Workbooks.Add 1
    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Bar"

    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"
    Debug.Print ThisWorkbook.Sheet1.Range("A1").Value '// Prints "Foo"

End Sub

Interfaccia a singolo documento e interfacce a più documenti

Si noti che Microsoft Excel 2013 (e versioni successive) utilizza Single Document Interface (SDI) e che Excel 2010 (e successivi) utilizza Multiple Document Interfaces (MDI).

Ciò implica che per Excel 2013 (SDI), ogni cartella di lavoro in una singola istanza di Excel contenga la propria interfaccia utente della barra multifunzione:

inserisci la descrizione dell'immagine qui

Al contrario, per Excel 2010, ciascuna cartella di lavoro in una singola istanza di Excel utilizzava un'interfaccia utente nastro comune (MDI): inserisci la descrizione dell'immagine qui

Ciò solleva alcuni problemi importanti se si desidera eseguire la migrazione di un codice VBA (2010 <-> 2013) che interagisce con la barra multifunzione.

È necessario creare una procedura per aggiornare i controlli dell'interfaccia utente della barra multifunzione nello stesso stato in tutte le cartelle di lavoro per Excel 2013 e versioni successive.

Nota che :

  1. Tutti i metodi, gli eventi e le proprietà delle finestre a livello di applicazione di Excel rimangono inalterati. ( Application.ActiveWindow , Application.Windows ...)
  2. In Excel 2013 e versioni successive (SDI) tutti i metodi, gli eventi e le proprietà delle finestre a livello di cartella di lavoro ora operano nella finestra di livello superiore. È possibile recuperare l'handle di questa finestra di livello superiore con Application.Hwnd

Per ottenere maggiori dettagli, vedere la fonte di questo esempio: MSDN .

Ciò causa anche alcuni problemi con userforms non modali. Vedi qui per una soluzione.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow