• Arrays / IsEmpty (XP/O2003/Word)

    Author
    Topic
    #417941

    Hi,

    Here’s a quick one, but I can’t locate an answer, so apologies if this one seems stupid.

    What’s the easiest way to check whether an array contains data or not…?
    Initially I tried with “IsEmpty” as it applies to variants but VBE still complains…
    Thought also about checking Ubound, but seems somehow odd…

    Code snippet:
    …..
    If strCompanyID = “” Then DocProp_Get (“cdpCompanyID1”)
    If IsEmpty(arrCompanyDetails) Then
    arrCompanyDetails = GetCompanyDetails(strCompanyID, iLANGID1)
    End if
    ……

    Ooops – forgot to mention that arrCompanyDetails is a custom defined type that gets filled when GetCompanyDetails are called
    (part of it’s Type definition below)

    Type BasicInfo ‘arrCompanyDetails get filled with these types
    Company_ID As String
    Company_Name As String
    Country_Name As String
    Sector_Name As String
    Currency_Basis As String
    Currency_Invoice As String
    ……
    End type

    Better suggestions?

    ThX

    Viewing 3 reply threads
    Author
    Replies
    • #939103

      You could loop through the elements of the array and test if they’re all empty.

    • #939142

      An array can’t really be Empty. That is, if IsArray(arrCompanyDetails) is True, IsEmpty(arrCompanyDetails) will necessarily be False.

      If you initially declare arrCompanyDetails without parentheses, like this:

      Dim arrCompanyDetails As Variant

      then arrCompanyDetails will (at that point) be a simple Variant (not yet an array), and Variants initialize to Empty, so IsEmpty will be True and IsArray will be False.

      If, on the other hand, you initially declare arrCompanyDetails with parentheses, like this:

      Dim arrCompanyDetails() As BasicInfo

      then arrCompanyDetails will (at that point) be an undimensioned array, so IsArray will be True and (perhaps unfortunately for you) IsEmpty will be False (even though the array will certainly be “empty” for most purposes).

      Testing whether something is an undimensioned array is a little tricky. The best way I know is to use a function that triggers an error and detects that error. Here’s a sample:

      Function IsUndimensionedArray(aTarget As Variant) As Boolean
      
          Dim x As Long
      
          If IsArray(aTarget) = True Then
              On Error Resume Next
              x = LBound(aTarget)
              If Err = 9 Then
                  IsUndimensionedArray = True
              End If
          End If
      
      End Function

      Finally, though, if you dimension your array when you first declare it (or, using ReDim, at any time before you test it for “emptiness”), then you can use Hans’s approach of looping through the elements and seeing if any of them is non-empty.

    • #939187

      I don’t know whether this applies in Word 2003 VBA, but in VB.Net, you can check the Length property of an array to determine how many items it contains.

      • #939226

        (How quickly she forgets…)

        A spokesperson for the poor VB6 arrays has asked me to remind you that none of them have any property at all.

    • #939225

      Your question reminded me of a similar thread from last year, post 389340.

      Extrapolating on that posting …

      Sub SeeIfArrayIsEmpty()
      Dim arr() As String
      '
      ' Is this array empty? Find out:
      MsgBox Not CBool(Len(Join(arr)))  ' --> True
      '
      ReDim arr(1)
      arr(1) = vbNullString
      ' Now is the array empty?
      MsgBox Not CBool(Len(Join(arr))) ' --> False
      '
      ' And finally ...
      arr(1) = "foo"
      MsgBox Not CBool(Len(Join(arr))) ' --> False
      End Sub
      
      ' A more useful generic test function would be:
      Function IsArrayEmpty(vArr As Variant) As Boolean
      IsArrayEmpty = Not CBool(Len(Join(vArr)))
      End Function
      

      HTH,

      • #939232

        Shoot, I was a (somewhat hapless) participant in that thread you pointed to, and I somehow missed the import of that post with the Join trick. Good stuff.

        I note, however, (1) that it doesn’t work (an error is triggered) if the subject of the test is an empty variant (so it may make sense, in some situations, to precede it with an IsArray test), and (2) that, as your post showed, it will return False as long as the array has any elements, even if all of those elements are themselves empty (so you’d follow it with Hans’s loop through the elements if that was appropriate).

        • #939235

          In VBA an array with an element is NOT empty, it simply contains an empty element. shrug

      • #939237

        FOLLOW-UP DISCOVERY: If you specify an empty string as the delimiter of the Join function — i.e., CBool(Len(Join(arr, vbNullString))) — your function seems to do a pretty good job of returning True not only if the array is undimensioned, but also if it’s dimensioned but all its elements are empty.

        • #939240

          That makes sense. The default delimiter of Join is a space, which is why even if it’s run on an empty array, its result has a non-zero length.

      • #939238

        FOLLOW-UP FLY IN OINTMENT: If you try to use the Join function on an array of user-defined types, like Henrik’s, VB complains that only udt’s in public object modules can be coerced blah blah or passed blah blah.

        • #939242

          That’s true, but you can’t use IsArray() or IsEmpty() on an array of UDTs either.

          I’ve never had much use for UDTs, though I’m sure they have their place. I’d opt for a class or a collection in this case, though I’m not sure if that’d suit Henrik’s needs.

          Function NewCompanyDetails( _
                                     Company_ID As String, _
                                     Company_Name As String, _
                                     Country_Name As String, _
                                     Sector_Name As String, _
                                     Currency_Basis As String, _
                                     Currency_Invoice As String) _
                                       As Collection
          Dim col As Collection
          Set col = New Collection
          col.Add Key:="Company_ID", Item:=Company_ID
          col.Add Key:="Company_Name", Item:=Company_Name
          col.Add Key:="Country_Name", Item:=Country_Name
          col.Add Key:="Sector_Name", Item:=Sector_Name
          col.Add Key:="Currency_Basis", Item:=Currency_Basis
          col.Add Key:="Currency_Invoice", Item:=Currency_Invoice
          Set NewCompanyDetails = col
          End Function
          '
          Sub UseCollection()
          Dim colAllCompanyDetails As Collection
          Dim k As Long
          Set colAllCompanyDetails = New Collection
          
          ' see if collection is empty:
          MsgBox Not CBool(colAllCompanyDetails.count)
          
          
          colAllCompanyDetails.Add _
              Item:=NewCompanyDetails( _
                  Company_ID:="12345", _
                  Company_Name:="widgets, inc", _
                  Country_Name:="US", _
                  Sector_Name:="Northeast", _
                  Currency_Basis:="Dollar", _
                  Currency_Invoice:="no idea what this is")
          
          colAllCompanyDetails.Add _
              Item:=NewCompanyDetails( _
                  Company_ID:="99999", _
                  Company_Name:="Foobar, Inc", _
                  Country_Name:="Canada", _
                  Sector_Name:="West", _
                  Currency_Basis:="Dollar", _
                  Currency_Invoice:="no idea what this is")
          
          ' Now is it empty?:
          MsgBox Not CBool(colAllCompanyDetails.count)
          
          ' Also can iterate easily:
          For k = 1 To colAllCompanyDetails.count
              MsgBox "Company Name is: " + colAllCompanyDetails(k)("Company_Name")
          Next k
          End Sub
          
          • #939244

            [indent]


            That’s true, but you can’t use IsArray() or IsEmpty() on an array of UDTs either.


            [/indent]Ouch. Right you are. (UDTs are gotcha-heaven, aren’t they?) It occurs to me (finally) that the UDTs may have been what triggered the error that prompted Henrik to post in the first place — which would mean your last post was the answer to the question he didn’t know he was asking.

            Whatever happened to Henrik, anyway? grin

            • #939501

              Hiyah, still following this thread, that has become unexpectedly interesting (grin)
              I can see that Andrew also came across the error message of UDT’s blah blah blah – that was the one that triggered my initial Q

              Lots of thanks for all your inputs – and yeah I agree a new collection seems to be the best way around this.
              …I was only hoping that I could avoid it as it implies a lot of code rewriting – but I guess that’s the name of the game…

            • #939714

              In terms of the amount of code-rewriting: I note that Andrew’s approach uses a collection at both levels (so you end up with a collection of collections, in place of an array of UDT’s). A halfway approach (that would retain more of your existing code) would be to move to an array of collections. Unlike an array of UDT’s you can use IsArray, IsEmpty and similar functions on a array of collections — although you can’t use the Len() trick to test for an undimensioned array of collections, since it will return 0 if it’s undimensioned but trigger an error if it’s dimensioned (but you could use the error-harnessing method in my previous post if that type of non-Empty “emptiness” is a possibility you need to test for).

    Viewing 3 reply threads
    Reply To: Arrays / IsEmpty (XP/O2003/Word)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: