?
Solved

How to find the length of an array in VB6?

Posted on 2010-08-31
20
Medium Priority
?
1,575 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
[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
  • 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 100 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 300 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 600 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 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 300 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 28

Assisted Solution

by:Ark
Ark earned 500 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:Deepu Sreedhar
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
 

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 86

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 500 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 28

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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering 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

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
With User Account Control (UAC) enabled in Windows 7, one needs to open an elevated Command Prompt in order to run scripts under administrative privileges. Although the elevated Command Prompt accomplishes the task, the question How to run as script…
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 Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Suggested Courses
Course of the Month9 days, 19 hours left to enroll

762 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