web-dev-qa-db-fra.com

Quels objets Excel sont-ils sur zéro et quels sont-ils sur un?

Utilisation de VBA pour accéder à la première feuille d'une feuille de calcul est Worksheets (1). Le premier élément d'un ListBox est myListBox.List (0). J'ai entendu dire que les collections sont basées sur 1, mais je ne sais pas ce qu'elles sont. Les tableaux VBA sont basés sur 0. Les fonctions de chaîne Excel telles que MID sont basées sur 1. Existe-t-il un principe général concernant ce qui est basé sur 0 ou 1, ou pourriez-vous fournir une liste de chacun?

16
Noumenon

Il existe 3 types principaux de constructions de regroupement disponibles dans VBA, avec des distinctions entre les index

  • Collections - index basé sur 1

    • Exceptions basées sur 0: collections UserForm telles que des onglets, des pages et des contrôles (ListBox, TextBox)
    • Les collections sont des objets Excel natifs contenant des groupes (ou des listes) d'objets liés logiquement
    • Normalement utilisé pour contenir des objets complexes, mais peut également contenir des types de base
    • Collections Excel:

      • Cahiers d'exercices, feuilles, plages, formes
      • Les feuilles (1) sont les premières du fichier, les cellules (1, 1) sont les cellules de la première ligne et de la première colonne.
    • Le principal avantage des collections est la commodité d'accéder aux éléments par leur nom.

      • La boucle For-Each est très efficace (comparée au traitement des tableaux For-Each)
      • L'accès à des éléments individuels par index est cependant plus rapide que leur accès par nom

  • Tableaux - basés sur 0 par défaut, mais le premier index peut être changé en n'importe quel nombre (illustré ci-dessous)

    • Les tableaux sont des variables contenant un ensemble de variables liées
    • Normalement utilisé pour les types de données primitifs tels que Boolean, Integer, Long, String, Double, etc.
    • Une fois défini, il ne contiendra qu'un seul type d'éléments: Dim x() As Long

      • Pour contenir des objets plus complexes, un tableau peut être défini comme suit: Dim x() As Variant
      • Les variantes peuvent être n’importe quel type d’objets, y compris les classeurs, les feuilles, les plages, les tableaux

        • Dim x As Variant: x = Array(1) '1 Variant variable containing 1 array
        • Dim y(2) As Variant '1 Variant array containing 3 arrays
        • y(0) = Array(1): y(1) = Array(2): y(2) = Array(3)
    • Le principal avantage des tableaux est la performance lors de l'accès aux éléments par index

      • Les boucles For index=0 To 10 sont plus rapides que les boucles For-Each

  • Dictionnaires - non indexés, mais les index peuvent être simulés avec des clés

    • Natif pour VB Script, pas VBA (doit utiliser une bibliothèque externe)
    • Peut contenir n'importe quel type d'objets, y compris des tableaux, des collections ou d'autres dictionnaires

Un ListBox est un objet complexe auquel il est possible d'accéder via la collection de contrôles basée sur 0.

La propriété .List () de ListBox est un tableau basé sur 0

Autres notes

  • Les index basés sur 0 sont la norme pour les autres langues

  • VBA a introduit le concept basé sur 1 pour le rendre plus intuitif pour les nouveaux utilisateurs:

    • Sheet1 à Sheet3, avec collection Compter de 3 plus facile à utiliser que
    • Sheet0 à Sheet2, avec collection Comptez sur 3

Quelques exemples pratiques de la différence entre leurs index:

Public Sub vbaCollections()
    Dim c As New Collection     '1-based index

    c.Add Item:="a", Key:="1"   'index 1; Key must a String
    c.Add Item:="b", Key:="2"   'index 2
    c.Add Item:="c", Key:="3"   'index 3

    Debug.Print c.Count         '3;   Items in index sequence: a,b,c, Keys: "1","2","3"
    Debug.Print c.Item(1)       'a;   not available for Dictionaries
    'Debug.Print c.Key("1")     'invalid, so is: c.Key(1)

    c.Remove Index:=2
    Debug.Print c.Count         '2;   items in index sequence: a,c, Keys: "1","3"
    'c.Remove Item:="c"         'invalid, so is: c.Remove Key:="3"

    'c.Add Item:="c", Key:="3", Before:=1   'Key must be unique - Error
    c.Add Item:="c", Key:="5", Before:=1    'allows duplicate Item
    Debug.Print c.Count         '3;   items in index sequence: c,a,c, Keys: "5","1","3"
End Sub

Public Sub vbaArrays()
    Dim a() As Long, b(3) As Long   'Arrays default to "Option Base {0 | 1}"
    Dim c(0 To 0)                   'if "Option Base" not defined, it defaults to 0
    Dim ar(1) As Worksheet: Set ar(0) = Worksheets(1)   'array with 1 Worksheets object

    ReDim a(3)          'creates an array of 4 elements; indexes 0,1,2,3
        Debug.Print "LB: " & LBound(a) & ", UB: " & UBound(a)   'LB: 0, UB: 3
        Debug.Print UBound(a) - LBound(a)                       '3, array b() is the same

    'even whith "Option Base 1", the following still default to 0
    Dim v As Variant:  v = Split("A B")         'array with 2 items: v(0) = "A", v(1) = "B"
    'UserForm1.ListBox1.List = Array("Test")    'array with 1 item: .List(0,0) = "Test"

    ReDim a(0 To 3)     'creates an array of 4 elements; indexes 0,1,2,3
    a(0) = 1:   a(1) = 2:   a(2) = 3    'a(3) defaults to 0

        Debug.Print "LB: " & LBound(a) & ", UB: " & UBound(a)   'LB: 0, UB: 3
        Debug.Print UBound(a) - LBound(a)                       '3; offset index by -1

    ReDim a(1 To 3)     'creates an array of 3 elements; indexes 1,2,3
    a(1) = 1:   a(2) = 2:   a(3) = 3

        Debug.Print "LB: " & LBound(a) & ", UB: " & UBound(a)   'LB: 1, UB: 3
        Debug.Print UBound(a) - LBound(a)                       '2; offset count by +1

    ReDim a(5 To 7)     'creates an array of 3 elements; indexes 5,6,7
    a(5) = 1:   a(6) = 2:   a(7) = 3

        Debug.Print "LB: " & LBound(a) & ", UB: " & UBound(a)   'LB: 5, UB: 7
        Debug.Print UBound(a) - LBound(a)                       '2; offset count by +1

    ReDim a(-3 To -1)   'creates an array of 3 elements; indexes -3,-2,-1
    a(-3) = 1:  a(-2) = 2:  a(-1) = 3

        Debug.Print "LB: " & LBound(a) & ", UB: " & UBound(a)   'LB: -3, UB: -1
        Debug.Print UBound(a) - LBound(a)                       '2; offset count by +1
End Sub

Public Sub vbsDictionaries()
    Dim d As Object         'not indexed (similar to linked lists)
    Set d = CreateObject("Scripting.Dictionary")    'native to VB Script, not VBA

    d.Add Key:="a", Item:=1 'index is based on Key (a, b, c)
    d.Add Key:="b", Item:=2
    d.Add Key:="c", Item:=3
    Debug.Print d.Count     '3; Keys: a,b,c, Items: 1,2,3

    Debug.Print d(1)        'output is empty ("") - adds new element: Key:="1", Item:=""
    Debug.Print d.Count     '4; Keys: a,b,c,1, Items: 1,2,3,Empty
    Debug.Print d("a")      '1
    Debug.Print d(1)        'output is Empty ("") from element with Key:="1"

    'd.Add Key:="b", Item:=2        'attempt to add existing element: Key:="b" - Error

    'd.Keys  - 0-based array (not available for Collections)
    'd.Items - 0-based array (not available for Collections)

    d.Remove d.Keys()(1)            'remove element Item:=2 (Key:="b")
        Debug.Print d.Count         '3; Keys: a,c,1, Items: 1,3,""
    d.Remove d.Items()(0)           'remove Items element 0 (Key:="1", Item:="")
        Debug.Print d.Count         '2; Keys: a,c, Items: 1,3
    d.Remove "c"                    'remove element Key:="c" (Item:=3)
        Debug.Print d.Count         '1; Keys: a, Items: 1

    d.Add Key:="c", Item:=3
        Debug.Print d.Count         '2; Keys: a,c, Items: 1,3

    'd.Remove d.Items()(0)          'invalid
    Debug.Print d.Items()(d.Count - 1)  '3
    d.Remove d.Keys()(d.Count - 1)  'remove last element; access last Key by Key
        Debug.Print d.Count         '1; Keys: a, Items: 1

    Debug.Print d.Exists("a")       'True (not available for Collections)
    Debug.Print d.Exists(2)         'False
End Sub

Lectures complémentaires:

19
paul bica