Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Subscript out of range on an Array

Posted on 2000-08-16
7
479 Views
Last Modified: 2008-02-01
I Have a Function that returns an Array.  When the function has return I do a UBound to get the count of array elements.  If the function doesn't fill the array (like if no records are available) I get the subscript out of range error. I can work around it with error trapping but I was wondering if there is a way to check the array size without getting the error?
0
Comment
Question by:tomkent
7 Comments
 
LVL 14

Expert Comment

by:mcrider
ID: 3957272
You can code your own function...  For example:

    Function GetUbound(ArrayObject As Variant)
        Dim iVal As Long
        On Error Resume Next
        iVal = -1
        iVal = UBound(ArrayObject)
        GetUbound = iVal
    End Function



To use this function, you can do something like this:
   
    Private Sub Command1_Click()
        Dim x() As String
        Dim y As Long
       
        y = GetUbound(x)
        If y = -1 Then
            MsgBox "No Items in array"
        Else
            MsgBox "Ubound is " + CStr(y)
        End If
    End Sub



Cheers!®©
0
 
LVL 2

Accepted Solution

by:
ParallelProcessor earned 200 total points
ID: 3958174
Tom,

I agree - error trapping is a messy way to do it. Also, error trapping is not a very fast way to do it and it is a pain if you are debugging your project with the debugger set to stop at all errors.

The trick that I use is to read the SAFEARRAY descriptor in memory (Matt Curland's book is a great resource for these kinds of tricks). This particular bit of code can also be found on www.vb2themax.com

Good Luck!

Jon





To use, one would write the following code:

if ArrayDims(TestArray)=0 then
  msgbox "TestArray is empty"
end if


Add the following function to a module:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As _
    Any, Source As Any, ByVal bytes As Long)


Function ArrayDims(arr As Variant) As Integer
    Dim ptr As Long
    Dim VType As Integer
   
    Const VT_BYREF = &H4000&
   
    ' exit if not an array
    If (VType And vbArray) = 0 Then Exit Function
   
    CopyMemory ptr, ByVal VarPtr(arr) + 8, 4
    If (VType And VT_BYREF) Then
        CopyMemory ptr, ByVal ptr, 4
    End If
   
    If ptr Then
        CopyMemory ArrayDims, ByVal ptr, 2
    End If
End Function
0
 

Expert Comment

by:ArtWroble
ID: 3958292
Back in the early days of BASIC, it seems to me that there was some ambiguity about the i'th element of a vector, in some cases the first element's subscript was 0 or 1.  But I don't remember what was the default.  I vaguely remember you had to define it near where you Dim'd the array.  I wonder if it carried over into VB.  You might try looking at that aspect.  
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 14

Expert Comment

by:wsh2
ID: 3961200
If you Redim the array immediately after you create it then your UBound WILL work.

<---- Code Begin ----->

Private Sub Form_Load()

   If UBound(xMyArray) = 0 _
   Then
      MsgBox "Empty Table"
   End If

End Sub

Private Function xMyArray() As Variant

   Dim x() As String
   ReDim x(0)
   '
   ' Your Processing Here
   '
   xMyArray = x()
   
End Function

<----- Code End ----->

If you store your data in elements 1 on up this works very simply. If you want to use element 0, then you have to initialize it with a Unique value.. and test for it to find out if the array is empty.

<---- Code Begin ----->

Private Sub Form_Load()

   If xMyArray(0) = -32768 _
   Then
      MsgBox "Empty Table"
   End If

End Sub

Private Function xMyArray() As Variant

   Dim x() As Integer
   ReDim x(0)
   x(0) = -32768
   xMyArray = x()
   
End Function

<----- Code End ----->


0
 
LVL 1

Expert Comment

by:mindphaser
ID: 3966806
Public Function IsBound(vArray As Variant) As Boolean
   On Error Resume Next
   IsBound = IsNumeric(UBound(vArray))
End Function
0
 
LVL 13

Expert Comment

by:crazyman
ID: 3967252
            Private Declare Sub Copymemory Lib "kernel32" Alias "rtlmovememory" _
        (pdest As Any, Psrc As Any, Byval Bytelen As Long)


Private Function Getarraydimensions(byval Arrptr As Long) As Integer
    Dim Address As Long
    Copymemory Address, Byval Arrptr, Byval 4
    If Address <0 Then
        Copymemory Getarraydimensions, Byval Address, 2
    End If
End Function

Private Function Varptrarray(arr As Variant) As Long
    Copymemory Varptrarray, Byval Varptr(arr) + 8, Byval 4
End Function


Private Sub Form_load()
    Dim Myarr() As Long
    Dim Ndims As Integer

   Ndims = Getarraydimensions(varptrarray(myarr))
    If Ndims > 1 Then
        Msgbox "the Array Has " & Ndims & " Dimension(s)."
    Else
        Msgbox "the Array Has Not Been Initialized."
    End If
End Sub



           
0
 
LVL 14

Expert Comment

by:wsh2
ID: 3967398
Unless a dynamic array is ReDim'd.. there is NO WAY to test for its existence in VB (or the API for that matter). The best thing to do is always ReDim the array right after it's (Dim)creation.. after that UBound and other tests will always work.. <smile>.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question