Vba excel очистить массив

Обновлено: 02.07.2024

Я работаю на надстройку Excel VBA, который обменивает объекты с COM-сервером, что-то вроде этого:

Получение массивов хорошо работает: если массив содержит объекты , которые он работает , как и следовало ожидать, если массив пуст , то UBound(Ents) = -1 и все работает , как ожидалось.

Похоже, Erase оператор покидает массив неопределенный / испорченный , а не пустой.

EDIT (разъяснения в комментарии ниже):

Выполнение этого кода происходит сбой , поскольку он не может вычислить UBound :

Но если добавить Ents к окну часов, а затем установить точку останова на Debug.Print строку и выполнить, отладчик показывает ISmartId(0 to -1) в колонке Type. После этого выполнение продолжается без аварии, а окно отладки показывает ожидаемое -1 .

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

3 stenci [2014-01-22 20:37:00]

Я работаю над добавлением Excel VBA, который обменивается объектами с COM-сервером, примерно так:

Получение массивов работает хорошо: если массив содержит объекты, он работает так, как ожидалось, если массив пуст, то UBound(Ents) = -1 и все работает так, как ожидалось.

Отправка массивов работает только с непустыми массивами, потому что я не могу Redim Ents(-1) и Erase в том, что в массив попадают как VBA, так и COM-сервер: Debug.Print UBound(Ents) сбой в VBA и кто знает, что сбой сервера.

Похоже, что оператор Erase оставляет массив undefined/поврежден, а не пуст.

EDIT (пояснение к комментарию ниже):

Выполнение этого кода происходит сбой, поскольку он не может вычислить UBound :

Но если вы добавите Ents в окно просмотра, установите точку прерывания в строку Debug.Print и выполните, отладчик показывает ISmartId(0 to -1) в столбце Тип. После этого выполнение продолжается без сбоев, а окно Debug показывает ожидаемый -1 .

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

Функции LBound, UBound

Функции LBound, UBound возвращают нижнее и верхнее граничные значения индексов статического или динамического массива.

LBound (array_Name [, dimension])
UBound (array_Name [, dimension])

Нижеприведенный листинг демонстрирует использование функций LBound, UBound:


Очистка и удаление массивов при помощи Erase

Данный оператор обнуляет (если массив статический) или очищает (если массив динамический) массив My_Array.

Оператор Erase удаляет из памяти динамические массивы, освобождая область памяти, ранее используемую этим массивом. При удалении динамического массива с помощью оператора Erase необходимо повторно создать массив с помощью оператора ReDim перед тем, как можно будет использовать этот определенный динамический массив снова.

Поведение оператора Erase для статических массивов зависит от конкретного типа элементов массива (см. таблицу):

Массивы используются для хранения в памяти множества значений. Вместо того, чтобы объявлять множество похожих друг на друга переменных, часто гораздо удобнее воспользоваться массивом.

Объявление массива производится очень просто:

Dim MyArray (2) As Integer

Такой массив может хранить три целочисленных элемента. 2 — это верхняя граница массива (upper bound). Количество элементов, которое может хранить массив, — от 0 до верхней границы включительно.

Если вам хочется, чтобы нумерация элементов в массиве начиналась с 1, то в раздел объявлений модуля нужно внести команду

В принципе, тип данных для массива можно не объявлять:

В этом случае для элементов массива будет использован тип Variant. Такой массив сможет хранить в себе элементы разных типов данных, но требования к памяти у него будут выше и работать он будет чуть медленнее.

Присвоить значение отдельному элементу массива (в нашем случае — первому) можно очень просто:

А затем это значение можно будет извлечь:

MsgBox MyArray (0)

Массивы вполне могут быть многомерными:

В каждой строке многомерного массива удобно хранить данные, относящиеся к одному объекту (например имя сотрудника, уникальный номер, номер телефона). В VBScript в одном массиве может быть до 60 измерений.

Часто необходимы массивы динамические — те, размер которых можно изменять в ходе выполнения. Динамический массив объявляется следующим образом:

Dim MyArray () '- объявляем массив без верхней границы, эту строку можно ‘пропустить

ReDim MyArray (4) ' — изменяем размер массива

Команда ReDim не только изменяет размер массива, но и удаляет из него все старые значения. Чтобы старые значения сохранить, используется ключевое слово Preserve:

ReDim Preserve MyArray (7)

Однако если новый размер массива меньше, чем кол-во помещенных в него элементов, слово Preserve не поможет — часть данных все равно будет потеряна.

Массивы можно создавать и заполнять одновременно при помощи встроенной функции Array():

MyArray = Array(100, 200, 300, 400, 500)

Указывать размер массива необязательно — он будет автоматически настроен в соответствии с кол-вом передаваемых элементов.

Очистить массив можно командой Erase:

Массив фиксированной длины просто очищается, динамический массив разинициализируется — его придется инициализировать (определять размер) заново.

В динамических массивах часто не известно, сколько элементов в массиве. Для определения кол-ва элементов используется функция UBound() (если массив одномерный или вас интересует размер первого измерения, то измерение передавать не надо):

UBound (имяМассива [, измерение])

Как ни удивительно, но при программировании в VBA вам редко придется сталкиваться с массивами. Вместо них в объектных моделях приложений Office обычно используются коллекции. Коллекции — это специальные объекты, которые предназначены для хранения наборов одинаковых элементов. Например, в Word предусмотрена коллекция Documents для хранения элементов Document — то есть всех открытых документов, в Excel — коллекции Workbooks (открытые книги) и Worksheets (листы в книге) и т.п. Коллекции обычно удобнее, чем массивы: они изначально безразмерны и в них предусмотрен стандартный набор свойств и методов (метод Add() для добавления нового элемента, свойство Count для получения информации о количестве элементов, метод Item() для получения ссылки на нужный элемент) Подробнее про работу с коллекциями будет рассказано в главе 4 этой книги.

Как очистить весь массив?
Как насчет коллекции?

Вы можете использовать операторы Erase или ReDim для очистки массива:

Обновление

Чтобы удалить коллекцию, вы перебираете ее элементы и используете метод remove :

Просто быстрое примечание, по крайней мере для VBA, вы не можете переопределить массив, который был объявлен с измерениями. Сарфраз, есть ли причина, по которой вы бы просто не сказали: MyCollection = new Collection. Зачем перебирать это? что если я просто позвоню в ReDim ? Он просто сбрасывает в ноль значения или выделяет новый массив в то время? Мои опасения касаются временных характеристик при вызове ReDim для сброса большого массива в цикле примечание: последняя строка (redim) не нужна, если массив объявлен для всего модуля. Это все не работает с тестом "IsEmpty (aFirstArray)". Я добавил ответ для этой цели

Для удаления динамического массива в VBA используйте команду Erase .

Надеюсь на эту помощь!

По какой причине был опубликован ответ через два года после того, как был задан вопрос, если этот самый ответ уже был опубликован? @Gerg, это очень хорошо сформулированное предложение. Бесполезные комментарии к вам обоим. Нет ответа свидетельствует о стирании. Кроме того, спустя почти год после того, как Андрес опубликовал свой ответ, он фактически дал мне решение для однострочного кода, которое я искал. Если бы я мог опровергнуть оба ваших комментария, я бы сделал это. Добавленные комментарии полезны для тех из нас, кто просматривает их позднее - например, я использовал этот ответ в декабре 2018 года. Спасибо, Андрес, что нашли время опубликовать.

Это так же просто, как:

Тот же ответ, что и Андрес, опубликованный 4 года назад. Не могу понять, как это полезно.

Затем массив будет без содержимого и может быть снова заполнен.

Используйте оператор Redim

i упал в случай, когда очистка всего массива завершилась неудачей с помощью dim/redim:

с 2-мя модульными массивами, приватными внутри пользовательской формы,

Один массив является динамическим и использует модуль класса, другой - фиксированный и имеет особый тип.

И у меня есть sub, объявленный как public, чтобы очистить эти массивы (и связанные с ними временные элементы управления) изнутри и вне пользовательской формы, например:

Объявление одномерных (линейных) статических массивов в VBA Excel:

В первом случае публичный массив содержит 10 элементов от 0 до 9 (нижний индекс по умолчанию — 0, верхний индекс — 9), а во втором случае локальный массив содержит 9 элементов от 1 до 9.

По умолчанию VBA Excel считает в массивах нижним индексом нуль, но, при желании, можно сделать нижним индексом по умолчанию единицу, добавив в самом начале модуля объявление «Option Base 1». Вместо верхнего индекса можно использовать переменную.

Многомерные массивы

Объявление многомерных статических массивов в VBA Excel аналогично объявлению одномерных массивов, но с добавлением размерностей дополнительных измерений через запятую:

Третий массив состоит из 10000 элементов — 10×10×10×10.

Динамические массивы

Динамические массивы в VBA Excel, в отличие от статических, объявляются без указания размерности:

Такие массивы используются, когда заранее неизвестна размерность, которая определяется в процессе выполнения программы. Когда нужная размерность массива становится известна, она в VBA Excel переопределяется с помощью оператора ReDim:

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

При переопределении размерности динамических массивов в VBA Excel теряются значения их элементов. Чтобы сохранить значения, используйте оператор Preserve:

Обратите внимание!
Переопределить с оператором Preserve можно только последнюю размерность динамического массива. Это недоработка разработчиков, которая сохранилась и в VBA Excel 2016. Без оператора Preserve можно переопределить все размерности.

Максимальный размер

Размер массива – это произведение длин всех его измерений. Он представляет собой общее количество элементов, содержащихся в данный момент в массиве.

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

Использование массивов

Приведу два примера, где не обойтись без массивов.

1. Как известно, функция Split возвращает одномерный массив подстрок, извлеченных из первоначальной строки с разделителями. Эти данные присваиваются заранее объявленному строковому (As String) одномерному динамическому массиву. Размерность устанавливается автоматически в зависимости от количества подстрок.

2. Данные в массивах обрабатываются значительно быстрее, чем в ячейках рабочего листа. Построчную обработку информации в таблице Excel можно наблюдать визуально по мерцаниям экрана, если его обновление (Application.ScreenUpdating) не отключено. Чтобы ускорить работу кода, можно значения из диапазона ячеек предварительно загрузить в динамический массив с помощью оператора присваивания (=). Размерность массива установится автоматически. После обработки данных в массиве кодом VBA полученные результаты выгружаются обратно на рабочий лист Excel. Обратите внимание, что загрузить значения в диапазон ячеек рабочего листа через оператор присваивания (=) можно только из двумерного массива.

Функции Array, LBound, UBound

Функция Array

Функция Array возвращает массив элементов типа Variant из первоначального списка элементов, перечисленных через запятую. Нумерация элементов в массиве начинается с нуля. Обратиться к элементу массива можно, указав в скобках его номер (индекс).

у меня есть глобальный массив, prLst() это может переменной длины. Он принимает числа как строки "1" to Ubound(prLst) . Однако, когда пользователь вводит "0" , Я хочу удалить этот элемент из списка. У меня есть следующий код, написанный для выполнения этого:

(B) просто установите "фиктивное" значение в качестве значения вместо фактического удаление элемента

(C) прекратите использовать массив и измените его на VBA.Коллекция. Коллекция-это (уникальная)структура пары ключ/значение, в которой вы можете свободно добавлять или удалять элементы из

при создании массива, почему бы просто не пропустить 0 и сэкономить время, чтобы беспокоиться о них позже? Как упоминалось выше, массивы не подходят для удаления.

Я довольно новичок в vba & excel - только делал это около 3 месяцев - Я думал, что поделюсь своим методом де-дублирования массива здесь, поскольку этот пост кажется ему актуальным:

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

Я надеюсь, что люди найдут это полезным, С уважением Джо!--2-->

удаление элементов в массиве, если элемент имеет определенное значение VBA

чтобы удалить элементы в массиве с определенным условием, вы можете закодировать следующим образом

Я часто манипулирую 1D-массивом с Join / Split но если вам нужно удалить определенное значение в нескольких измерениях, я предлагаю вам изменить этот массив на 1D-массив, как это

вот пример кода, с помощью CopyMemory функция для выполнения задания.

предположительно "намного быстрее" (в зависимости от размера и типа массива. ).

Я не автор, но я проверял это :

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

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

Читайте также: