Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to check for empty arrays. Google gave me varied solutions but nothing worked. Maybe I am not applying them correctly.

Function GetBoiler(ByVal sFile As String) As String
'Email Signature
    Dim fso As Object
    Dim ts As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
    GetBoiler = ts.ReadAll
    ts.Close
End Function

Dim FileNamesList As Variant, i As Integer
' activate the desired startfolder for the filesearch
FileNamesList = CreateFileList("*.*", False) ' Returns File names
' performs the filesearch, includes any subfolders
' present the result
' If there are Signatures then populate SigString
Range("A:A").ClearContents
For i = 1 To UBound(FileNamesList)
    Cells(i + 1, 1).Formula = FileNamesList(i)
Next i

SigString = FileNamesList(3)

If Dir(SigString) <> "" Then
    Signature = GetBoiler(SigString)
Else
    Signature = ""
End If

Here if FileNamesList array is empty, GetBoiler(SigString) should not get called at all. When FileNamesList array is empty, SigString is also empty and this calls GetBoiler() function with empty string. I get an error at line

Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)

since sFile is empty. Any way to avoid that.

share|improve this question
1  
Check out modArraySupport, a useful set of procedures by Chip Pearson to support handling arrays. IsArrayEmpty does what you want. – Jean-François Corbett Jul 14 '11 at 11:01
2  
0% accept rate - please mark one of these excellent responses as accepted ! – iDevlop Feb 29 '12 at 11:31
@iDevlop OP hasn't been seen in over three years, doubt this will ever be marked as resolved. Just upvote the answer(s) you like best. – JimmyPena Jun 21 '12 at 1:16

9 Answers

As you are dealing with a string array, have you considered Join?

If Len(Join(FileNamesList)) > 0 Then
share|improve this answer
This is elegant and works with an empty array. – iDevlop Feb 15 '10 at 13:45
2  
yeah it's short. but it potentially does a lot of unnecessary work. – peter Nov 27 '11 at 9:51

If you test on an array function it'll work for all bounds:

Function IsVarArrayEmpty(anArray As Variant)

Dim i As Integer

On Error Resume Next
    i = UBound(anArray,1)
If Err.number = 0 Then
    IsVarArrayEmpty = False
Else
    IsVarArrayEmpty = True
End If

End Function
share|improve this answer

This code doesn't do what you expect:

If Dir(SigString) <> "" Then
    Signature = GetBoiler(SigString) 
Else
    Signature = "" 
End If

If you pass an empty string ("") or vbNullString to Dir, it will return the name of the first file in the current directory path (the path returned by CurDir$). So, if SigString is empty, your If condition will evaluate to True because Dir will return a non-empty string (the name of the first file in the current directory), and GetBoiler will be called. And if SigString is empty, the call to fso.GetFile will fail.

You should either change your condition to check that SigString isn't empty, or use the FileSystemObject.FileExists method instead of Dir for checking if the file exists. Dir is tricky to use precisely because it does things you might not expect it to do. Personally, I would use Scripting.FileSystemObject over Dir because there's no funny business (FileExists returns True if the file exists, and, well, False if it doesn't). What's more, FileExists expresses the intent of your code much clearly than Dir.

Method 1: Check that SigString is non-empty first

If SigString <> "" And Dir(SigString) <> "" Then
    Signature = GetBoiler(SigString) 
Else
    Signature = "" 
End If

Method 2: Use the FileSystemObject.FileExists method

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

If fso.FileExists(SigString) Then
    Signature = GetBoiler(SigString) 
Else
    Signature = "" 
End If
share|improve this answer

When writing VBA there is this sentence in my head: "Could be so easy, but..."

Here is what I adopted it to:

Private Function IsArrayEmpty(arr As Variant)
  ' This function returns true if array is empty
  Dim l As Long

  On Error Resume Next
  l = Len(Join(arr))
  If l = 0 Then
    IsArrayEmpty = True
  Else
    IsArrayEmpty = False
  End If

  If Err.Number > 0 Then
      IsArrayEmpty = True
  End If

  On Error GoTo 0
End Function

Private Sub IsArrayEmptyTest()
  Dim a As Variant
  a = Array()
  Debug.Print "Array is Empty is " & IsArrayEmpty(a)
  If IsArrayEmpty(a) = False Then
    Debug.Print "  " & Join(a)
  End If
End Sub
share|improve this answer

I'll generalize the problem and the Question as intended. Test assingment on the array, and catch the eventual error

Function IsVarArrayEmpty(anArray as Variant)
Dim aVar as Variant

IsVarArrayEmpty=False
On error resume next
aVar=anArray(1)
If Err.number then '...still, it might not start at this index
    aVar=anArray(0)
    If Err.number then IsVarArrayEmpty=True ' neither 0 or 1 yields good assignment
EndIF
End Function

Sure it misses arrays with all negative indexes or all > 1... is that likely? in weirdland, yes.

share|improve this answer
3  
If it doesn't work in weirdland, then it isn't "generalized". – Jean-François Corbett Jul 14 '11 at 10:56

Go with a triple negative:

If Not Not FileNamesList <> 0 Then
    ' Array has been initialized, so you're good to go.
Else
    ' Array has NOT been initialized
End If

Maybe it's just me, but I've never liked doing an operation and then seeing if it generated an error. There has to be a better way! ... like this one-liner.

share|improve this answer

Another solution to test for empty array

if UBound(ar) < LBound(ar) then msgbox "Your array is empty!"

Or, if you already know that LBound is 0

if -1 = UBound(ar) then msgbox "Your array is empty!"

This may be faster than join(). (And I didn't check with negative indexes)

Here is my sample to filter 2 string arrays so they do not share same strings.

' Filtering ar2 out of strings that exists in ar1

For i = 0 To UBound(ar1)

    ' filter out any ar2.string that exists in ar1
    ar2 = Filter(ar2 , ar1(i), False)    

    If UBound(ar2) < LBound(ar2) Then
       MsgBox "All strings are the same.", vbExclamation, "Operation ignored":
       Exit Sub

    End If

Next

' At this point, we know that ar2 is not empty and it is filtered 
'
share|improve this answer
UBound will fail if the array is empty, it won't return -1 or one-less-than-lbound – PhilHibbs Oct 17 '12 at 9:34
Public Function arrayIsEmpty(arrayToCheck() As Variant) As Boolean
    On Error GoTo Err:
    Dim forCheck
    forCheck = arrayToCheck(0)
    arrayIsEmpty = False
    Exit Function
Err:
    arrayIsEmpty = True
End Function
share|improve this answer

Personally, I think one of the answers above can be modified to check if the array has contents:

if UBound(ar) > LBound(ar) Then

This handles negative number references and takes less time than some of the other options.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.