Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 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), пишешь код под какую-нибудь кнопочку...
With Combo1
For a = 0 To .ListCount - 1
    For b = 1 To .ListCount - 1
        If .List(a) = .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-сайт: vt-dbnz.narod.ru
 Профиль | | #3
Добавлено: 03.03.06 16:05
Чтобы скорость была действительно высокой, работай с массивом.

Конечно, приведенный код плохой, так как работает за n^2. А можно сделать это в один проход (если данные сортированы).

Что-то типа этого.
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


Надеюсь, не ошибся, так как на действие не проверял. Но суть должна быть ясна.
Можно сделать по-другому. Хранить не индекс предыдущего элемента, а его значение. Возможно, оно было бы немного эффективнее, сразу мне трудно понять.

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-сайт: sur.hotbox.ru/
 Профиль | | #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-сайт: bit.pirit.info
 Профиль | | #9
Добавлено: 03.03.06 17:53
'Способ Victor'а
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-сайт: bit.pirit.info
 Профиль | | #10
Добавлено: 03.03.06 17:57
Есть такой пример добавления в Combo, не добавляет повторы

Option Explicit

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-сайт: bit.pirit.info
 Профиль | | #12
Добавлено: 03.03.06 18:47
Ржунимагу, Требую РУЯ!

Ответить

Номер ответа: 13
Автор ответа:
 avdey



ICQ: 219571279 

Вопросов: 34
Ответов: 486
 Профиль | | #13 Добавлено: 06.03.06 11:57
Жшош хлопцi вопросикум закрытикум....?

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам