14

I have to do some ASP work and I found out that the language doesn't provide a way to detect zero-length arrays (well, I suppose you can detect the exception they throw when you try to use them...). Why would Split() return an empty array if there isn't any sane way to handle it? Or am I missing something?

I concocted the following hack to detect empty arrays, but there has to be an easier way. Which is it? TIA

function ArrayEmpty (a)
    dim i, res
    res = true
    for each i in a
        res = false
        exit for
    next
    ArrayEmpty = res
end function
bluish
  • 26,356
  • 27
  • 122
  • 180
angus
  • 2,305
  • 1
  • 15
  • 22
  • 1
    Maybe you should be checking your input before passing it to Split() – Tester101 Jan 21 '10 at 15:07
  • VBScript and VBA are quite similar, so see http://stackoverflow.com/questions/206324/how-to-check-for-empty-array-in-vba-macro/206526#206526 – Fionnuala Oct 24 '11 at 08:06

5 Answers5

8

For:

Dim arr1 : arr1 = Array()
Dim arr2
Dim arr3 : ReDim arr3(1) : Erase arr3
WScript.Echo UBound(arr1)
WScript.Echo UBound(arr2)
WScript.Echo UBound(arr3)

Will return -1 for arr1, but "VBScript runtime error: Subscript out of range: 'UBound'" for arr2 and arr3.

A general purpose function to test if an array is "Dimmed" or "Empty" should also (probably) test if the variable is actually an array.

Function IsDimmedArray(arrParam)

Dim lintUBound : lintUBound = 0
Dim llngError  : llngError = 0

    IsDimmedArray = False
    If Not IsArray(arrParam) Then : Exit Function

 '' Test the bounds
    On Error Resume Next

        lintUBound = UBound(arrParam)
        llngError = Err.Number
        If (llngError <> 0) Then : Err.Clear

    On Error Goto 0
    If (llngError = 0) And (lintUBound >= 0) Then : IsDimmedArray = True

End Function                  ' IsDimmedArray(arrParam)

For me, 99% of the time when I am checking if an array is "Dimensioned", is if I need to get the UBound of the array and I want to prevent a runtime-error in the cases where the array is not dimensioned. So I will usually pass the UBound as a parameter like:

Function IsDimmedArray(arrParam, intUBoundParam)
    intUBoundParam = 0
    ...

I don't know if this practice actually saves any "Time", but it does save 1 line of code with nearly every use, and is an easy way to enforce the practice of error checking.

Also, I include it for completeness, but in practice, the checking of "UBound >= 0" in IsDimmedArray:

    If (llngError = 0) And (lintUBound >= 0) Then : IsDimmedArray = True

is typically not necessary because usually it will be used in cases like:

Dim arrX
Dim lintUBound
Dim intNdx

arrX = Array()
lintUBound = UBound(arrX)
WScript.Echo "arrX is an array with UBound=" & lintUBound

For intNdx = 0 to lintUBound
    WScript.Echo "This will not print: " & intNdx
Next

So, in this case, lintUBound = -1 and the For ... Next will be skipped.

Amessihel
  • 5,891
  • 3
  • 16
  • 40
Kevin Fegan
  • 1,292
  • 1
  • 16
  • 29
6

An empty array created using the Array function or returned by other intrinsic VBScript functions, such as Split, has an upper bound of -1. So you can test for an empty array like this:

Dim arr : arr = Array()

If UBound(arr) >= 0 Then
  ' arr is non-empty
Else
  ' arr is empty
End If

More info here: Testing for Empty Arrays.

Helen
  • 87,344
  • 17
  • 243
  • 314
  • 5
    Your code is incorrect because UBound fails on empty arrays. The page you linked confirms my suspicion that the only way is by detecting that an exception is thrown (or by my "for each" hack). That's sad :-/ – angus Jan 21 '10 at 09:38
  • 2
    @angus: he is correct because his code looks like "dim results : results = Array()" – Totonga May 25 '12 at 13:36
  • 2
    Helen's answer has the key in the first line--"using the Array function . . . ". What's missing from the answer is an explanation of what you're doing wrong. It's what @Totonga noted: if you declare your array like this "Dim someArray()", they UBound will return undefined. If you declare it like so "Dim someArray : Array()", then UBound will return -1. – Ickster Dec 02 '14 at 15:41
  • 1
    Whoops. The declaration should be "Dim someArray : someArray = Array()" – Ickster Dec 02 '14 at 15:48
2

If your method should be able to return an empty array your code has to be like this

Option Explicit

dim result : result = mymethod
if(NOT ubound(result) > 0) then MsgBox "Array Is Empty"
dim elem : for each elem in result
  MsgBox "Element"
Next

Function mymethod
  dim results : results = Array()
  mymethod = results
End Function

The Array() creates an Ubound = -1 array that has no loop in the for each loop.

Totonga
  • 4,236
  • 2
  • 25
  • 31
1

I think this ist a good way to check a Array in VBS

Dim myArray
myArray = Array()
sTest = IsArrayEmpty(myArray)
Msgbox (sTest) ' True
Function IsArrayEmpty(myArray)
    iRet = True

    If IsArray(myArray) Then
        i = 0
        For Each e In myArray
            If Not IsEmpty(e) And Len(e)>0 Then
                i = i +1
            End If
        Next
        If i>0 Then
            iRet = False
        End If
    End If
    wIsArrayEmpty = iRet
End Function
schorschi
  • 11
  • 1
0

I found a thread on TechNet that suggested using VarType to check for an Array:

Function ArrayEmpty (a)
    If VarType(a) < 8192 Then ArrayEmpty=True Else ArrayEmpty=False
End Function

It worked for me.

Rob
  • 1