Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    4 Star Lounger
    Join Date
    Feb 2001
    Location
    Gillingham, Kent, England
    Posts
    511
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Parsing arrays (VB6 SR6)

    (at least I thing "Parsing" is the correct term!!!).

    I have a piece of code that deals with a dynamic array. It is possible that the array could have no elements, therefore the subsequent for loop which will deal with the array will error instead of simply jumping out of the loop. Is there a command to parse an array or will I need to handle the error and use a goto statement to jump back to the end of the loop?

  2. #2
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts

    Re: Parsing arrays (VB6 SR6)

    I think you'll have to handle the error. You could test before entering the loop whether UBound(arrayname) can be accessed, and only enter the loop if so.

    Dim n As Long
    On Error Resume Next
    n = UBound(ArrayName)
    If Err = 0 Then
    On Error GoTo ErrHandler
    For n = LBound(ArrayName) To UBound(ArrayName)
    ...
    Next n
    End If

  3. #3
    4 Star Lounger
    Join Date
    Feb 2001
    Location
    Gillingham, Kent, England
    Posts
    511
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    I thought i'd have to do something like that, but as I find jumping in and out of the error handler a messy way to program (difficult to follow when debugging etc), I prefer to run a check if there is one available.

    Thanks for the tip and agreeing with my suspision.

    Regards,
    Phil

  4. #4
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Parsing arrays (VB6 SR6)

    I don't have a Dodge Viper and it would pretty much astound me if I knew anything Hans didn't about arrays (which generally cause my head to pound), so this is probably a worthless post (i.e., I'm probably misunderstanding your question), but here goes:

    I believe you can detect an array that's been declared (so IsArray(avarX) is True) but doesn't have any elements using the IsEmpty function. And I believe it's also possible to have a situation where the array itself isn't empty (so IsEmpty(avarX) is False) but all its elements are empty. But if you first check whether the array is empty (and bail if it is), and then, if the array itself isn't empty, check whether its first element is empty (if that's a possible state of affairs in your procedure), and bail if it is, I think you may be able to proceed with your loop without risk of triggering an error. (Depending on what type of variables your array is made up of, I believe IsNull might be the appropriate test of the array's first element, rather than IsEmpty.)

  5. #5
    3 Star Lounger
    Join Date
    Apr 2004
    Location
    Boston, Massachusetts, USA
    Posts
    389
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    If you want to avoid dealing with error codes, would your code work by just using a variant? You could then test it using either the IsArray or IsEmpty function to determine if it's still empty.

    <pre>Dim v As Variant
    Debug.Print IsEmpty(v) ' true
    Debug.Print IsArray(v) ' false
    ReDim v(0)
    Debug.Print IsEmpty(v) ' false
    Debug.Print IsArray(v) ' true
    End Sub
    </pre>



    HTH

  6. #6
    4 Star Lounger
    Join Date
    Feb 2001
    Location
    Gillingham, Kent, England
    Posts
    511
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    Thanks st3333ve for your reply, I haven't yet found someone with a Viper, let alone someone who will gladly lend me one!

    As for my problem....
    I have got it working using the error handling method but I tried your suggestion out of curiosity.

    I tried it with both string and int arrays and isempty always returned false, however I tried with a Variant not initially declared as an array as per Andrew 77s suggestion and it worked like a treat, so thanks load to both of you for your help.

    I may ask this as a new question altogether, but as its relevant to the solution of this one....

    What are the cons of using variants? I read somewhere that in some cases it wasn't good practice to use variants if another option is available. Is it just that they take up more memory is does it go deeper than that? I remember reading something about variants and .net too but I can't remember what it was.

  7. #7
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    > will I need to handle the error

    I'd strongly recommend against using On Error for this. I see On Error as a lack of foresight, either on the part of the VBA developer, or on the part of MicroSoft.

    In your case you already know what types of events can occur, and your options are not limited to
    (1) testing to see if UBound(array) > LBound(array) - in which case at least one REDIM PRESERVE has been executed
    (2) testing the LBOUND element as a sentinel (in most cases an array, if primed, would have data, and the LBOUND element would be not null and not empty and not nothing)
    (3) falling back on a Boolean switch
    (4) any other methods suggested in previous responses.

    The only reasons I can see for using On Error is where MicroSoft's design forces us to use it to trap events that signal things Microsoft chose not to show.

    A classic example with Arrays is that of determining the rank of an array, that is, how many dimensions the array possesses. Is it 1- 2- 3- or 4-dimensional and so on?

    Without a means (or property) of detecting this, we are forced to write a klutzy loop using varying degrees of dimension until a UBound triggers an error.

    Another example is MicroSoft's failure to provide a suitable IfFileExists text. The most common method I've seen is to use On Error to trap "FileLen(strMyFile) = FileLen(strMyFile) ".


    Again, you already know what constitutes a virgin array, and so it ought to be possible for you to program around it without causing, and then trapping, an error.

    I note with interest that On Error is not available in VB.NET. An introductory Microsoft booklet says that the GoTo method is "considered harmful".

  8. #8
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts

    Re: Parsing arrays (VB6 SR6)

    If you know that a variable will only hold values of a certain type, say long integers, it is more efficient to use a variable of type Long than of type Variant. Because a variant can hold many types of values, there is an overhead for keeping track of what type of data the variable currently contains; this is both in storage/memory use and in processing time. If you add two variables of type Long, VB can pass the calculation to the processor immediately; the CPU is very good at handling long integers. If you add two variables of type Variant, VB must check the current data type of each of the values, then decide what the addition should do (for strings, addition is equivalent to concatenation), etc. So if you need to do a lot of calculations, being specific speeds up your application significantly.

    On the other hand, specific data types such as Long cannot handle null values. Null is different from 0: null indicates a missing value, 0 is a specific number. In Access, for example, fields in a table can contain null values. If you want to assign a field value to a variable, you must either write extra code to handle null values separately, or declare the variable as a variant and assign the value directly.

    In .Net, the Variable data type is not supported. Instead, Object serves as universal data type. In VB6, Object has a specific meaning, in .Net, Object can hold all types of data. See Universal Data Type Changes in Visual Basic.

  9. #9
    Bronze Lounger
    Join Date
    Nov 2001
    Location
    Arlington, Virginia, USA
    Posts
    1,394
    Thanks
    0
    Thanked 3 Times in 3 Posts

    Re: Parsing arrays (VB6 SR6)

    In reference to, determining dimension of an array, this can be done w/o resorting to raising "Subscript out of bounds" error, though the error-raising approach is much simpler. See this previous post & related thread:

    <!post=Re: Turning off Error Trapping in Word (W2002SP-2),378337>Re: Turning off Error Trapping in Word (W2002SP-2)<!/post>

    If using error-raising approach, code is relatively simple:

    <code>Public Function GetDimCountByErr(ByRef Arr As Variant) As Integer</code>
    <code> On Error GoTo ErrHandler</code>

    <code> Dim n As Long</code>
    <code> Dim i As Integer</code>
    <code> Const MAX_DIM As Integer = 60 ' Max dimensions in array</code>
    <code> </code>
    <code> ' Return value of 0 indicates variable has not been dimensioned</code>

    <code> If VarType(Arr) > vbArray Then</code>
    <code> For i = 1 To MAX_DIM</code>
    <code> n = LBound(Arr, i)</code>
    <code> Next i</code>
    <code> Else</code>
    <code> GetDimCountByErr = 0</code>
    <code> End If</code>
    <code> </code>
    <code>PROC_EXIT:</code>
    <code> Exit Function</code>
    <code>ErrHandler:</code>
    <code> Dim strMsg As String</code>
    <code> Select Case Err.Number</code>
    <code> Case 9 ' Subscript out of range</code>
    <code> GetDimCountByErr = i - 1</code>
    <code> Resume PROC_EXIT</code>
    <code> Case 13 ' Type mismatch (Arr arg not array)</code>
    <code> GetDimCountByErr = 0</code>
    <code> Resume PROC_EXIT</code>
    <code> Case Else</code>
    <code> strMsg = "Error " & Err.Number & ":" & Err.Description</code>
    <code> MsgBox strMsg, vbExclamation, "Error Message"</code>
    <code> GetDimCountByErr = 0</code>
    <code> Resume PROC_EXIT</code>
    <code> End Select</code>
    <code>End Function</code>

    Test sub:

    <code>Sub TestGetDimCountByErr()</code>

    <code> Dim A(10) As Integer</code>
    <code> Dim B(1, 1) As Long</code>
    <code> Dim C(2, 2, 2) As String</code>
    <code> Dim D(1, 1, 1, 1) As Variant</code>
    <code> Dim E As Variant</code>
    <code> </code>
    <code> Debug.Print "A: " & GetDimCountByErr(A) & " dimensions"</code>
    <code> Debug.Print "B: " & GetDimCountByErr([img]/forums/images/smilies/cool.gif[/img] & " dimensions"</code>
    <code> Debug.Print "C: " & GetDimCountByErrİ & " dimensions"</code>
    <code> Debug.Print "D: " & GetDimCountByErr(D) & " dimensions"</code>
    <code> Debug.Print "E: " & GetDimCountByErr(E) & " dimensions"</code>
    <code> </code>
    <code>End Sub</code>

    The GetDimCountByErr function returns zero if variable passed to function is not an array, or has not been dimensioned. If using Variants, another method to determine if the variable has been dimensioned is to use the VB VarType function to return the subtype of a variable. If the value returned is less than vbArray (8192), the variable is not an array. If the variable has been dimensioned, then varType will return the sum of vbArray and the specific data subtype (vbInteger, vbString, etc). For example:

    Dim v() As String
    Debug.Print VarType(v)

    will print 8200, the sum of vbArray (8192) and vbString (8).

    HTH

  10. #10
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Parsing arrays (VB6 SR6)

    Assuming, however, that Phil wanted to declare his dynamic array as a string array (Dim arrayX() As String), is there any way to test whether it's received any values or is still in its initial state without using some kind of error-trigger routine?

    After it's initially declared using "Dim arrayX() As String", IsArray(arrayX) is True, IsEmpty(arrayX) is False, but any attempt to refer to any of the array's elements -- e.g., arrayX(0) or arrayX(1) or arrayX(LBound(arrayX)) -- seems to inevitably generate the "subscript out of range" error.

  11. #11
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    caveta: I can type Caveat properly when I want to (grin!)

    Further thoughts:

    There's a difference between utility functions used internaly and those used externaly. Here's a trivial example: If I'm writing a function to accumulate an array of words, I'm in control of the calling sequence (it's me writing the code that calls the utility function), and I am well-behaved. If I were writing a utility function to be used by all and sundry, then, perhaps, I'd be instituting various IsArray and IsEmpty functions as suggested in this thread.

    Same reasoning as checking data : we check data as it crosses our application boundary, but not while it is within the application.

    If I am writing a fucntion which calls an array-handling fucntion, then I'm expected to have control over just what may or may not be in the array. For the life of me (not worth much!) I can't dream up a case where, as the programmer, I wouldn't know what was being passed. I'm the PROGRAMMER fer heaven's sakes.


    Now, If I were writing a general-purpose function to build (or use) an array, and couldn't/didn't trust the world, I'd possibly check that the unknown caller had passed me the correct parameters.

    I'm tempted to ask for a clear example of why we, as programmers, need to test IsArray etc for any case OTHER THAN writing a function to be used by the Great Unwashed Public. I'm pretty sure that Microsoft isn't doing those sorts of checks, judging by the myraid ways one can crash their code.

  12. #12
    5 Star Lounger st3333ve's Avatar
    Join Date
    May 2003
    Location
    Los Angeles, California, USA
    Posts
    705
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Re: Parsing arrays (VB6 SR6)

    Your code samples declare the array as an array of variants. They may end up containing string values, but they're technically arrays of variants. I was wondering if there was a way to avoid an error-trigger routine if the array is declared as a string array.

    When I'm writing a procedure for my own use (not the use of the Great Unwashed Public you refer to) but it's one I expect I may be using many times, in many circumstances, and I don't want to ever have to think about whatever functionality it encapsulates again, I'm often inclined to put quite a bit of error-checking at the start of it, so it aborts gracefully if it's ever called in a circumstance where running its code would be nonsensical or worse.

  13. #13
    3 Star Lounger
    Join Date
    Apr 2004
    Location
    Boston, Massachusetts, USA
    Posts
    389
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    You can avoid the error and use a string by immediately ReDim-ing to 0:

    <pre>Dim str() as String
    Redim str(0)
    Debug.Print VarType(str) ' -> 8200, aka string array
    Debug.Print UBound(0) ' 0
    </pre>


    If your code permits you to do it this way, you'll have what you're looking for. BUT there will be no way to tell whether the array is as it was initially, or if a null string has been placed in its first element (which is what the Redim line is doing). If you know that all your array elements will be actual (non-zero length) strings, this technique may work for you.

  14. #14
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    caveta: I typed the code samples by hand; they are untested

    > is there any way to test

    I'm going to respond "yes" to this, on the broad grounds that I make frequent and varied use of dynamic string arrays and have not yet used On Error (excepting to test rank as an academic exercise).

    My applications accumulate arrays of file names (from the nested DIR commands and FileObject), arrays of paragraphs, of Interesting Words, of Unique Interesting Words, of Wallpaper bit maps - you name it, the only time I fail in arrays is when I ask for a raise (grin!).

    Generally I define the array:
    <pre>Dim strAr() AS STRING
    Redim strAr(0)</pre>

    in the code and
    <pre>Redim Preserve strAr(Ubound(strAr)+1)</pre>

    within the loop and
    <pre>Redim Preserve strAr(Ubound(strAr)-1)</pre>

    after the loop is complete.

    If the array accumulation is used locally within that procedure, my test following the loop will be along the lines of:
    <pre>If Ubound(strAr) > 0 Then ' we found some entries
    ''' use them
    Else ' We found no entries
    ''' do nothing
    EndIf</pre>


    If the array is to be used in the calling code, then my procedure is, as always, a Function (Post 342195 in This thread) which returns a result. Since I'm building an array, the Function result can be a Boolean (True==> found some data) or a Long (==> count of items found, 0==> none found).

    Here's the traditional bottom line: If, as a programmer, I know that there may be no valid data loaded into the array, I ought to program that condition myself, and not rely on an "On Error" event..

  15. #15
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Parsing arrays (VB6 SR6)

    > Your code samples declare the array as an array of variants

    oops! That's because I was keying in the code off the top of my head. I have edited in the AS STRING. I very rarely, if at all, use variants. Most generally when I've pasted code from a help screen or SDK package.


    Regarding the need to perform thinking, I'm writing functions to perform specific tasks on specific data items, and so the Intellisense prompts me for the approriate type. Most commonly I'm writing a function that processes string data and returns a string, or processes numeric data and returns a numeric value. Probably 95% of my utility functions are string-string or long-long. The remaining 5% are most likely returning a Boolean or a Long after operating on string arguments.


    Would you care to post a short example of one of your catch-all-problem functions? We could agree to restrict ongoing commentary to the employment of On Error (grin!)

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •