Які об’єкти Excel мають нульовий характер, а які - одноосновні?


20

Використання VBA для доступу до першого аркуша на робочому аркуші - це Workheets (1). Перший елемент у ListBox - це myListBox.List (0). Я чув, що колекції базуються на 1, але не знаю, що вони. Масиви VBA засновані на 0. Функції рядка Excel, такі як MID, засновані на 1. Чи існує загальний принцип того, що базується на 0 або 1, чи ви можете надати список кожного?


клітинка (1,1) .характеристики (індекс, довжина) дорівнює 1, але робить якесь обмеження межі таким чином, що комірка (1,1) .характеристики (0, довжина) = комірка (1,1) .характеристики (1, довжина) (excel 2013)
seanv507

Відповіді:


24

У VBA доступні 3 основні типи групувальних конструкцій з відмінністю між індексами

  • Колекції - індекс на основі 1

    • Винятки на основі 0: колекції UserForm, такі як вкладки, сторінки, елементи керування (ListBox, TextBox)
    • Колекції - це власні об'єкти Excel, які містять групи (або списки) логічно пов'язаних об'єктів
    • Зазвичай використовується для вміщення складних об'єктів, але також може містити основні типи
    • Колекції Excel:

      • Робочі зошити, аркуші, діапазони, форми
      • Таблиці (1) - це перша у файлі, комірки (1, 1) - клітина в першому рядку та першому стовпчику
    • Основна перевага колекцій - зручність доступу до елементів по імені

      • Для кожного циклу дуже ефективна (порівняно з обробкою масивів For-Every)
      • Доступ до окремих елементів за індексом швидше, ніж доступ до них по імені

  • Масиви - за замовчуванням на основі 0, але перший індекс можна змінити на будь-яке число (проілюстровано нижче)

    • Масиви - це змінні, що містять набір пов'язаних змінних
    • Зазвичай використовується для примітивних типів даних, таких як булеві, цілі, довгі, рядкові, подвійні тощо
    • Після того, як буде визначено, він буде містити лише один тип елементів: Dim x() As Long

      • Для вміщення більш складних об'єктів масив можна визначити як Dim x() As Variant
      • Варіантами можуть бути будь-який тип об’єктів, включаючи робочі зошити, аркуші, діапазони, масиви

        • 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)
    • Основна перевага масивів - продуктивність при доступі до елементів за індексом

      • For index=0 To 10петлі швидші, ніж For-Eachпетлі

  • Словники - не індексовані, але індекси можна імітувати за допомогою клавіш

    • Native to VB Script, а не VBA (повинен використовувати зовнішню бібліотеку)
    • Може вміщувати будь-який тип об’єктів, включаючи масиви, колекції чи інші словники

ListBox - складний об'єкт, до нього можна отримати доступ через колекцію елементів керування на основі 0

Властивість .List () ListBox - це масив на основі 0

Інші примітки

  • Індекси на основі 0 - це стандарт для інших мов

  • VBA представила концепцію на основі 1, щоб зробити її більш інтуїтивно зрозумілою для нових користувачів:

    • Sheet1 to Sheet3, з колекції Кількість 3 легше у використанні, ніж
    • Sheet0 to Sheet2, зі збіркою Кількість 3

Деякі практичні приклади різниці між їх показниками:

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

Подальше читання:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.