Results 1 to 21 of 21

Thread: VB6 ListView.FIndItem gets Run-time error '13'

  1. #1

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    VB6 ListView.FIndItem gets Run-time error '13'

    I've been pulling my hair out over this one, any help is greatly appreciated.

    I'm loading a VB6 ListView with up to 70K of items and populating the Key property of each item with the Add method. View=lvwReport.

    My interpretation of the docs is that I can provide either an index or a key in the "index" parameter of FindItem. If the data type of the "index" parameter is String, then FindItem will use the value as a Key. If integer, then Index. If no key or index is supplied, FindItem will start at the beginning of the list each time, which would be much slower than using a key.

    As long as I specify an integer for "index", FindItem work fine. When I specify a string key value, it gets run-time error 13 type mismatch. It's as though FindItem doesn't recognize that I'm supplying a string key, not an integer index.


    Dim LI As ListItem
    Dim W$

    ' Syntax: object.Add(index, key, text, icon, smallIcon)
    Set LI = ListView1.ListItems.Add(, "K111", "111")
    Set LI = ListView1.ListItems.Add(, "K222", "222")
    Set LI = ListView1.ListItems.Add(, "K333", "333")
    W$ = ListView1.ListItems(2).Key ' Just checkin', Returns "K222"


    * Syntax: object.FindItem (string, value, index, match)

    * string Required. A string expression indicating the ListItem object to be found.

    * value Optional. An integer or constant specifying whether the string will be matched to
    the ListItem object's Text, Subitems, or Tag property, as described in Settings.

    * index Optional. An integer or string that uniquely identifies a member of an object
    collection and specifies the location from which to begin the search. The integer
    is the value of the Index property; the string is the value of the Key property.
    If no index is specified, the default is 1.

    * match Optional. An integer or constant specifying that a match will occur if the item's
    Text property is the same as the string, as described in Settings.


    ' "index" is an integer (Start search at item #1).
    Set LI = ListView1.FindItem("222", lvwText, 1) ' Returns "222"

    ' "index" is an integer (Start search at item #2).
    Set LI = ListView1.FindItem("222", lvwText, 2) ' Returns "222"

    ' "index" is an integer (Start search at item #3).
    Set LI = ListView1.FindItem("222", lvwText, 3) ' Returns nothing

    ' "index" is a string (Start search with item whose key = "K222"
    ' Gets a Run-time error '13', type mismatch
    Set LI = ListView1.FindItem("222", lvwText, "K222") ' Run-time error 13

  2. #2
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    5,871

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    You can not search for the key, because if you know the key then you can just retrieve the ListItem based on the key.

    * value An integer or constant specifying whether the string will be matched to
    the ListItem object's Text, Subitems, or Tag property, as described in Settings.

    The index is used to specify where in the list of items you want to start your search.
    If you have for example a list of names, then you can find in a loop all items which match the search string.

    * index An integer or string that uniquely identifies a member of an object
    collection and specifies the location from which to begin the search. The integer
    is the value of the Index property; the string is the value of the Key property.
    If no index is specified, the default is 1.

    Code:
    Option Explicit
    
    Private Sub Command1_Click()
      Dim LI As ListItem
      
      Set LI = ListView1.FindItem("Line 3", lvwText)
      
      MsgBox LI.Key
    End Sub
    
    Private Sub Command2_Click()
      Dim LI As ListItem
      
      Set LI = ListView1.ListItems("Key4")
      
      MsgBox LI.Text
      
    End Sub
    
    Private Sub Form_Load()
      With ListView1
        .ListItems.Clear
        .View = lvwList
        .ListItems.Add , "Key1", "Line 1"
        .ListItems.Add , "Key2", "Line 2"
        .ListItems.Add , "Key3", "Line 3"
        .ListItems.Add , "Key4", "Line 4"
        .ListItems.Add , "Key5", "Line 5"
        .ListItems.Add , "Key6", "Line 6"
      End With
    End Sub

  3. #3

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Arnoutdv, thanks for quick response, and the great coding example for FindItem.

    The problem with your example is performance. The FindItem,as coded in your example will begin a serial search of the entire collection beginning with the first item in the collection. Every time it is executed.

    The index parameter of FindItem gives us the option of starting somewhere other than at the beginning. If it worked. I believe there is a bug that prevents it from working as documented.

    And yes, I could use:

  4. #4

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Darn, wasn't ready to post.

    Anyway, I could use:
    Set LI = ListView1.ListItems("K222")

    But FindItem should work as documented but apparently doesn't.

  5. #5
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    5,871

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    It works for me (Windows Common Controls 6.0)
    Code:
    Option Explicit
    
    Private m_lLastFound As Long
    
    Private Sub Form_Load()
      With ListView1
        .ListItems.Clear
        .View = lvwList
        .ListItems.Add , "key:1", "Item 1"
        .ListItems.Add , "key:2", "Line 2"
        .ListItems.Add , "key:3", "Row 3"
        .ListItems.Add , "key:4", "Item 4"
        .ListItems.Add , "key:5", "Line 5"
        .ListItems.Add , "key:6", "Row 6"
        .ListItems.Add , "key:7", "Item 7"
        .ListItems.Add , "key:8", "Line 8"
        .ListItems.Add , "key:9", "Row 9"
      End With
    End Sub
    
    Private Sub cmdFind_Click()
      Dim LI As ListItem
      
      Set LI = ListView1.FindItem(txtSearch.Text, lvwText, , lvwPartial)
      If LI Is Nothing Then
        m_lLastFound = -1
      Else
        m_lLastFound = LI.Index + 1
        MsgBox LI.Key & vbCrLf & LI.Text
      End If
      
    End Sub
    
    Private Sub cmdNext_Click()
      Dim LI As ListItem
      
      If m_lLastFound = -1 Then
        Set LI = ListView1.FindItem(txtSearch.Text, lvwText, , lvwPartial)
      Else
        Set LI = ListView1.FindItem(txtSearch.Text, lvwText, m_lLastFound, lvwPartial)
      End If
      If LI Is Nothing Then
        m_lLastFound = -1
      Else
        m_lLastFound = LI.Index + 1
        MsgBox LI.Key & vbCrLf & LI.Text
      End If
    End Sub

  6. #6
    Fanatic Member
    Join Date
    Jan 2013
    Posts
    759

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    I'm loading a VB6 ListView with up to 70K of items
    Aaaargh!! Why??

    What are you expecting the Poor Soul sat in front of this "monster" to do with 70,000 items in a list?

    Whilst I'm sure you'll get some good responses around here, I think they will all be what I call "Technical Solutions in Search of a Problem". I would strongly suggest you reconsider your User Interface design and make better use of your data[base] assets (i.e don't read all the data "up front"). A user will happily accept a half second delay here and there while the program gets a "bit more" data for them; make them wait a full minute just to load the first list and they'll complain like anything!

    Regards, Phill W.

  7. #7

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Quote Originally Posted by Arnoutdv View Post
    It works for me (Windows Common Controls 6.0)
    Code:
    Option Explicit
    
    Private m_lLastFound As Long
    
    Private Sub Form_Load()
      With ListView1
        .ListItems.Clear
        .View = lvwList
        .ListItems.Add , "key:1", "Item 1"
        .ListItems.Add , "key:2", "Line 2"
        .ListItems.Add , "key:3", "Row 3"
        .ListItems.Add , "key:4", "Item 4"
        .ListItems.Add , "key:5", "Line 5"
        .ListItems.Add , "key:6", "Row 6"
        .ListItems.Add , "key:7", "Item 7"
        .ListItems.Add , "key:8", "Line 8"
        .ListItems.Add , "key:9", "Row 9"
      End With
    End Sub
    
    Private Sub cmdFind_Click()
      Dim LI As ListItem
      
      Set LI = ListView1.FindItem(txtSearch.Text, lvwText, , lvwPartial)
      If LI Is Nothing Then
        m_lLastFound = -1
      Else
        m_lLastFound = LI.Index + 1
        MsgBox LI.Key & vbCrLf & LI.Text
      End If
      
    End Sub
    
    Private Sub cmdNext_Click()
      Dim LI As ListItem
      
      If m_lLastFound = -1 Then
        Set LI = ListView1.FindItem(txtSearch.Text, lvwText, , lvwPartial)
      Else
        Set LI = ListView1.FindItem(txtSearch.Text, lvwText, m_lLastFound, lvwPartial)
      End If
      If LI Is Nothing Then
        m_lLastFound = -1
      Else
        m_lLastFound = LI.Index + 1
        MsgBox LI.Key & vbCrLf & LI.Text
      End If
    End Sub

    Thanks again for persisting with this thing Arnoutdv but I think you've missed the point. Yes, your example works but it isn't an example of the problem. It works because your are not searching by key, but by index. In your example, m_lLastFound is a Long, not a String.

    Use a string value to represent the key you are looking for and it fails. I've decided it is either a bug or the docs are flat wrong.

  8. #8

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Quote Originally Posted by Phill.W View Post
    Aaaargh!! Why??

    What are you expecting the Poor Soul sat in front of this "monster" to do with 70,000 items in a list?

    Whilst I'm sure you'll get some good responses around here, I think they will all be what I call "Technical Solutions in Search of a Problem". I would strongly suggest you reconsider your User Interface design and make better use of your data[base] assets (i.e don't read all the data "up front"). A user will happily accept a half second delay here and there while the program gets a "bit more" data for them; make them wait a full minute just to load the first list and they'll complain like anything!

    Regards, Phill W.
    Hi Phil! Since your response didn't attempt to help me resolve my issue, or even address it, I was tempted to simply ignore it. But then I realized it was an opportunity to make two good points.

    The first is that something that takes 1/2 a second can stretch into much more when it's happening on a network and/or over a VPN connection. If it happens to extend the "unavailability" of a shared ( and locked) resource, then it's impact is on more than one user. If it happens to be in some function that ends up in a loop somewhere, perhaps made a bit longer by an unexpected growth in volume, the performance hit can be even bigger. I can honestly say that after a 40+ year career in programming I haven't met many users who happily accept delays.

    Second, when one knows nothing about an application, or its development history, it might be prudent to withhold criticism and suggestions of a redesign.

    So Phil, I hope you're right about me getting some good responses here. I really would like to know if this is a true bug in VB6 (the first I have ever found) or, more likely, I've just bungled it somewhere.

  9. #9
    Fanatic Member
    Join Date
    Jan 2013
    Posts
    759

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Totally agree with your first point.
    Any bottleneck can be exacerbated to the point where the whole system grinds to a halt.

    Totally disagree with your second point, though.
    Just because something's "been done that way" doesn't make it right.
    Even if it was right when it was first written, it may not be right any more. The Problem that never gets challenged is the one that will never get fixed.
    Sure, it doesn't win you many friends pointing out that something is creaking at the seams and needs to be updated ("Continual Service Improvement" is one Buzz-word to throw at people who like such things) but, IMHO, that's preferable to letting the problem roll on and on until it hits some "hard" limit and the application breaks completely.

    And, in an effort to redress my earlier omission -
    Remember that the argument to FindItem is a Variant. If VB can "get away" with converting whatever argument you pass it into a number, then it will do so, because indexed look-ups are more efficient that keyed ones. I would suggest prefixing every key you create with a non-numeric character (nobody's ever going to see them, right?) and you should be OK.

    Regards, Phill W.

  10. #10

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Quote Originally Posted by Phill.W View Post
    Totally agree with your first point.
    Any bottleneck can be exacerbated to the point where the whole system grinds to a halt.

    Totally disagree with your second point, though.
    Just because something's "been done that way" doesn't make it right.
    Even if it was right when it was first written, it may not be right any more. The Problem that never gets challenged is the one that will never get fixed.
    Sure, it doesn't win you many friends pointing out that something is creaking at the seams and needs to be updated ("Continual Service Improvement" is one Buzz-word to throw at people who like such things) but, IMHO, that's preferable to letting the problem roll on and on until it hits some "hard" limit and the application breaks completely.

    And, in an effort to redress my earlier omission -
    Remember that the argument to FindItem is a Variant. If VB can "get away" with converting whatever argument you pass it into a number, then it will do so, because indexed look-ups are more efficient that keyed ones. I would suggest prefixing every key you create with a non-numeric character (nobody's ever going to see them, right?) and you should be OK.

    Regards, Phill W.

    I've already been prefixing the key data with "K" as shown in my first post.
    To restate the problem, FindItem appears to work when "index" is an integer, but
    fails when it is a not.

    undefined Code:
    1. Here's a cleaner sample of the problem (Note the alphabet character in the key)
    2.  
    3.     Set LI = ListView1.ListItems.Add(, "K111", "111")   ' Add an item whose key is K111
    4.     Set LI = ListView1.ListItems.Add(, "K222", "222")   ' Add an item whose key is K222
    5.     Set LI = ListView1.ListItems.Add(, "K333", "333")   ' Add an item whose key is K333
    6.  
    7. ' Next stmt fails, Run-time error '13' type mismatch
    8.     Set LI = ListView1.FindItem("222", lvwText, "K222")     ' Find item whose key is K222


    ' According to the docs, the Remove method works in the same fashion as the FindItem
    ' method in that they both interpret the "index" parameter as either an actual index or
    ' a key depending on the data type. String = Key, integer = Index.

    ListView1.Remove("K222") ' <-- The Remove method works as advertised

    ' In other words the Remove method works, the FindItem fails.

  11. #11
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    5,871

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Maybe I do misunderstand or maybe it's a mistake in the documentation, but if you know the Key then you also know the Index.
    So just threat Index as a numeric value.
    Why insist on specifying the key when you also have the index?

  12. #12
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    If you look at the documentation, it becomes obvious you've misusing the FindItem... in two ways...
    http://msdn.microsoft.com/en-us/libr...(v=vs.60).aspx

    First, let's talk about the "starting index" ... first it's just that INDEX... here's what it says about that...
    Optional. An integer or string that uniquely identifies a member of an object collection and specifies the location from which to begin the search.
    NOT KEY... not "what ever you want" ... it says "Integer" ...

    that's why this works:
    Code:
    ' "index" is an integer (Start search at item #2).
    Set LI = ListView1.FindItem("222", lvwText, 2) ' Returns "222"
    And this doesn't:
    Code:
    ' "index" is a string (Start search with item whose key = "K222"
    ' Gets a Run-time error '13', type mismatch
    Set LI = ListView1.FindItem("222", lvwText, "K222")	' Run-time error 13
    What the heck? INDEX is an integer, not a string, so yeah, it fails as I would expect it to do.

    Secondly, the FindItem does NOT WORK on the KEY... It works on the TEXT or the SUBITEMS or the TAG properties... NO WHERE does it state that it does a search by Key.

    Again, from the documentation...
    Constant Value Description
    lvwText 0 (Default) Matches the string with a ListItem object's Text property.
    lvwSubitem 1 Matches the string with any string in a ListItem object's SubItems property.
    lvwTag 2 Matches the string with any ListItem object's Tag property.
    I DOES work as documented... for what ever reason, that documentation doesn't fit your paradigm.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  13. #13

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Hi techgnome, thanks for joining the conversation. With all these folks getting involved, we'll surely get to the bottom of this. I'm afraid my interpretation of the docs is quite a bit different than yours. When I look at the documentation, it is obvious that FindItem can start it's search with an item whose non-integer key matches the supplied key, or an item who's actual index is supplied as an integer. As in "an integer or string ..."

    You say that the index parameter of the FindItem method, used to specify "the starting location from which to begin the search", is only an item's index and can only be an integer. To support that assertion, you quote only half of the docs that describer this parameter.

    Here is the complete spec for "index":

    Optional. An integer or string that uniquely identifies a member of an object collection and specifies the location from which to begin the search. The integer is the value of the Index property; the string is the value of the Key property. If no index is specified, the default is 1.
    What do you suppose they mean when they say "An integer or string?" And what's this stuff about a Key?

    There is more to correct in your post but it's pointless if we can't get past this.


    Back to my original problem, the FindItem doesn't seem to work as advertised. However, The Remove method, which also supports identifying an item by it's key or index, works just fine with the key.

  14. #14
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    The "string" in that quote goes back to the String parameter... the key as it were... so it seems if you DONT specify an index, the string is the Text (or tag or Subitem) but if you DO specify a starting index (again, index - the integer) ... then the search string is the KEY value... But the index is still an integer, not a string. So, again, that's why the first example works and the last one doesn't... index simply cannot be a string... if it could be anything, the parameter would be defined as a variant. Then it could accept anything.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  15. #15

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Quote Originally Posted by techgnome View Post
    The "string" in that quote goes back to the String parameter... -tg
    Really techgnome? Not a chance! I would explain why but it's simply too obvious.

    Here's the relevant doc:
    Finds and returns a reference to a ListItem object in a ListView control.

    Syntax

    object.FindItem (string, value, index, match)

    The FindItem method syntax has these parts:

    Part Description
    object Required. An object expression that evaluates to a ListView control.
    string Required. A string expression indicating the ListItem object to be found.
    value Optional. An integer or constant specifying whether the string will be matched to the ListItem object's Text, Subitems, or Tag property, as described in Settings.
    index Optional. An integer or string that uniquely identifies a member of an object collection and specifies the location from which to begin the search. The integer is the value of the Index property; the string is the value of the Key property. If no index is specified, the default is 1.
    match Optional. An integer or constant specifying that a match will occur if the item's Text property is the same as the string, as described in Settings.
    It's pretty clear that the "index" parameter can be either a string or an integer. It's also clear that, when a string is used, it means start the search with the item whose Key property matches the string value of "index."

  16. #16

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    The debate over the meaning of the docs, which speak for themselves, has taken the focus off of the actual problem, which is the FindItem doesn't appear to work as intended. Find by string Key fails with a Run-time error '13'

    Code:
    Dim LI As ListItem  
    Dim W$  
        
    ' ADD THREE ITEMS TO LISTVIEW WITH KEYS
        ' Syntax:  object.Add(index, key, text, icon, smallIcon)  
    	Set LI = ListView1.ListItems.Add(, "K111", "111")  
    	Set LI = ListView1.ListItems.Add(, "K222", "222")  
    	Set LI = ListView1.ListItems.Add(, "K333", "333")  
    	W$ = ListView1.ListItems(2).Key     ' Just checkin', Returns "K222" 
    
    ' FINDITEM BY INDEX
        ' Syntax:  object.FindItem (string, value, index, match) 
    	Set LI = ListView1.FindItem("222", lvwText, 1) ' Start search at item #1, Returns "222"
     	Set LI = ListView1.FindItem("222", lvwText, 2) ' Start search at item #2, Returns "222"
     	Set LI = ListView1.FindItem("222", lvwText, 3) ' Start search at item #3, Returns nothing 
    
    ' FINDITEM BY KEY
        ' Syntax:  object.FindItem (string, value, index, match)  <--"index" parm contains a string
     	Set LI = ListView1.FindItem("222", lvwText, "K222") ' Start with item whose key = "K222", Gets error '13'
    All help appreciated.

  17. #17
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    FindItem(sz As String, [Where], [Index], [fPartial])

    You're sending a string to index. Can't do that.

    Edit: And it's just the starting point anyway. If you know the key, why not use ListItems.Item(Key).index?
    Last edited by fafalone; Apr 24th, 2014 at 09:15 PM.

  18. #18
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Why not simply ignore the imprecise MSDN-documentation (which apparently doesn't match with the implementation) -
    and do the thing which was perhaps forgotten to implement ("under the covers") with a fast Hash-Lookup yourself?

    This was suggested to you already in Post #11.

    The following works just fine here:

    Code:
    Dim LI As ListItem
    
      With ListView1
      ' ADD THREE ITEMS TO LISTVIEW WITH KEYS
          ' Syntax:  object.Add(index, key, text, icon, smallIcon)
        Set LI = .ListItems.Add(1, "K111", "111")
        Set LI = .ListItems.Add(2, "K222", "222")
        Set LI = .ListItems.Add(3, "K333", "333")
      
      ' FINDITEM BY INDEX
          ' Syntax:  object.FindItem (string, value, index, match)
        Set LI = .FindItem("222", lvwText, 1)  ' Start search at item #1, Returns "222"
        Set LI = .FindItem("222", lvwText, 2)  ' Start search at item #2, Returns "222"
        Set LI = .FindItem("222", lvwText, 3)  ' Start search at item #3, Returns nothing
       
      ' FINDITEM BY KEY
          ' Syntax:  object.FindItem (string, value, index, match)  <--"index" parm contains a string
        Set LI = .FindItem("222", , .ListItems("K222").Index) ' Start with item whose key = "K222"
      End With
    Olaf

    Edit: Hah, too slow for fafalone...
    Last edited by Schmidt; Apr 24th, 2014 at 09:46 PM.

  19. #19

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Quote Originally Posted by Schmidt View Post
    Why not simply ignore the imprecise MSDN-documentation (which apparently doesn't match with the implementation) -
    and do the thing which was perhaps forgotten to implement ("under the covers") with a fast Hash-Lookup yourself?

    This was suggested to you already in Post #11.

    The following works just fine here:

    Code:
    Dim LI As ListItem
    
      With ListView1
      ' ADD THREE ITEMS TO LISTVIEW WITH KEYS
          ' Syntax:  object.Add(index, key, text, icon, smallIcon)
        Set LI = .ListItems.Add(1, "K111", "111")
        Set LI = .ListItems.Add(2, "K222", "222")
        Set LI = .ListItems.Add(3, "K333", "333")
      
      ' FINDITEM BY INDEX
          ' Syntax:  object.FindItem (string, value, index, match)
        Set LI = .FindItem("222", lvwText, 1)  ' Start search at item #1, Returns "222"
        Set LI = .FindItem("222", lvwText, 2)  ' Start search at item #2, Returns "222"
        Set LI = .FindItem("222", lvwText, 3)  ' Start search at item #3, Returns nothing
       
      ' FINDITEM BY KEY
          ' Syntax:  object.FindItem (string, value, index, match)  <--"index" parm contains a string
        Set LI = .FindItem("222", , .ListItems("K222").Index) ' Start with item whose key = "K222"
      End With
    Olaf

    Edit: Hah, too slow for fafalone...

    Thanks for the comments Schmidt.

    As long as the Key exists, these solutions will work. When the Key does not exist, a Run-time error '35601' occurs, unlike FindItem, which returns nothing.

    A good variation of it is:
    Set LI = ListView1.ListItems("K222") 'This works nicely when Key is present

    I was originally using my own time-tested binary search to find the items in the collection but determined that FindItem with Index or Key was very much quicker (for Key I used the direct reference shown above).

    When I first posted this issue, I kind of assumed I was doing something wrong and would get corrected by someone here on the forum. I didn't really think there was a bug in FindItem. However, I now believe that is exactly the problem.

    I guess I'll use the direct reference shown above and, in instances where there could be a key-not-found, I'll just trap the error and deal with it.

    Thanks to all,
    Tom
    Last edited by StuckWithVB6; Apr 25th, 2014 at 12:09 AM.

  20. #20
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    It's more like an error in the documentation. That parameter simply doesn't accept a string.

    Just out of curiosity, how long is it taking to add/search through 70k items? I normally use the 5.0 ListView and found it was so slow with even my 2-3000 items that I switched to a pure API listview (and got a 10x speed bump); is the 6.0 lv fast?

  21. #21

    Thread Starter
    New Member
    Join Date
    Apr 2014
    Posts
    11

    Re: VB6 ListView.FIndItem gets Run-time error '13'

    Quote Originally Posted by fafalone View Post
    It's more like an error in the documentation. That parameter simply doesn't accept a string.

    Just out of curiosity, how long is it taking to add/search through 70k items? I normally use the 5.0 ListView and found it was so slow with even my 2-3000 items that I switched to a pure API listview (and got a 10x speed bump); is the 6.0 lv fast?
    I thought it was just an error in the docs too, but then I saw that the Remove method Index parameter is documented with the same language, that you can use an integer index or a string key. So I tried Remove both ways, and it works with either one, an integer or a string (like the docs say). This leads me to believe that both FindItem and the Remove were intended to work as documented, but, for whatever reason, the implementation fell short. Maybe they'll get it fixed in VB7. :-)

    Regarding the speed of the VB6 ListView, I started with FindItem and just the search string. This was pretty slow (by comparison). Then, still using ListView, I switched to my little binary search and it was quite a bit faster (10x). Life was good.

    A few days later, while reading the docs (something you should always do after you implement :-) ), the part about Index defaulting to 1 and the search starting at the beginning, I reasoned that the FindItem search was slow because it was doing a serial lookup starting at the beginning of the collection each time. I saw that stuff about using a key in the Index parm to get a starting point for the search and figured "they" must be maintaining some sort of internal index (impervious to column sorting), and that they're probably using some sort of binary search on their index to locate the item with a matching key. This means that FindItem would always "start the search" with the matching item (assuming a match exists, and not searching on a partial key) and there would be, in fact, no further search at all.

    Since I couldn't get FindItem to work with the key, I just used the direct reference with the key and it worked very well. It was a little bit faster than my Binary search, so I dumped my search and went with the direct reference by key which, I believe, uses the same index lookup function that FindItem would have used had it been working.

    To answer your question, I would say yes, it's pretty fast. The adds go fast (comparable to string arrays) and the searching is real fast as long as you don't use the FindItem with no Index (starting point). If it can beat my little binary search routine, it's acceptable to me.

    Did you use FindItem with your VB5 ListView?

    Just for grins, I also loaded the data into a string array and used the binary search, which was just a bit faster than using the ListView with key.

Posting Permissions

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



Click Here to Expand Forum to Full Width