Зачем использовать массивы в VBA, когда есть коллекции?

многие люди широко используют массивы в Excel / VBA для хранения списка данных. Однако есть объект коллекции, который, на мой взгляд, намного удобнее (в основном: не нужно повторно/определять длину списка).

Итак, я искренне спрашиваю себя, не упускаю ли я чего-то? Почему другие люди все еще используют массивы для хранения списка данных? Это просто похмелье прошлого?

3 ответов


несколько причин использовать массивы вместо коллекций (или словарей):

  • вы можете легко перенести массив в диапазон (и наоборот) с помощью Range("A1:B12") = MyArray
  • коллекции могут хранить только уникальный ключи, тогда как массивы могут хранить любое значение
  • коллекции должны хранить пару (ключ, значение), тогда как вы можете хранить все, что угодно в массиве

посмотреть статья чипа Пирсона о массивах для лучшего понимание

лучше спросить, почему люди будут использовать коллекции над словарями (хорошо, коллекции являются стандартными VBA, тогда как вы должны импорт словари)


@CharlesWilliams ответ правильный: цикл через все значения массива быстрее, чем итерация коллекции или словаря: настолько, что я всегда использую метод Keys() или Items() словаря, когда мне нужно это сделать - оба метода возвращают векторный массив.

примечание: Я использую класс Dictionary намного больше, чем я использую коллекции, метод Exists() слишком полезен.

есть, или, конечно, недостатки в коллекциях и словарях. Один из них это массивы могут быть 2-или даже 3-мерными-гораздо лучшая структура данных для табличных данных. Вы can хранить массивы как члены коллекции, но есть некоторые недостатки: один из них заключается в том, что вы не можете получить ссылку на элемент - если вы не используете arrItem = MyDictionary(strKey) вы почти наверняка получите копию массива "ByVal"; это плохо, если ваши данные являются динамическими и могут быть изменены несколькими процессами. Это также медленно: много распределения и освобождение.

хуже всего, я не совсем доверяю VBA, чтобы освободить память, если у меня есть коллекция или словарь с массивами (или объектами!) как члены: не на вне-области, не Set objCollection = Nothing, даже не по objDictionary.RemoveAll-трудно доказать, что проблема существует с ограниченным набором инструментов тестирования, доступным в VBE, но я видел достаточно утечек памяти в приложениях, которые использовали массивы в словарях, чтобы знать, что вам нужно быть осторожным. Как говорится, Я никогда не использую массив без команды стирания.

@JMax объяснил другой большой плюс для массивов: вы можете заполнить массив одним "ударом" на листе и записать свою работу одним "ударом".

вы можете, конечно, получить лучшее из обоих миров, построив класс индексированного массива: 2-мерный массив со связанными объектами коллекции или словаря, хранящими какой-то идентификатор строки в качестве ключей, и ординалы строк в качестве элементов данных.


коллекции, которые автоматически изменяют размер, медленнее (теоретически говоря, разные реализации, очевидно, будут иметь свой собственный пробег). Если вы знаете, что у вас есть заданное количество записей, и вам нужно только получить к ним доступ линейным способом, то традиционный массив является правильным подходом.