|
-
Mar 3rd, 2017, 04:17 PM
#4
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|