массив vb6 с -1 для верхней границы - PullRequest
5 голосов
/ 18 августа 2011

Некоторые функции, такие как Split(), возвращают массив с -1 для верхней границы и ноль для нижней границы, если в массиве нет элементов, например:

Dim s() As String
s = Split("", ",")
Debug.Print UBound(s)
Debug.Pring LBound(s)

В этом случае UBound (s) будет равно -1, а LBound (s) будет равно 0. У меня есть достаточное количество кода, проверяющего -1 на верхней границе, чтобы увидеть, есть ли у массива значения или нет.Это прекрасно работает.

Проблема в том, что теперь я хочу изменить тип данных массива со строки на long.Я не могу создать массив длинных с верхней границей -1 и нижней границей 0, а функции Split() и Join() работают только со строковыми массивами.

Я бы хотел бытьвозможность вернуть длинный массив с верхней границей -1.Это возможно?

Ответы [ 4 ]

4 голосов
/ 18 августа 2011

Я не думаю, что вы можете сделать это в VB6 самостоятельно.Однако, если вы хотите использовать функцию Windows API SafeArrayCreateVector , вы можете сделать это:

Private Declare Function LongSplitEmulator Lib "OLEAUT32.DLL" Alias "SafeArrayCreateVector" _
    (Optional ByVal vt As VbVarType = vbLong, _
     Optional ByVal low As Long = 0, _
     Optional ByVal count As Long = 0) As Long()

Dim a() As Long
a = LongSplitEmulator()
MsgBox UBound(a)

Если вам нужно сделать это для других типов данных, вы можете изменить параметр vt.

Обратите внимание, я думаю, что я первоначально узнал об этом из ответа Vi2 на это обсуждение .

1 голос
/ 18 августа 2011

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

Private Sub SplitLongs(ByVal strData As String, ByRef lng() As Long)
    Dim i As Integer
    Dim s() As String
    s = Split(strData, ",")
    If UBound(s) = -1 Then
        ReDim lng(-1 To -1)
    Else
        ReDim lng(LBound(s) To UBound(s))
        For i = LBound(s) To UBound(s)
            If IsNumeric(s(i)) Then lng(i) = s(i)
        Next
    End If
End Sub
0 голосов
/ 24 августа 2011

Другим способом является строго типизированная «фабричная» функция:

Private Declare Function SafeArrayRedim Lib "oleaut32.dll" (ByVal ArrayPtr As Long, ByRef DataPtr As tagSAFEARRAYBOUND) As Long

Private Type tagSAFEARRAYBOUND
  cElements As Long
  lLbound As Long
End Type

Public Type Feed
  ID As String
  Name As String
  Active As Boolean
  BasePath As String
End Type

Public Sub EmptyFeedArray(ByRef Arr() As Feed)
Dim Data As tagSAFEARRAYBOUND
Dim lngErr As Long

  'Redim to one item
  ReDim Arr(0 To 0)
  'Reset the safe array to empty
  lngErr = SafeArrayRedim(Not Not Arr, Data)
  'Raise any errors
  If lngErr <> 0 Then Err.Raise lngErr
End Sub

Я думаю, что это также работает с целочисленными типами.

0 голосов
/ 18 августа 2011

Одна проблема с VB6 заключается в том, что нет способа надежно создать или обнаружить пустой (или неинициализированный) массив.Иногда можно обнаружить неинициализированный массив, проверив, больше ли верхняя граница, чем нижняя граница;однако, это не элегантно и не задокументировано.Лучший способ сделать это правильно - заключить массив в Variant и установить Variant в значение Empty, чтобы деинициализировать массив.Затем вы можете использовать проверку, например If VarType (v) = vbEmpty ...

...