Quels objets Excel sont basés sur zéro et lesquels sont basés sur un?

20

L'utilisation de VBA pour accéder à la première feuille d'une feuille de calcul est Worksheets (1). Le premier élément dans 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 baies VBA sont basées sur 0. Les fonctions de chaîne Excel comme MID sont basées sur 1. Existe-t-il un principe général sur ce qui est basé sur 0 ou 1, ou pourriez-vous en fournir une liste?

Noumenon
la source
cell (1,1) .characters (index, length) est basé sur 1 mais effectue une sorte de délimitation des limites de sorte que cell (1,1) .characters (0, length) = cell (1,1) .characters (1, (excel 2013)
seanv507

Réponses:

24

Il existe 3 principaux types 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 comme Tabs, Pages, Controls (ListBox, TextBox)
    • Les collections sont des objets Excel natifs qui contiennent des groupes (ou des listes) d'objets liés de manière logique
    • Normalement utilisé pour contenir des objets complexes, mais peut également contenir des types de base
    • Collections Excel:

      • Classeurs, feuilles, gammes, formes
      • Sheets (1) est le premier du fichier, Cells (1, 1) est la cellule 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 (par rapport au traitement For-Each des tableaux)
      • L'accès à des éléments individuels par index est cependant plus rapide que l'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 qui contiennent un ensemble de variables liées
    • Normalement utilisé pour les types de données primitifs tels que booléen, entier, long, chaîne, 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 Dim x() As Variant
      • Les variantes peuvent être n'importe quel type d'objet, y compris des classeurs, des feuilles, des plages, des 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

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

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

    • Native à VB Script, pas VBA (doit utiliser une bibliothèque externe)
    • Peut contenir tout type d'objets, y compris des tableaux, des collections ou d'autres dictionnaires

Un ListBox est un objet complexe et est accessible 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 la collection Count de 3 plus facile à utiliser que
    • Sheet0 à Sheet2, avec collection Nombre de 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:

paul bica
la source