vb6 array with -1 for upper bound
Asked Answered
R

4

5

Some functions such as Split() will return an array with -1 for the upper bound and zero for the lower bound if the array has no items, eg:

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

In this case UBound(s) will equal -1 and LBound(s) will equal 0. I have a fair amount of code checking for -1 on the upper bound to see if the array has values or not. This works great.

The problem is that I now want to change the array data type from string to long. I cannot seem to create an array of longs with an upper bound of -1 and a lower bound of 0, and the Split() and Join() functions only operate on string arrays.

I would like to be able to return a long array with an upper bound of -1. Is this possible?

Recrudescence answered 17/8, 2011 at 20:54 Comment(2)
I may have missed your point here but you can create an array of Long with upperbound -1: Dim lngArray(-1 To -1) As LongHerbert
@Matt @Recrudescence Bugtussle, you should probably explain in your question that you want a lower bound of zero as well as an upper bound of -1! Otherwise you have to know the behaviour of Split really well. I'll edit your question accordinglyAlexalexa
C
4

I don't think you can do it in VB6 it self. However, if you're willing to use the Windows API function SafeArrayCreateVector you can do it:

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)

If you need to do it for other datatypes you can change the vt parameter.

Please note, I think I originally found out about this from Vi2's answer to this discussion.

Carchemish answered 17/8, 2011 at 21:43 Comment(1)
This creates an array with lbound 0 and ubound -1 which behaves exactly like the split function when s = Split("", ","). ThanksRecrudescence
H
1

You could write your own split function to do this:

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
Herbert answered 18/8, 2011 at 10:44 Comment(1)
I was looking for redim lng(-1 to -1). Thanks. I think I only tried ReDim(-1) and ReDim(0 to -1) and received an error :PRecrudescence
A
0

One problem with VB6 is there is no way to reliably create or detect an empty (or uninitialized) array. Sometimes, it is possible to detect an uninitialized array by checking whether the upper-bound is greater than the lower-bound; however, this is neither elegant nor documented. The best way to accomplish such a thing properly is to enclose the array in a Variant, and set the Variant to Empty to deinitialize the array. You may then use a check such as If VarType(v) = vbEmpty ...

Aronow answered 17/8, 2011 at 21:2 Comment(1)
I think it's elegant. You can consider it as the null object patternAlexalexa
T
0

Another way is a strongly typed "factory" function:

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

I think this also works with integral types.

Telemotor answered 24/8, 2011 at 11:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.