Results 1 to 6 of 6

Thread: How to prevent duplicate item.

Threaded View

  1. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,918

    Re: How to prevent duplicate item.

    Here, something like this is what I'd propose. If you further manipulate the listbox though, you'd need to do further work with the collection to make sure it stayed mirrored:

    Code:
    
    Option Explicit
    
    Dim coll As New Collection
    
    
    Private Sub Form_Load()
    
        Dim i As Long
        Dim s As String
    
        For i = 1 To 1000
            s = sRandomString(2)
            If bAddedToCollection(s) Then List1.AddItem s
        Next i
    
    
        MsgBox List1.ListCount
    
    End Sub
    
    Public Function bAddedToCollection(sData As String) As Boolean
        ' Returns false if already in collection.
        On Error GoTo HadError
        coll.Add sData, sData
        bAddedToCollection = True
    HadError:
    End Function
    
    Public Function sRandomString(iLength As Integer) As String
        Dim i As Integer
        Dim j As Integer
        Dim s As String
        Static b As Boolean
        '
        If Not b Then
            Randomize
            b = True
        End If
        '
        Do Until j = iLength
            ' This returns an integer from 48 to 83.
            i = Int(36 * Rnd + 48)
            ' Skip over characters between 9 and A.
            If i > 57 Then i = i + 7
            ' Now, i is between 48 and 57 or 65 and 90.
            '                   "0"    "9"   "A"    "Z"
            s = s + Chr$(i)
            j = j + 1
        Loop
        sRandomString = s
    End Function
    
    
    

    EDIT1: Vb6Lovers code also looks quite interesting, and it's certainly more memory efficient than mine.

    EDIT2: However, just out of curiousity, I timed both methods. The Collection method seems to be WAY faster. I suspect that this is true because the API still has to loop through the listbox, and a collection has a binary-tree index that can be searched (which is much faster than a loop).

    After running it a few times, my results were:
    Code:
    API Seconds:  1.574219 
    Collection Seconds:  0.3046875 
    API Seconds:  1.546875 
    Collection Seconds:  0.3007813 
    API Seconds:  1.5625 
    Collection Seconds:  0.296875
    And here's my patched up code I used to test the timing:
    Code:
    Option Explicit
    
    Dim coll As New Collection
    
    Private Const LB_FINDSTRINGEXACT = &H1A2
    Private Const LB_ADDSTRING = &H180
    
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    '
    
    
    Public Function bFoundInListBox(s As String, lst As ListBox) As Boolean
        Dim iRet As Long
        iRet = SendMessage(lst.hwnd, LB_FINDSTRINGEXACT, -1&, ByVal s)
        bFoundInListBox = iRet > -1&
    End Function
    
    Private Sub Form_Load()
        
        Dim i As Long
        Dim s As String
        Dim nStart As Single
        
        
        nStart = Timer
        For i = 1 To 3000
            s = sRandomString(3)
            If Not bFoundInListBox(s, List1) Then List1.AddItem s
        Next i
        Debug.Print "API Seconds: "; Timer - nStart
    
    
    
        
        
        nStart = Timer
        For i = 1 To 3000
            s = sRandomString(3)
            If bAddedToCollection(s) Then List2.AddItem s
        Next i
        Debug.Print "Collection Seconds: "; Timer - nStart
        
        
        MsgBox List1.ListCount
        
    End Sub
    
    Public Function bAddedToCollection(sData As String) As Boolean
        ' Returns false if already in collection.
        On Error GoTo HadError
        coll.Add sData, sData
        bAddedToCollection = True
    HadError:
    End Function
    
    Public Function sRandomString(iLength As Integer) As String
        Dim i As Integer
        Dim j As Integer
        Dim s As String
        Static b As Boolean
        '
        If Not b Then
            Randomize
            b = True
        End If
        '
        Do Until j = iLength
            ' This returns an integer from 48 to 83.
            i = Int(36 * Rnd + 48)
            ' Skip over characters between 9 and A.
            If i > 57 Then i = i + 7
            ' Now, i is between 48 and 57 or 65 and 90.
            '                   "0"    "9"   "A"    "Z"
            s = s + Chr$(i)
            j = j + 1
        Loop
        sRandomString = s
    End Function
    Last edited by Elroy; Mar 3rd, 2017 at 04:40 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

Tags for this Thread

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