¿Qué objetos de Excel están basados ​​en cero y cuáles están basados ​​en uno?


20

Usar VBA para acceder a la primera hoja de una hoja de trabajo es Hojas de trabajo (1). El primer elemento en un ListBox es myListBox.List (0). Escuché que las Colecciones están basadas en 1 pero no sé cuáles son. Las matrices de VBA están basadas en 0. Las funciones de cadena de Excel como MID están basadas en 1. ¿Existe un principio general sobre lo que se basa en 0 o 1, o podría proporcionar una lista de cada uno?


cell (1,1) .characters (index, length) está basado en 1, pero hace algún tipo de recorte de límite para que cell (1,1) .characters (0, length) = cell (1,1) .characters (1, duración) (excel 2013)
seanv507

Respuestas:


24

Hay 3 tipos principales de construcciones de agrupación disponibles en VBA, con distinciones entre índices

  • Colecciones - índice basado en 1

    • Excepciones basadas en 0: colecciones de UserForm como pestañas, páginas, controles (ListBox, TextBox)
    • Las colecciones son objetos nativos de Excel que contienen grupos (o listas) de objetos relacionados lógicamente
    • Normalmente se usa para contener objetos complejos, pero también puede contener tipos básicos
    • Colecciones de Excel:

      • Libros de trabajo, hojas, rangos, formas
      • Hojas (1) es la primera en el archivo, Celdas (1, 1) es la celda en la primera fila y la primera columna
    • La principal ventaja de las colecciones es la conveniencia de acceder a los elementos por nombre.

      • El bucle For-Each es muy eficiente (en comparación con el procesamiento For-Each de matrices)
      • Sin embargo, acceder a elementos individuales por índice es más rápido que acceder a ellos por nombre

  • Matrices: basadas en 0 de forma predeterminada, pero el primer índice se puede cambiar a cualquier número (se ilustra a continuación)

    • Las matrices son variables que contienen un conjunto de variables relacionadas.
    • Normalmente se usa para tipos de datos primitivos como booleano, entero, largo, cadena, doble, etc.
    • Una vez que se define, contendrá solo un tipo de elementos: Dim x() As Long

      • Para contener objetos más complejos, una matriz se puede definir como Dim x() As Variant
      • Las variantes pueden ser cualquier tipo de objetos, incluidos libros de trabajo, hojas, rangos, matrices

        • 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)
    • La principal ventaja de las matrices es el rendimiento al acceder a elementos por índice

      • For index=0 To 10los bucles son más rápidos que los For-Eachbucles

  • Diccionarios: no indexados, pero los índices se pueden simular con Keys

    • Nativo de VB Script, no VBA (debe usar una biblioteca externa)
    • Puede contener cualquier tipo de objetos, incluidos matrices, colecciones u otros diccionarios

Un ListBox es un objeto complejo y se puede acceder a través de la colección de controles basada en 0

La propiedad .List () de ListBox es una matriz basada en 0

Otras notas

  • Los índices basados ​​en 0 son el estándar para otros idiomas

  • VBA introdujo el concepto basado en 1 para hacerlo más intuitivo para los nuevos usuarios:

    • Sheet1 a Sheet3, con la colección Count of 3 más fácil de usar que
    • Sheet0 a Sheet2, con colección Count of 3

Algunos ejemplos prácticos de la diferencia entre sus índices:

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

Otras lecturas:

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.