Quali oggetti Excel sono basati su zero e quali sono basati su uno?


20

L'uso di VBA per accedere al primo foglio in un foglio di lavoro è Fogli di lavoro (1). Il primo elemento in un ListBox è myListBox.List (0). Ho sentito che le raccolte sono basate su 1, ma non so cosa siano. Le matrici VBA sono basate su 0. Le funzioni di stringa di Excel come MID sono basate su 1. Esiste un principio generale su ciò che si basa su 0 o 1 o potresti fornire un elenco di ciascuno?


cell (1,1) .characters (indice, lunghezza) è basato su 1 ma esegue una sorta di ritaglio al contorno in modo che cell (1,1) .characters (0, length) = cell (1,1) .characters (1, lunghezza) (excel 2013)
seanv507

Risposte:


24

Esistono 3 tipi principali di costrutti di raggruppamento disponibili in VBA, con distinzioni tra gli indici

  • Raccolte - indice basato su 1

    • Eccezioni basate su 0: raccolte UserForm come schede, pagine, controlli (ListBox, TextBox)
    • Le raccolte sono oggetti Excel nativi che contengono gruppi (o elenchi) di oggetti logicamente correlati
    • Normalmente utilizzato per contenere oggetti complessi, ma può contenere anche tipi di base
    • Collezioni di Excel:

      • Quaderni di lavoro, fogli, gamme, forme
      • Fogli (1) è il primo nel file, Celle (1, 1) è la cella nella prima riga e nella prima colonna
    • Il vantaggio principale delle raccolte è la comodità di accedere agli elementi per nome

      • Il ciclo For-Each è molto efficiente (rispetto all'elaborazione For-Each degli array)
      • L'accesso ai singoli elementi per indice, tuttavia, è più veloce dell'accesso ad essi per nome

  • Array: basato su 0 per impostazione predefinita, ma il primo indice può essere modificato in qualsiasi numero (illustrato di seguito)

    • Le matrici sono variabili che contengono un insieme di variabili correlate
    • Normalmente utilizzato per tipi di dati primitivi come booleano, intero, lungo, stringa, doppio, ecc
    • Una volta definito, conterrà solo un tipo di elementi: Dim x() As Long

      • Per contenere oggetti più complessi è possibile definire un array come Dim x() As Variant
      • Le varianti possono essere qualsiasi tipo di oggetto, inclusi cartelle di lavoro, fogli, intervalli, matrici

        • 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)
    • Il vantaggio principale delle matrici è la prestazione quando si accede agli elementi per indice

      • For index=0 To 10i loop sono più veloci dei For-Eachloop

  • Dizionari: non indicizzati, ma gli indici possono essere simulati con le chiavi

    • Nativo di VB Script, non VBA (deve utilizzare una libreria esterna)
    • Può contenere qualsiasi tipo di oggetto, inclusi array, raccolte o altri dizionari

Un ListBox è un oggetto complesso ed è possibile accedervi tramite la raccolta di controlli basata su 0

La proprietà .List () di ListBox è un array basato su 0

Altre note

  • Gli indici basati su 0 sono lo standard per altre lingue

  • VBA ha introdotto il concetto basato su 1 per renderlo più intuitivo per i nuovi utenti:

    • Da Foglio1 a Foglio3, con un conteggio di 3 più facile da usare di
    • Da Sheet0 a Sheet2, con raccolta Conteggio di 3

Alcuni esempi pratici della differenza tra i loro indici:

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

Ulteriori letture:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.