Страница: 1 |
Страница: 1 |
Вопрос: Определение размера пустых массивов
Добавлено: 16.05.06 12:40
Автор вопроса: objMihail
Требуется сделать функцию на VB6, которая добавляет к массиву элемент в конец. В функцию передаётся добавляемый элемент и массив. Массив динамический. Массив может быть пустым (быть только объявлянным, без указания числа элементов), или иметь уже некоторое количество элементов.
Так вот, если в функцию передать пустой массив (с нулём элементов), то попытки определить его размер с помощью UBound(Массив) приводят к ошибке выхода за границы. И никакие другие способы не помогают - сравнения с Nothing с Empty и др. тоже приводят либо к ошибкам либо ничего не дают.
Так как определить факт того, что в массиве отсутствуют элементы? Можно, конечно, перехватывать ошибку выхода за границы, но, боюсь, это сильно замедлит скорость выполнения. Да и путь это какой-то извилистый...
Весь Интернет перерыл, но ничего не нашел. Подскажите, кто знает.
Вот код глючащей процедуры:
Dim НовыйРазмер As Long
НовыйРазмер = UBound(Массив) + 1 ' Здесь происходит ошибка.
ReDim Preserve Массив(НовыйРазмер)
Массив(НовыйРазмер) = Текст
End Sub
Ответы
Всего ответов: 6
Номер ответа: 1
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #1
Добавлено: 16.05.06 12:51
Проще всего - проверяй UBound(MyArray) на ошибку, только обработчик добавь.
Как вариант - используй апишку SafeArrayGetUBound, проверяй возвращаемое значение на DISP_E_BADINDEX, но по скорости оптимальное - не использовать UBound вообще. Введи переменную типа Long, которая будет содержать размер массива, и, соответственно, ReDim на неё.
Номер ответа: 2
Автор ответа:
objMihail
Вопросов: 1
Ответов: 1
Профиль | | #2
Добавлено: 16.05.06 13:06
Ладо, буду таскать за массивами переменные с их размером. Выглядит не так уж сложно.
Спасибо за ответ.
Номер ответа: 3
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #3
Добавлено: 16.05.06 13:18
Имеет смысл только в случае критичиской нехватки быстродействия, и то слабо помогает. Это не твой случай.
Проще сделай так
Public Sub AddElement(MyArray() As String, Text As String)
On Error Resume Next
Dim NewDim As Long
NewDim = UBound(MyArray) + 1 ' Здесь происходит ошибка.
If Err Then NewDim = 0
ReDim Preserve MyArray(NewDim)
MyArray(NewDim) = Text
End Sub
Извини, русские имена переменных не выношу
Номер ответа: 4
Автор ответа:
Victor
ICQ: 345743490
Вопросов: 42
Ответов: 385
Web-сайт:
Профиль | | #4
Добавлено: 16.05.06 16:26
Public Declare Function AryPtr Lib "msvbvm60.dll" Alias "VarPtr" (Ary() As Any) As Long
Public Function IsAryEmpty(ByVal ptrAry As Long) As Boolean
Dim PtrStruc As Long
If ptrAry = 0 Then
Err.Raise 1111, "IsAryEmpty", "Illegal pointer passed. Use AryPtr(array)! And do not rely on this error in your code!!!"
End If
CopyMemory PtrStruc, ByVal ptrAry, 4
IsAryEmpty = PtrStruc = 0&
End Function
Пользоваться так:
Erase ary
If IsAryEmpty(AryPtr(ary)) Then
Debug.Print "Empty!"
End If
Номер ответа: 5
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #5
Добавлено: 17.05.06 19:28
свой аналог Ubound'a с On error resume next
Номер ответа: 6
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #6
Добавлено: 18.05.06 12:04
Ну, пошли пятиколесные полноприводные велосипеды...
Нахрена городить кучу апишек для такой задачи? А CopyMemory вообще хлебом не корми - дай gpf выкинуть.
Если уж хочется использовать АПИ - одной SafeArrayGetUBound будет достаточно. И то не обязательно.