Страницы: 1
RSS
Как обьявить и использовать массив, если наперед неизвестны его размеры?
 
доброго времени, есть макрос с массивом, в теории все должно работать, но ругается при попытке заполнения массива.
Код
Sub sreda()
Dim sr()
s = 1
For d = 1 To 31
    dd = DateSerial(Year(Date), 9, d)
    If Weekday(dd, vbMonday) = 3 Then
        MsgBox "day   " & Day(dd)
        MsgBox "s   " & s
        sr(s) = Day(dd)
        s = s + 1
        MsgBox "s+1   " & s
    End If
Next
For s = 1 To 5
    MsgBox sr(s)
Next
End Sub
почему выдает ошибку и как исправить?
заработало без оштбок только при явном определении размера массива, почему динамический не идет?
Изменено: Irbis_evs - 30.07.2019 11:34:02
Инженер не тот, кто все знает, а тот кто знает где найти ответ.
 
В теории размерность массива нужно определять ДО его наполнения.
Согласие есть продукт при полном непротивлении сторон
 
Добавьте
Код
ReDim Preserve sr(s)
Перед
Код
sr(s) = Day(dd)
и
Код
MsgBox sr(s)
 
но если заранее не известна размерность (ну допустим такое) как тогда быть с заполнением?
Инженер не тот, кто все знает, а тот кто знает где найти ответ.
 
спс
Инженер не тот, кто все знает, а тот кто знает где найти ответ.
 
Код
ReDim Preserve sr(s)
Как раз и переопределяет каждый раз размер массива значением s
 
GRIM, спс, понял, попутно исправил еще один косячек
Инженер не тот, кто все знает, а тот кто знает где найти ответ.
 
Название темы кто будет придумывать?
 
название темы:
как обьявить и использовать массив если наперед не известны его размеры?
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
vikttur, «Ошибка при наполнении динамического массива»
Цитата
Irbis_evs: почему динамический не идет?
здравствуйте. Потому что надо учить матчасть
Цитата
GRIM: ReDim Preserve sr(s)
в данном случае прокатит, но вообще-то очень ресурсозатратно в цикле постоянно увеличивать размерность.

Как лучше:
1. Объявить размерность с запасом (количество элементов, больше которого точно не будет. В примере = 31). Если "запас" огромный (миллионы), то можно переполнить память и получить ошибку.
    1.1. По окончании цикла сделать 1 раз ReDim Preserve до нужного количества элементов.
    1.2. Выводить только нужное количество (непустые элементы массива)
2. Узнать точное количество и задать размерность точно - тогда ReDim Preserve не нужен

P.S.: для отладки в цикле (вывод значений) лучше использовать Debug.Print вместо MsgBox, т.к. он "пишет" результат в окне Immediate, не останавливая код. А в MsgBox можно посмотреть итог, например сцепку элементов массива Join(arr), если их не много.

P.P.S.: как советует Hugo (ниже) может быть быстрее, но надо тестить. Также, в качестве одномерного массива, размерность которого не нужно определять, можно использовать словарь, но этот объект сторонний и его нужно будет подключать поздним связыванием. Словарь также можно разложить на 2 одномерных массива: ключей и элементов
Изменено: Jack Famous - 30.07.2019 12:01:32
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
В данном случае вместо массива удобно использовать коллекцию без ключа  -наполняете её сколько получается/нужно, в итоге имеете одномерное собрание значений, что по сути и есть одномерный массив или коллекция.
Вот, не вникая в суть и смысл, только заменил массив на коллекцию:
Код
Sub sreda()
Dim sr As New Collection, s&, d&, dd As Date
s = 1
For d = 1 To 31
    dd = DateSerial(Year(Date), 9, d)
    If Weekday(dd, vbMonday) = 3 Then
        MsgBox "day   " & Day(dd)
        MsgBox "s   " & s
        sr.Add Day(dd)
        s = s + 1
        MsgBox "s+1   " & s
    End If
Next
For s = 1 To sr.Count
    MsgBox sr(s)
Next
End Sub
Изменено: Hugo - 30.07.2019 12:08:17
Страницы: 1
Наверх