Solved

How to find the length of an array in VB6?

Posted on 2010-08-31
20
1,014 Views
Last Modified: 2012-05-10
hi,

I am trying to find the number of elements in an array. and then print each value in the array.
Can anybody please suggest how to do this? The following is not working. Thanks.


Private Sub Form_Load()
    Dim strarray() As String
    strarray(0) = "1"
    strarray(1) = "2"
       
    For i = 1 To Len(strarray())
        MsgBox (strarray(i))
    Next
End Sub
0
Comment
Question by:ipjyo
  • 6
  • 3
  • 2
  • +5
20 Comments
 
LVL 47

Expert Comment

by:Wayne Taylor (webtubbs)
ID: 33572051
0
 
LVL 47

Assisted Solution

by:Wayne Taylor (webtubbs)
Wayne Taylor (webtubbs) earned 25 total points
ID: 33572066
Also, because the first index of your array is 0, you'll need to do this....

    For i = 0 To UBound(strarray)
        MsgBox (strarray(i))
    Next
0
 

Author Comment

by:ipjyo
ID: 33572107
Thanks for the suggestion. Now the below code is working. I had to include "ReDim" statement also.
But if I dont know how many values this array is going to hold, how can I define the upper bound in the ReDim statement. Is there any alternative way? Thanks.

Private Sub Form_Load()
    Dim strarray() As String
       
    ReDim strarray(2) As String
   
    strarray(0) = "1"
    strarray(1) = "2"
           
    For i = 0 To UBound(strarray) - 1
        MsgBox (strarray(i))
    Next
End Sub
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 75 total points
ID: 33572156
Use a collection instead...it will "grow" automatically to hold as many items as you want.

    Dim col As New Collection
    col.Add "1"
    col.Add "2"
    col.Add "3"

The Count() property will tell you how many items are in it:

    MsgBox col.Count & " item(s)"

See: http://msdn.microsoft.com/en-us/library/aa242681(VS.60).aspx
0
 
LVL 4

Expert Comment

by:coolcurrent4u
ID: 33572834
this should work, tell me if you get errors
Private Sub Form_Load()

    Dim strarray() As String

    strarray(0) = "1"

    strarray(1) = "2"

       

    For i = 1 To ubound(strarray)

        MsgBox (strarray(i))

    Next

End Sub

Open in new window

0
 

Author Comment

by:ipjyo
ID: 33573065
hi,

did nt work for me.
I got the below error.

Run-time error '9':

Subscript out of range

0
 
LVL 16

Accepted Solution

by:
HooKooDooKu earned 150 total points
ID: 33573360
You have to tell VB how big to make the array.  In VB6, you can even set the lower and upper bound.  As an example, you can use...
ReDim strarry(-10 to 10)
...to create an array with 21 elements with indexes from -10 to 10 (index 0 makes the total 21).

If you do not specify a lower bound, VB will assume 0 (unless you use some specially setting that I don't recall off hand to set the default lower bound to something else.  Unlike C, C++, and similar languanges, when you set the upper bound, that is the last index.  So a command like...
ReDime strarray(10) creates and array with 11 elements (index 0 to 10).

You can "grow" an array with the Preserve key word...
ReDim Preserve strarray(100)
...but you don't want to do this very often, because the process actually creates a new array and COPIES the old values to the new array.  So if you want to use the Preserve key word, it would be better to "grow" the array in appropriately sized block and use a seperate variable to track the last element used....

Public Sub AddValueToArray( ByRef strarray() as string, LastIndex as integer, str as string )
Dim UB as integer
  UB = UBound( strarray )
  if UB = LastIndex  then
    ReDim Preserve strarray( UB + 20 )
  end if
  LastIndex = LastIndex + 1
  strarray( LastIndex ) = str
End Sub

...Of course the size by which to grow your array would be based on what you expect to be reasonable values the program is expected to encounter.

Other than ReDim Preserve, your next best bet is the Collection object that Idle Mind is directing you at.  It is an object with only about 4 properties/functions.  Add inserts an item in the collection.  It has optional parameters to specify where in the collection to insert the item, and even assign a key string that can be used to access the value (or you can access elements by index, such as ...
str = Col.Item(1)
...but the biggest weakness of using keys in a collection is that the collection has no way to tell you if a given key exists (beyond trying to access an item by key and use On Error blocks to catch the error that results).

Otherwise, like I said, you have to tell VB how big an array is... an if you need to ask VB how big you made it, you use UBound() and LBound() to find the upper and lower bounds of the array.
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 75 total points
ID: 33573382
If you want to know if a key exists without error trapping then you can use the Dictionary class instead of the Collection...but this requires a reference to the VBScript Runtime.  =\
0
 
LVL 27

Assisted Solution

by:Ark
Ark earned 125 total points
ID: 33574084
Though it seems to be a newbie question, it's not so trivial - VB6 doesn't recognized UBound for undimmed arrays:

Private Sub Command1_Click()
  Dim abArray() As Long
  MsgBox PureUBound(abArray)
  'MsgBox UBound(abArray) 'subscript out of range error
  ReDim abArray(2)
  MsgBox PureUBound(abArray)
  MsgBox UBound(abArray) 'OK
  'MsgBox UBound(abArray, 2) 'subscript out of range error
End Sub

Option Explicit



Type SAFEARRAYBOUND

    cElements As Long  ' # of elements in the array dimension

    lLbound   As Long  ' lower bounds of the array dimension

End Type



Type SAFEARRAY

    cDims       As Integer          ' // Count of dimensions in this array.

    fFeatures   As Integer          ' // Flags used by the SafeArray

                                    ' // routines documented below.

    cbElements  As Long             ' // Size of an element of the array.

                                    ' // Does not include size of

                                    ' // pointed-to data.

    cLocks      As Long             ' // Number of times the array has been

                                    ' // locked without corresponding unlock.

    pvData      As Long             ' // Pointer to the data.

    rgsabound() As SAFEARRAYBOUND  ' // One bound for each dimension.

End Type

Const VT_BYREF = &H4000&



Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)



Public Function PureUBound(TheArray As Variant, Optional ByVal Rank As Integer = 1) As Integer

   Dim lp As Long, VType As Integer

   If IsNull(TheArray) Then Exit Function 'Throw NULL Exception

   If Not IsArray(TheArray) Then Exit Function 'Throw TypeMismatch Exception

   Dim nDims As Integer

   PureUBound = -1

   CopyMemory VType, ByVal VarPtr(TheArray), 2

   CopyMemory lp, ByVal (VarPtr(TheArray) + 8), 4

   If lp = 0 Then Exit Function

   If (VType And VT_BYREF) <> 0 Then

      CopyMemory lp, ByVal lp, 4

   End If

   If lp = 0 Then Exit Function

   CopyMemory nDims, ByVal lp, 2

   If nDims >= Rank Then

      PureUBound = UBound(TheArray, Rank)

   'Else

      'Throw Rank Exception

   End If

End Function

Open in new window

0
 
LVL 3

Expert Comment

by:deepusreedhar
ID: 33575410
Is this working for you?
Private Sub Form_Load()

    Dim strarray(2) As String

    strarray(0) = "1"

    strarray(1) = "2"

       

    For i = 0 To UBound(strarray) - 1

        MsgBox (strarray(i))

    Next

End Sub

Open in new window

0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:ipjyo
ID: 33579579
Thank you very much everybody for the clarifications. In my case, I have to use arrays for some reason. I can't use Collection object.
It looks like I should always specify the Upper Bound of the array to be able to loop through the array.

I am trying to get the attached code working.
It gives me "Subscript out of range error" when the array strIDs() is empty and does not have any values.
Should I specify the upper bound while declaring the array as follows.

Dim strIDs(50) As String

Thank you.
Dim strIDs() As String

strIDs() = GetIDs  'returns an array of strings and the array can be empty sometimes

bIDExists = IDExists(CurrentID, strIDs())     'returns true if CurrentID exists in strIDs()


Private Function IDExists(strCurrentID As String, _
                                IDs() As String) As Boolean
    Dim i As Integer
    Dim bExists As Boolean
    bExists = False
    
    For i = 0 To UBound(IDs)
        If strCurrentID = IDs(i) Then
            bExists = True
            Exit For
        End If
    Next i
    
    IDExists = bExists

End Function

Open in new window

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 33579598
Ark was demonstrating in his comment back here:
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_26442863.html#33574084

...that his PureUBound() function will work for empty arrays and will return -1 in those cases.
0
 
LVL 29

Assisted Solution

by:nffvrxqgrcfqvvc
nffvrxqgrcfqvvc earned 125 total points
ID: 33580126
You can also use the following for checking if elements exists.

Option Explicit

Private Declare Function SafeArrayGetDim Lib "oleaut32" (ByRef saArray() As Any) As Long



Private Sub Form_Load()

Dim Test1() As String

If SafeArrayGetDim(Test1) Then

  Debug.Print "OK"

Else

  Debug.Print "no dimensions"

End If



'

Dim Test2(0) As String

If SafeArrayGetDim(Test2) Then

  Debug.Print "OK"

Else

  Debug.Print "no dimensions"

End If

End Sub

Open in new window

0
 

Author Comment

by:ipjyo
ID: 33581654
Thanks very much. It is working for me when I tested it in a form.
But when I tried to place this line in my class module, it says

Run-time error '453':
Can't find DLL entry point SafeArrayGetDim in oleaut32

Private Declare Function SafeArrayGetDim Lib "oleaut32" (ByRef saArray() As Any) As Long

I have the function as follows.

Private Function IDExists(strCurrentID As String, _
                                IDs() As String) As Boolean
    Dim i As Integer
    Dim bExists As Boolean
    bExists = False
   
If SafeArrayGetDim(IDs) Then

    For i = 0 To UBound(IDs)
        If strCurrentID = IDs(i) Then
            bExists = True
            Exit For
        End If
    Next i
Else
    bExists = False
End If
   
    IDExists = bExists

End Function
0
 

Author Comment

by:ipjyo
ID: 33581718
Sorry...It was working fine. I tried to change the name of the function SafeArrayGetDim to something else. Then it did not work. But I tried with the same function name "SafeArrayGetDim" and it is working great.

Thanks.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33581749
You can change the name, but you also must specify the Alias member in the decleration if you want to to change the name.

Private Declare Function SafeArrayAnyNameYouWant Lib "oleaut32" Alias "SafeArrayGetDim" (ByRef saArray() As Any) As Long

Open in new window

0
 
LVL 16

Expert Comment

by:HooKooDooKu
ID: 33583342
Ark Said:Though it seems to be a newbie question, it's not so trivial - VB6 doesn't recognized UBound for undimmed arrays:

That's correct... that is why I use the trick of ALWAYS doing a ReDim on any undimmed arrays at the start of the program (or in a class/form Initialize event) with...
  ReDim m_MyArray( -1 to -1 )
..., that way from the moment the application starts, the array actually has been dimmed so that a UBound command won't blow up, but I can test if my logic (post initilization) has ReDimmed the array by testing...
  if UBound( m_MyArray ) = -1 then
...

Sub Class_Initialize
  ReDim m_MyArray( -1 to -1)
End Sub

...that way, if I want to test if the code that REALLY is supposed to ReDim the array has executed or not, I can use UBound, and if the result is -1, then I know the array hasn't LOGICALLY been allocated.
0
 
LVL 4

Expert Comment

by:coolcurrent4u
ID: 33592294
Arrays are zero based by default except you define the lower bound

this is the best ,method if  you don't know the lower bound and upper bound of the array

try this


Private Sub Form_Load()

    Dim strarray() As String

    strarray(0) = "1"

    strarray(1) = "2"

       

    For i = lbound(strarray) To ubound(strarray)

        MsgBox (strarray(i))

    Next

End Sub

Open in new window

0
 
LVL 27

Expert Comment

by:Ark
ID: 33592390
>>Arrays are zero based by default except <b>YOU</b> define the lower bound
this is the best ,method if  <b>YOU</> don't know the lower bound and upper bound of the array<<
:)
0
 

Author Comment

by:ipjyo
ID: 33600366
Thank you very much for the additional clarifications.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Not long ago I saw a question in the VB Script forum that I thought would not take much time. You can read that question (Question ID  (http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_28455246.html)28455246) Here (http…
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…
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…

757 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now