Использование VBA для доступа к первому листу на рабочем листе - это «Рабочие листы» (1). Первым элементом в ListBox является myListBox.Список (0). Я слышал, что коллекции основаны на 1, но я не знаю, что это такое. Массивы VBA основаны на 0. Строковые функции Excel, такие как MID, основаны на 1. Есть ли общий принцип относительно того, что основано на 0 или 1, или вы могли бы предоставить список каждого?
1 ответ
Существует три основных типа группирующих конструкций, доступных в VBA, с различиями между индексами
Коллекции - 1 основанный индекс
- Исключения на основе 0: коллекции пользовательских форм, такие как вкладки, страницы, элементы управления (ListBox, TextBox)
- Коллекции - это собственные объекты Excel, которые содержат группы (или списки) логически связанных объектов.
- Обычно используется для хранения сложных объектов, но может также содержать базовые типы
Коллекции Excel:
- Рабочие тетради, листы, диапазоны, формы
- Sheets (1) является первым в файле, Cells (1, 1) является ячейкой в первой строке и первом столбце
Основным преимуществом коллекций является удобство доступа к элементам по имени
- Цикл For-Each очень эффективен (по сравнению с обработкой массивов For-Each)
- Доступ к отдельным элементам по индексу, однако, быстрее, чем доступ к ним по имени
Массивы - по умолчанию на основе 0, но первый индекс можно изменить на любое число (показано ниже)
- Массивы - это переменные, которые содержат набор связанных переменных
- Обычно используется для примитивных типов данных, таких как Boolean, Integer, Long, String, Double и т.д.
Как только он будет определен, он будет содержать только один тип предметов:
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
Словари - не индексируются, но индексы можно моделировать с помощью клавиш
- Родной для VB Script, а не VBA (должен использовать внешнюю библиотеку)
- Может содержать объекты любого типа, включая массивы, коллекции или другие словари.
ListBox - сложный объект, доступ к которому можно получить через коллекцию элементов управления на основе 0
.Свойство List() объекта ListBox представляет собой массив на основе 0
Другие заметки
Основанные на 0 индексы являются стандартом для других языков
VBA представила концепцию на основе 1, чтобы сделать ее более понятной для новых пользователей:
- Sheet1 to Sheet3, с коллекцией Count 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
Дальнейшее чтение: