Welche Excel-Objekte basieren auf Null und welche auf Eins?

20

Der Zugriff auf das erste Blatt eines Arbeitsblatts über VBA erfolgt über Arbeitsblätter (1). Das erste Element in einer ListBox ist myListBox.List (0). Ich habe gehört, dass Sammlungen 1-basiert sind, aber ich weiß nicht, was sie sind. VBA-Arrays basieren auf 0. Excel-Zeichenfolgenfunktionen wie MID basieren auf 1. Gibt es ein allgemeines Prinzip, was auf 0 oder 1 basiert, oder könnten Sie eine Liste von jedem bereitstellen?

Noumenon
quelle
cell (1,1) .characters (index, length) basiert auf 1, schneidet jedoch Grenzen ab, sodass cell (1,1) .characters (0, length) = cell (1,1) .characters (1, Länge) (Excel 2013)
Seanv507

Antworten:

24

In VBA stehen drei Haupttypen von Gruppierungskonstrukten zur Verfügung, wobei zwischen Indizes unterschieden wird

  • Sammlungen - 1-basierter Index

    • 0-basierte Ausnahmen: UserForm-Sammlungen wie Registerkarten, Seiten, Steuerelemente (ListBox, TextBox)
    • Sammlungen sind native Excel-Objekte, die Gruppen (oder Listen) logisch zusammengehöriger Objekte enthalten
    • Wird normalerweise zum Speichern komplexer Objekte verwendet, kann aber auch Grundtypen enthalten
    • Excel-Sammlungen:

      • Arbeitsmappen, Blätter, Bereiche, Formen
      • Blätter (1) ist das erste in der Datei, Zellen (1, 1) ist die Zelle in der ersten Zeile und der ersten Spalte
    • Der Hauptvorteil von Sammlungen ist der bequeme Zugriff auf Elemente über den Namen

      • For-Each-Schleife ist sehr effizient (im Vergleich zur For-Each-Verarbeitung von Arrays)
      • Der Zugriff auf einzelne Elemente über den Index ist jedoch schneller als der Zugriff über den Namen

  • Arrays - standardmäßig 0-basiert, aber der erste Index kann in eine beliebige Zahl geändert werden (siehe Abbildung unten)

    • Arrays sind Variablen, die eine Reihe verwandter Variablen enthalten
    • Wird normalerweise für primitive Datentypen wie Boolean, Integer, Long, String, Double usw. Verwendet
    • Sobald es definiert ist, enthält es nur einen Elementtyp: Dim x() As Long

      • Um komplexere Objekte aufzunehmen, kann ein Array definiert werden als Dim x() As Variant
      • Varianten können alle Arten von Objekten sein, einschließlich Arbeitsmappen, Blätter, Bereiche und Arrays

        • 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)
    • Der Hauptvorteil von Arrays ist die Leistung beim Zugriff auf Elemente über den Index

      • For index=0 To 10Loops sind schneller als For-EachLoops

  • Wörterbücher - nicht indiziert, aber Indizes können mit Schlüsseln simuliert werden

    • Native zu VB Script, nicht VBA (muss eine externe Bibliothek verwenden)
    • Kann alle Arten von Objekten enthalten, einschließlich Arrays, Sammlungen oder anderer Wörterbücher

Eine ListBox ist ein komplexes Objekt und kann über die 0-basierte Sammlung von Steuerelementen aufgerufen werden

Die .List () - Eigenschaft von ListBox ist ein 0-basiertes Array

Weitere Hinweise

  • 0-basierte Indizes sind der Standard für andere Sprachen

  • VBA hat das 1-basierte Konzept eingeführt, um es für neue Benutzer intuitiver zu machen:

    • Sheet1 bis Sheet3, mit einer Sammlungsanzahl von 3, die einfacher zu verwenden ist als
    • Sheet0 bis Sheet2, mit der Auflistung Count of 3

Einige praktische Beispiele für den Unterschied zwischen ihren Indizes:

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

Weitere Lektüre:

Paul Bica
quelle