Проблема с массивом

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Проблема с массивом

Сообщение SLIM » 13.06.2008 (Пт) 21:34

Вот такая ситуация возникла
Код: Выделить всё
Private Type KeyI
  NameK As String
  ValueK As String
End Type

Private Type Sect
  NameS As String
  ValuesS() As KeyI
End Type

Private SectionArr() As Sect

Заполнил массив SectionArr так что допустим есть 3 элемента NameS
В первом NameS есть 2 элемента в ValuesS
Во втором есть три
В третьем есть NameS, но нет ни одного элемента в ValuesS

Теперь задача. Вывести в список такую инфу
1.Имя элемента 1
2.Значение 1
3.Значение2
4.Значение3
5.Имя элемента 2
6.Значение 1
7.Значение 2
.................
Я делал так
Код: Выделить всё
For i = LBound(SectionArr) To UBound(SectionArr)
    Debug.Print SectionArr(i).NameS
    For t = LBound(SectionArr(i).ValuesS) To  Bound(SectionArr(i).ValuesS)
      Debug.Print SectionArr(i).ValuesS(t).NameK & "=" & SectionArr(i).ValuesS(t).ValueK
    Next
  Next

Проблем не возникает когда заполнено все хотя бы одним элементом/ Но если имеется NameS, но нет ValuesS, возникает ошибка.
Что делать?
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 14.06.2008 (Сб) 0:04

Сначала надо подумать (надо было подумать), почему вообще возниает ошибка.

В VB (скажем, в COM а не в VB) верхняя и нижняя граница массива может быть произвольной.
LBound возвращает нижнюю (потому что L - Lower -нижний) границу, а
UBound - верхнюю (потому что U - Upper - верхний).

Для динамических массивов изначально ничего не определено (ни размерность, ни границы).

Судя по тому, что возникает ошибка, ReDim массиву SectionArr(3).ValuesS() никто никто не делал.

Поэтому не понятно, что ты ожидаешь получить от LBound и UBound, подсовывая им неопределённый массив.

Выходы:
1) Изменить логику и хранить в Sect также поле ItemsCount As Long, в котором бы хранилось кол-во элементов в массиве ValuesS().
Индексацию ValuesS() начинать с 1.
Цикл перебора организовать так:
Код: Выделить всё
For t = 1 To SectionArr(i).ItemsCount.

Таким образом, если там нет вообще элементов, то цикл вообще выполняться не станет (как и должно быть), а если 1 или 2 - выполнится столько раз, сколько нужно.
Отказаться от UBound и LBound в данном случае немного полезно, потому что они для дин.массивов работают долго (лезут в SA, проверяют его, если SA неопределён, выкидывают исключении, если определён, читают поле, в котором хранится число размерностей, лезут в нужную размерность и читают соотв. границу. UBound вообще читает два поля - "нижняя граница" и "кол-во элементов", складывает их и таким образом получает верхнюю).

Кстати, рекомендуется использовать j вместо t.

2) Изменить принцип перебора.
(Если первый пункт выполнить невозможно)
Перед
Код: Выделить всё
For t = LBound(SectionArr(i).ValuesS) To UBound(SectionArr(i).ValuesS)
проверять, а не пуст ли массив, и если вдруг пуст -- пропускать цикл.

Проверять можно (придётся) отдельной функцией. Такую функцию можно либо написать самому (например, функция пытается получить LBound, и если возникает ошибка, считается что массив не установлен), либо взять например SafeArrayGetDim.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Сообщение SLIM » 14.06.2008 (Сб) 20:08

проверять, а не пуст ли массив, и если вдруг пуст -- пропускать цикл.
Вот ты и добрался до сути вопроса. Именно это мне и нужно было. Значит нужно проверять "заданность массива" способом "Возникает ли ошибка" и если да то не выполнять, если нет то выполнять.
Спасибо! Кстати проверять с помощью LBound?
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 15.06.2008 (Вс) 2:40

Нет вот что за, а?

Из всех вараинтов, предложенных здесь, ты выбрал худший.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25

    TopList