Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Определение размера пустых массивов Добавлено: 16.05.06 12:40  

Автор вопроса:  objMihail
Требуется сделать функцию на VB6, которая добавляет к массиву элемент в конец. В функцию передаётся добавляемый элемент и массив. Массив динамический. Массив может быть пустым (быть только объявлянным, без указания числа элементов), или иметь уже некоторое количество элементов.

Так вот, если в функцию передать пустой массив (с нулём элементов), то попытки определить его размер с помощью UBound(Массив) приводят к ошибке выхода за границы. И никакие другие способы не помогают - сравнения с Nothing с Empty и др. тоже приводят либо к ошибкам либо ничего не дают.

Так как определить факт того, что в массиве отсутствуют элементы? Можно, конечно, перехватывать ошибку выхода за границы, но, боюсь, это сильно замедлит скорость выполнения. Да и путь это какой-то извилистый...
Весь Интернет перерыл, но ничего не нашел. Подскажите, кто знает.


Вот код глючащей процедуры:

Public Sub Добавить(Массив() As String, Текст As String)

    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-сайт: vt-dbnz.narod.ru
 Профиль | | #4
Добавлено: 16.05.06 16:26
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
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


Пользоваться так:
Dim Ary() As Long
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 будет достаточно. И то не обязательно.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам