3 GBSingh [2015-07-29 14:00:00]

Я пытаюсь добавить дату в массив, но не могу это сделать. Каждый раз, когда я пытаюсь это сделать, я получаю ошибку в индексе вне диапазона. Я использовал массивы раньше на других языках, поэтому это должно работать, но это не так, и я не понимаю, почему. Ниже я добавил код, который в настоящее время не работает. То, что я пытаюсь сделать, — после того, как пользователь вводит две даты, мой код должен сохранить начальное значение, а затем добавить его к этой дате и добавить его в массив и так далее, пока у меня не будет списка массивов всей даты с даты начала до даты окончания. Любая помощь будет очень благодарна

date arrays vba excel-vba excel

4 ответа

2 Решение 99moorem [2015-07-29 14:13:00]

Попробуйте ниже, redim изменит размер массива. ubound() находит верхний конец массива, поэтому ubound() + 1 добавит один дополнительный размер в массив. Ключевое слово сохранения сохраняет любые значения, которые в настоящее время находятся в массиве

Извещение 1: как я объявил, что переменные str1 — 3 не были объявлены как дата. 2: как я инициализировал ваш массив, не нужно делать 1 к 1, можно просто сказать, что я хочу x amount

Надеюсь, что поможет

Вам нужно увеличить размер массива. Эта строка:

предоставляет только один элемент в вашем массиве. Вы должны использовать:

после того, как вы выработали значение str2.

btw, вы можете использовать функцию Abs , чтобы дать вам положительное число:

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

переменные str1, str2, str3 все объявляются как Variant not Date .

1 mielk [2015-07-29 14:06:00]

Причина в том, что вы объявили массив dateArray как имеющий только один элемент, проиндексированный с помощью 1:

Позже в коде вы попытаетесь присвоить значение элементу этого массива с индексом 0 (но нет такого элемента, и именно поэтому эта ошибка отображается):

0 Rory [2015-07-29 14:20:00]

Вы уже рассчитали размер, чтобы использовать его с Redim один раз вместо использования Preserve , который является относительно дорогостоящей операцией, поскольку он копирует весь ваш массив. Я бы также предложил несколько описательных имен переменных, и вы должны явно объявить тип всех переменных:

Я предположил, что вы выводили результаты на рабочий лист, поэтому я использовал 2D-массив.

1674 просмотра

2 ответа

438 Репутация автора

Q & A: Как можно добавить элемент в конец (динамического) массива в VBA?

Этот же вопрос был для списка вместо массива: Добавление элемента в вариантный список / массив в VBA. Этот же вопрос касался переразметки массивов с 2 измерениями: Переопределение массива в VBA. Этот же вопрос не задавался для общего простого случая. : https://superuser.com/questions/808798/adding-an-element-to-the-end-of-an-array

Ответы (2)

1 плюс

438 Репутация автора

Это короткий код VBA для:

  1. Создать динамический массив.
  2. Перенаправление динамического массива на 3 элемента.

Заполните добавленный элемент значением.

Вот этот код объяснил:

Автор: a.t. Размещён: 15.09.2018 07:26

1 плюс

346 Репутация автора

Я уже сталкивался с этой проблемой, и я решил так

Массивы в VBA Excel: одномерные, многомерные и динамические. Объявление и использование массивов. Операторы Public, Dim и ReDim. Функции Array, LBound, UBound.

Массивы — это множества однотипных элементов, имеющих одно имя и отличающиеся друг от друга индексами. Они могут быть одномерными (линейными), многомерными и динамическими. Массивы в VBA Excel, как и другие переменные, объявляются с помощью операторов Dim и Public. Для изменения размерности динамических массивов используется оператор ReDim. Массивы с заранее объявленной размерностью называют статическими.

Одномерные массивы

Объявление одномерных (линейных) статических массивов в 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:

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

С помощью оператора ReDim невозможно изменить обычный массив, объявленный с заранее заданной размерностью. Попытка переопределить размерность такого массива вызовет ошибку компиляции с сообщением: Array already dimensioned (Массив уже измерен).

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

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

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

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

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

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

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

Функция Array

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

Скопируйте код в модуль VBA Excel и запустите его на выполнение. Информационное сообщение MsgBox покажет значения массива, извлеченные по индексу.

Функция LBound

Функция LBound возвращает значение типа Long, равное наименьшему (нижнему) доступному индексу в указанном измерении массива.
Синтаксис:
LBound (arrayname[, dimension])

  • arrayname — это имя переменной массива, является обязательным аргументом;
  • dimension — это номер измерения массива, необязательный аргумент, по умолчанию принимает значение 1.

Наименьший индекс по-умолчанию может быть равен 0 или 1 в зависимости от настроек оператора Option Base. Нижняя граница архива, полученного с помощью функции Array, всегда равна 0.

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

Функция UBound

Функция UBound возвращает значение типа Long, равное наибольшему (верхнему) доступному индексу в указанном измерении массива.
Синтаксис:
UBound( arrayname[, dimension])

  • arrayname — это имя переменной массива, является обязательным аргументом;
  • dimension — это номер измерения массива, необязательный аргумент, по умолчанию принимает значение 1.

Функция UBound используется вместе с функцией LBound для определения размера массива.

Скопируйте код в модуль VBA Excel и запустите его на выполнение. Информационное сообщение MsgBox покажет значения наименьшего и наибольшего индекса переменной массива a.

Очистка (обнуление) массивов

Первый способ

Очистить любой массив, статический или динамический, без использования цикла можно с помощью оператора Erase. Термин «обнуление» можно применить только к массиву числового типа.

Обратите внимание, что оба массива при таком способе очистки будут возвращены в исходное состояние, которое они имели сразу после объявления:

  • статический Massiv1 сохранит размерность (4, 3);
  • динамический Massiv2 не сохранит размерность ().

Второй способ

Динамический массив можно очистить (обнулить) без использования цикла с помощью оператора ReDim. Просто переопределите его с той же размерностью.

VBA Excel. Массивы (одномерные, многомерные, динамические) : 12 комментариев

Это все очень интересно и здорово, но хотелось бы еще узнать о заполнении массивов.
Например один цикл поможет заполнить одномерный массив. Два цикла двумерный. Но это в случае когда значения рассчитываются.
А если у меня есть двумерный массив с данными (постоянными) и мне надо его "ввести" в программу — как быть? Самый простой пример — календарь. В строках первый элемент месяц, второй элемент 1 число, третий элемент день недели, четвертое — последний день месяца, пятый — день недели последнего числа месяца.
То есть на входе у меня 12 строк, 5 столбцов, массив 5х12.
Теперь мне надо его заполнить, 60 значений. Цикл не подойдет, надо каждое вносить отдельно.
Чисто теоретически можно представить массив как одномерный массив строк, каждый элемент которого состоит из одномерного массива столбцов. А вот как это присвоение оформить в ВБА?

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

Увы, не могу. Дело в том, что :
1. Я пишу не в Екселе, а в Автокаде — там нет ячеек.
2. Мои данные это по сути константы, мне придется их заносить в ячейки (если делать нечто подобное в Екселе), а затем считывать программно. При этом с листа (из ячеек) их надо прятать, что бы случайно никто не изменил. Поэтому данные необходимо вводить в теле программы в массив и далее с ними работать. В то же время необходимо сделать так, что бы при желании было легко добавить еще одну строку с данными.

Артем, я правильно понял, что вы вносите все данные в массив вручную и хотите сделать автоматическое добавление «пустых строк» в массив под новые данные?

Нет, вручную вношу до 50 "строк", вручную добавляю (при необходимости, а необходимость возникает не часто) по 1-15 строк.
В общем на одном форуме подсказали несколько вариантов. Один из наиболее подходящих (для меня) оказался массив массивов. То есть создается массив, каждый элемент которого это тоже массив, содержащий наименование и далее параметры.
При необходимости просто добавляю элемент массива (строку) с наименованием и параметрами и все.
А вот как правильно обратится к каждому элементу массива и как работать с массивом массивов — вот это хорошо бы у вас в статье отобразить.

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

А как узнать размерность массива?

Иван, размерность массива (количество измерений) вы можете узнать с помощью пользовательской функции KolichestvoIzmereniy.

to Артем:
если массив в автокаде надо заполнять какими-то постоянными данными, то почему бы не хранить эти данные в отдельном файле (напр. txt или dbf) и считывать данные оттуда.

Msgbox не переваривает ";" когда ввожу &amp он пилит её на & amp и никак не учитывает, но стоит добавить в конец ";" чтобы получилось & всю строку выделяет красным!

Привет, Павел!
Это защита WordPress заменила амперсанд & на его html-код. Исправил.