Как создать экземпляр динамического пустого массива и добавить его первый элемент? - PullRequest
3 голосов
/ 30 апреля 2019

Я пытался создать пустой массив, в который я буду добавлять элементы. По какой-то причине мой скрипт выдает ошибку при простом вызове Ubound для пустого массива. Я не могу понять, как создать пустой массив ... Вот что у меня есть:

Dim data_dates 
data_dates = Array("6/24/2019", "7/1/2019", "7/8/2019", "7/15/2019", "7/22/2019", "7/29/2019", "8/5/2019", "8/12/2019", "8/19/2019", "8/26/2019", "9/2/2019")
Dim site_dates

For date_iter = 1 To UBound(data_dates)
    If start_date <= data_dates(date_iter) And last_date <= data_dates(date_iter) Then
        MsgBox UBound(site_dates) '- LBound(site_dates) + 1
        site_dates(UBound(site_dates) + 1) = data_dates(date_iter)
    End If
Next date_iter

Так что строка MsgBox выдает ошибку. Нормально ли для Ubound выдавать ошибку в пустой массив? Если да, то как мне добавить первый элемент в пустой массив?

Ответы [ 3 ]

3 голосов
/ 30 апреля 2019
Dim site_dates

Эта переменная неявная Variant.В то время как Variant может очень хорошо удерживать массив, он инициализируется в Variant/Empty, который не является массивом - поэтому UBound(site_dates) выдает ошибку: вы пытаетесь получить верхнюю границу Variant/Emptyи VBA не знает, что с этим делать.

Это объявляет динамический массив Variant элементов:

Dim site_dates()

Тем не менее, как правило, следует избегать изменения размеров массивов (цикл с ReDim Preserve theArray(UBound(theArray) + 1) копирует весь массив на каждой итерации просто для добавления одного элемента - штраф становится более очевидным с большим количеством элементов): если вы не знаете, сколько элементов вам понадобится, обычно этоЛучше использовать элементы Collection и Add по ходу дела.Если вы знаете, сколько элементов вам понадобится, то определите размер массива на сайте объявления соответствующим образом:

Dim site_dates(1 To 10)

Обратите внимание, что операторы Dim не являются исполняемыми, поэтому вы можете 'использовать переменную.Для этого используйте оператор ReDim:

ReDim site_dates(1 To datesCount)

ReDim действует как декларативный оператор, поэтому вам не нужно указывать Dim, даже если указано Option Explicit.

В этом случае вы можете использовать Application.WorksheetFunction.CountIf, чтобы получить число дат, соответствующих критериям, и задать размер массива перед началом итерации значений.

1 голос
/ 30 апреля 2019

Один из способов начать процесс роста:

Sub InTheBeginning()
    Dim site_dates() As Date, msg As String
    ReDim site_dates(1)

    For i = 1 To 10
        ReDim site_dates(1 To UBound(site_dates) + 1)
    Next i


    msg = LBound(site_dates) & vbCrLf & UBound(site_dates)
    MsgBox msg
End Sub

enter image description here

0 голосов
/ 01 мая 2019

Сначала убедитесь, что вы используете Вариант базы 1, потому что начните свои циклы с 1 ??

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

Отслеживать количество подходящих элементов, записанных в счетчике в цикле «Логика If».Затем, в конце, вы можете Redim Preserve до сгенерированной суммы:

ReDim Preserve site_dates(1 to qualifyingCounter)

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

Ссылка на mscorlib и использование ArrayList

Dim data_dates
data_dates = Array("6/24/2019", "7/1/2019", "7/8/2019", "7/15/2019", "7/22/2019", "7/29/2019", "8/5/2019", "8/12/2019", "8/19/2019", "8/26/2019", "9/2/2019")

Dim siteDate_ArrayList As New ArrayList

Dim date_iter As Long
For date_iter = 0 To UBound(data_dates)
    If date_iter Mod 2 = 0 Then 'I changed this logic just for my test
        siteDate_ArrayList.Add data_dates(date_iter)
    End If
Next date_iter

Dim site_dates As Variant
'Please note that array resultant from ToArray on an empty ArrayList will have a Ubound of -1
site_dates = siteDate_ArrayList.ToArray

РЕДАКТИРОВАТЬ: Для ссылки, перейдите в Инструменты -> Ссылки и посмотрите вниз по алфавиту mscorlib.dll.Тогда проверьте это.

enter image description here

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