Страница: 1 |
Страница: 1 |
Вопрос: Как убрать повторы в ComboBox
Добавлено: 03.03.06 14:29
Автор вопроса: flot
Например в моем ComboBox расположены следующие данные:
VALUE1
VALUE2
VALUE2
VALUE3
VALUE4
VALUE4
VALUE4
VALUE5
Как мне сделать, чтобы убрать повторы данных. Чтобы они были в виде:
VALUE1
VALUE2
VALUE3
VALUE4
VALUE5
Ответы
Всего ответов: 13
Номер ответа: 1
Автор ответа:
avdey
ICQ: 219571279
Вопросов: 34
Ответов: 486
Профиль | | #1
Добавлено: 03.03.06 14:51
Ставишь свойство Combo1.Sorted = true (програмно не получится, тк ReadOnly), пишешь код под какую-нибудь кнопочку...
For a = 0 To .ListCount - 1
For b = 1 To .ListCount - 1
If .List = .List(b) Then
If a <> b Then
.RemoveItem (b)
GoTo Mark
End If
End If
Next
Mark:
Next
End With
И все готово.
Номер ответа: 2
Автор ответа:
flot
Вопросов: 1
Ответов: 2
Профиль | | #2
Добавлено: 03.03.06 15:37
avdey - у меня в Combobox - около 15000 записей! Твой пример будет работать очень долго, если вообще программа не слетит с Out of memory
Номер ответа: 3
Автор ответа:
Victor
ICQ: 345743490
Вопросов: 42
Ответов: 385
Web-сайт:
Профиль | | #3
Добавлено: 03.03.06 16:05
Чтобы скорость была действительно высокой, работай с массивом.
Конечно, приведенный код плохой, так как работает за n^2. А можно сделать это в один проход (если данные сортированы).
Что-то типа этого.
PrevIndex = Combo1.ListCount-1
For i = Combo1.ListCount - 2 to 0 Step -1
If Combo1.List(i) = Combo1.List(PrevIndex) Then
Combo1.RemoveItem i 'совпадает с предыдущим, удалить.
PrevIndex = PrevIndex - 1 'После удаления элемент сместился вверх, надо обновить указатель
Else
PrevIndex = i 'Не совпадает с предыдущим. Он станет новым предыдущим.
End If
Next i
Надеюсь, не ошибся, так как на действие не проверял. Но суть должна быть ясна.
Можно сделать по-другому. Хранить не индекс предыдущего элемента, а его значение. Возможно, оно было бы немного эффективнее, сразу мне трудно понять.
PS. Никак не могу понять, как же все-таки устроен этот метод с двумя циклами. Еще и GoTo.
Номер ответа: 4
Автор ответа:
avdey
ICQ: 219571279
Вопросов: 34
Ответов: 486
Профиль | | #4
Добавлено: 03.03.06 16:40
как как, вот так и устроен... Сравнивает каждый елемент с другими... конечно по ламерски, но и вопрос...(flot, не в обиду
На самом деле стоит задуматься, Хорошая задачка (еслиб пара строк в Комбо, то всем бы пофиг было, а вот 15000, стоит задача оптимизации)
Я же не знал что там 15000 записей!!! Записей 100 за пару сек бы сделал...
Да сейчас у меня гоняются эти два цикла, а в Комбо 15000 случайных чисел... Прошло 18 мин.........................
Позже выложу сдесь сколько прошло времени...
И попробую методом Victor'а...
Номер ответа: 5
Автор ответа:
avdey
ICQ: 219571279
Вопросов: 34
Ответов: 486
Профиль | | #5
Добавлено: 03.03.06 16:53
Короче прошло 25 минут...
Он удалил совпадения и начал гонять пустые строки в листе Комбо где раньше были совпадающие символы...
О блин на работе *одку позвали пить, ща дерну и буду метод Виктора пробовать.
Номер ответа: 6
Автор ответа:
Sur
ICQ: 1249088
Вопросов: 10
Ответов: 304
Web-сайт:
Профиль | | #6
Добавлено: 03.03.06 17:00
Вотка это хорошо, но изобретать велосипед, да еще так мучительно испытывать - это перебор. Я еще подолью: ускорить процесс можно, зная тип и длины (строковых) данных в исходном массиве.
Номер ответа: 7
Автор ответа:
flot
Вопросов: 1
Ответов: 2
Профиль | | #7
Добавлено: 03.03.06 17:09
Вот придумал свой способ с коллекцией, сортирует 15000 параметров примерно за минуту!
Dim z As New Collection
For i = 1 To Me.Combo1.ListCount - 1
StartForm.ProgressBar1.Value = i
StartForm.Label2.Caption = Int((i / Val(Data1.Recordset.RecordCount)) * 100) & " %"
If Me.Combo1.List(i) <> Me.Combo1.List(i + 1) Then 'Сохраняю несовпадающие параметры
Me.Combo1.RemoveItem (i)
z.Add Me.Combo1.List(i)
End If
DoEvents
Next i
Me.Combo1.Clear 'Очищаю COMBO
For i = 1 To z.Count
Me.Combo1.AddItem z.Item(i) 'Опять записываю данные
Next i
Номер ответа: 8
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #8
Добавлено: 03.03.06 17:24
Например в моем ComboBox расположены следующие данные
Кем они там расположены?
Набиваешь его сам? Вот в процессе укладки и фильтруй совпадения, нефиг мартышкин труд делать.
ЗЫ В коллекции проверок не нужно, просто добавляй по ключу. Коллекция сама не даст добавить два одинаковых ключа.
Номер ответа: 9
Автор ответа:
[root]
Вопросов: 45
Ответов: 1212
Web-сайт:
Профиль | | #9
Добавлено: 03.03.06 17:53
Option Explicit
Private Sub Command1_Click()
'Удаляет повторы около 2 секунд
Dim i As Integer
Dim PrevIndex As Long 'индекс в комбобокс на последний неудаленный элемент
PrevIndex = Combo1.ListCount - 1
For i = Combo1.ListCount - 2 To 0 Step -1
If Combo1.List(i) = Combo1.List(PrevIndex) Then
Combo1.RemoveItem i 'совпадает с предыдущим, удалить.
PrevIndex = PrevIndex - 1 'После удаления элемент сместился вверх, надо обновить указатель
Else
PrevIndex = i 'Не совпадает с предыдущим. Он станет новым предыдущим.
End If
Next i
End Sub
Private Sub Form_Load()
'Заполняет чуть больше секунды
Dim i As Integer
For i = 1 To 15000
Combo1.AddItem Format$(1)
Next
End Sub
Номер ответа: 10
Автор ответа:
[root]
Вопросов: 45
Ответов: 1212
Web-сайт:
Профиль | | #10
Добавлено: 03.03.06 17:57
Есть такой пример добавления в Combo, не добавляет повторы
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
Private Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As String) As Long
Const CB_SHOWDROPDOWN = &H14F
Const CB_FINDSTRINGEXACT = &H158
Private Sub Command1_Click()
With Combo1
If Not CheckDuplicates(.hWnd, .Text) Then
.AddItem .Text
End If
SendMessage .hWnd, CB_SHOWDROPDOWN, True, ByVal 0&
End With
End Sub
Private Sub Form_Load()
'Put some items in the combobox
With Combo1
.AddItem "Sunday"
.AddItem "Monday"
.AddItem "Tuesday"
.AddItem "Wednesday"
.AddItem "Thursday"
.AddItem "Friday"
.AddItem "Saturday"
'Provide the default value
.Text = .List(0)
'Open the dropdown list
SendMessage .hWnd, CB_SHOWDROPDOWN, _
True, ByVal 0&
End With
End Sub
Private Function CheckDuplicates(chwnd As Long, StringText As String) As Boolean
CheckDuplicates = SendMessageByString(chwnd, CB_FINDSTRINGEXACT, -1, ByVal StringText) > -1
End Function
Номер ответа: 11
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #11
Добавлено: 03.03.06 18:12
ГыыЫы, жжош сцуко. Зачот
Номер ответа: 12
Автор ответа:
[root]
Вопросов: 45
Ответов: 1212
Web-сайт:
Профиль | | #12
Добавлено: 03.03.06 18:47
Ржунимагу, Требую РУЯ!
Номер ответа: 13
Автор ответа:
avdey
ICQ: 219571279
Вопросов: 34
Ответов: 486
Профиль | | #13
Добавлено: 06.03.06 11:57
Жшош хлопцi вопросикум закрытикум....?