Recherche…


Références éligibles

En faisant référence à une worksheet , à une range ou à des cells individuelles, il est important de qualifier complètement la référence.

Par exemple:

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

N'est pas entièrement qualifié: les références de Cells ne sont pas associées à un classeur et à une feuille de calcul. Sans référence explicite, Cells fait référence à ActiveSheet par défaut. Ce code échouera donc (produira des résultats incorrects) si une feuille de calcul autre que Sheet1 est l'actuelle ActiveSheet .

La manière la plus simple de corriger cela est d'utiliser une instruction With comme suit:

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

Vous pouvez également utiliser une variable de feuille de calcul. (Cela sera probablement la méthode préférée si votre code doit référencer plusieurs feuilles de calcul, comme la copie de données d'une feuille à une autre.)

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

Un autre problème fréquent est le référencement de la collection Worksheets sans qualifier le classeur. Par exemple:

Worksheets("Sheet1").Copy

La feuille de calcul Sheet1 n'est pas entièrement qualifiée et ne contient pas de classeur. Cela peut échouer si plusieurs classeurs sont référencés dans le code. Utilisez plutôt l'une des options suivantes:

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

Cependant, évitez d'utiliser les éléments suivants:

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

De même pour les objets de range , s’ils ne sont pas explicitement qualifiés, la range se réfère à la feuille actuellement active:

Range("a1")

Est le même que:

ActiveSheet.Range("a1")

Suppression de lignes ou de colonnes dans une boucle

Si vous souhaitez supprimer des lignes (ou des colonnes) dans une boucle, vous devez toujours effectuer une boucle à partir de la fin de la plage et revenir à chaque étape. En cas d'utilisation du code:

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

Vous allez manquer certaines lignes. Par exemple, si le code supprime la ligne 3, la ligne 4 devient la ligne 3. Cependant, la variable i passera à 4. Ainsi, dans ce cas, le code manquera une ligne et en vérifiera une autre, qui n'était pas dans la plage précédente.

Le bon code serait

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 et ThisWorkbook parfois utilisés indifféremment par les nouveaux utilisateurs de VBA sans comprendre parfaitement à quoi chaque objet se rapporte, cela peut entraîner un comportement indésirable au moment de l'exécution. Ces deux objets appartiennent à l' objet d'application


L'objet ActiveWorkbook fait référence au classeur qui se trouve actuellement dans la vue la plus haute de l'objet d'application Excel au moment de l'exécution. (Par exemple, le classeur avec lequel vous pouvez voir et interagir au moment où cet objet est référencé)

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'objet ThisWorkbook fait référence au classeur auquel appartient le code au moment de son exécution.

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

Interface de document unique et interfaces de documents multiples

Sachez que Microsoft Excel 2013 (et versions ultérieures) utilise l'interface SDI (Single Document Interface) et qu'Excel 2010 (et ci-dessous) utilise plusieurs interfaces de document (MDI).

Cela implique que pour Excel 2013 (SDI), chaque classeur d'une seule instance d'Excel contient sa propre interface utilisateur de ruban:

entrer la description de l'image ici

A l' inverse pour Excel 2010, chaque classeur dans une seule instance d'Excel utilise une interface de ruban commun (MDI): entrer la description de l'image ici

Cela pose des problèmes importants si vous souhaitez migrer un code VBA (2010 <-> 2013) qui interagit avec le ruban.

Une procédure doit être créée pour mettre à jour les contrôles de l'interface utilisateur du ruban dans le même état sur tous les classeurs pour Excel 2013 et versions ultérieures.

Notez que :

  1. Toutes les méthodes, événements et propriétés de fenêtre au niveau de l'application Excel restent inchangés. ( Application.ActiveWindow , Application.Windows ...)
  2. Dans Excel 2013 et versions ultérieures (SDI), toutes les méthodes, tous les événements et toutes les propriétés de la fenêtre au niveau du classeur fonctionnent désormais dans la fenêtre de niveau supérieur. Il est possible de récupérer le descripteur de cette fenêtre de niveau supérieur avec Application.Hwnd

Pour plus de détails, voir la source de cet exemple: MSDN .

Cela provoque également des problèmes avec les formes utilisateur sans modèle. Voir ici pour une solution.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow