?
Solved

Subscript out of range on an Array

Posted on 2000-08-16
7
Medium Priority
?
486 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
[X]
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
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 800 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…
Suggested Courses
Course of the Month13 days, 14 hours left to enroll

801 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