Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/34: Рейтинг темы: голосов - 34, средняя оценка - 4.68
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138

Поиск в ListBox

11.10.2014, 18:55. Показов 6444. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно такой вопрос... У мен я в ListBox ооооочень много значений. Поэтому нужен поиск по этим элементам. Сделать поиск по полному совпадение Edit1->Text и ListBox1->Items->Strings[i] не проблема, но допустим такая ситуация: человек знает лишь половину названия эл-та которого он ищет. Нужно что бы тогда отобразились что называется элементы по "совпадению". Может кто подскажет как такое реализивать..

Ещё лучше человек ввёл символы в Edit и лист бокс обновился, а там эл-т которые начинаются с таких букв..
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.10.2014, 18:55
Ответы с готовыми решениями:

Поиск в ListBox
Есть список файлов в ListBox. Как сделать так чтобы в каждом файле искало определенное слово и выводило файлы, в которых нашло(открывало...

При выделении строки в ListBox отображать ее в Edit, где можно отредактировать и заменить в ListBox-е
Подскажите пожалуйста как зделать задачку:При выделении строки в поле ListBox даная строка отображалась в Edit, где можна его...

Перенести данные из ListBox на форме в Listbox на PageСontrol
Доброго времени суток! Как заставить данные которые вносятся на Form в ListBox перенести на Listbox, который находится на Pagekontrol?

24
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
11.10.2014, 19:10
Есть методы Pos() и IndexOf(). Есть регулярки, если и этого окажется мало.

Обновление - тоже легко. Сохраняешь строки с ListBox'a в TStringList, выполняешь поиск, очищаешь листбокс и найденное в него добавляешь.
0
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
12.10.2014, 00:21  [ТС]
BRcr, у меня 7к элементов там, а то и больше под 15к... кидать из стринга в лист при малейшем изменении буквы в поиске - жестоко. или другого способа нету?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
12.10.2014, 13:11
Тогда я вообще не вижу смысла хранить список непосредственно в листбоксе. Зачем? Чтобы иметь возможность покрутить мышкой 15000 строк? Лучше уж в таком случае поисковую систему рассматривать как основной способ доступа.
Цитата Сообщение от semihal Посмотреть сообщение
кидать из стринга в лист при малейшем изменении буквы в поиске - жестоко.
При малейшем изменении действительно ни к чему. Строка поиска + кнопочка "Начать поиск", чтоб не шибко накладно было.
Цитата Сообщение от semihal Посмотреть сообщение
или другого способа нету?
Возможно и есть. Можно попробовать подменять указатель FItems, чтобы избежать нежелательных копирований списка, но не факт, что так уж легко это получится. На запись там стоит сеттер SetItems(), так что может присутствовать какая-то дополнительная обработка. Пробовать надо.
0
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
12.10.2014, 16:11  [ТС]
BRcr, нужно что бы так человек видел их, т.е. листбокс нужен..
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
12.10.2014, 16:26
Цитата Сообщение от semihal Посмотреть сообщение
BRcr, у меня 7к элементов там, а то и больше под 15к... кидать из стринга в лист при малейшем изменении буквы в поиске - жестоко. или другого способа нету?
Ну все 7к элементов одновременно видеть пользователю незачем.
Разбить нельзя по группам по какому либо признаку и отображать только запрошенную пользователем часть(категорию)?

Ну и если элементы действительно элементы почему не парсить поэлементно ...
0
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
12.10.2014, 17:00  [ТС]
Avazart, понимаешь эти элементы они грубо говоря динамичны. а разбить на категории точно никак, ибо там идут элементы, при клике на которые открывается массив данных в стпинггриде, индекс соответствует itemindex листбокса. + данные в листбоксе изменяются в соответствии с выбранным комбобоксом.

Тогда хотя бы что бы список не обновлялся а рработал по принципы, выделил первое совпадение , а ,дальше по кнопками след совпадение и т.д.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
12.10.2014, 17:24
Тогда задача совсем не ясна, ничем не помочь, пока не сформулируешь понятным образом.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33400 / 21510 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
12.10.2014, 17:44
Лучший ответ Сообщение было отмечено BRcr как решение

Решение

semihal, сделай листбокс виртуальным, и...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// ---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    L = new TStringList;
    ListBox1->Style = lbVirtual;
    for(int i = 1; i < 22000; i++) L->AddObject(IntToStr(i), (TObject*)i);
    L->AddObject("1 first", (TObject*)22000);
    L->AddObject("1 second", (TObject*)22001);
    L->AddObject("2 test", (TObject*)22002);
    L->AddObject("2 temp", (TObject*)22003);
    ListBox1->Count = 22003; // 4
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1Data(TWinControl *Control, int Index,
    UnicodeString &Data)
 
{
    Data = L->Strings[Index];
}
 
int __fastcall MyCompare(TStringList *List, int Index1, int Index2)
{
    int obj1 = (int)(List->Objects[Index1]);
    int obj2 = (int)(List->Objects[Index2]);
 
    if (obj1 * obj2 > 0)
    {
        return abs(obj1) - abs(obj2);
    }
    else
        return (obj1 < 0 ? -1 : 1);
}
 
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
    int count = 0;
    if(!Edit1->Text.Trim().IsEmpty())
    {
        for(int i = 0; i < L->Count; i++)
        {
            L->Objects[i] = (TObject*)(abs((int)(L->Objects[i])));
            if(L->Strings[i].Pos(Edit1->Text))
            {
                L->Objects[i] = (TObject*)(- (int)(L->Objects[i]));
                count += 1;
            }
        }
        L->CustomSort(MyCompare);
        ListBox1->Count = count;
    }
    else
    {
        for(int i = 0; i < L->Count; i++)
        {
            L->Objects[i] = (TObject*)(abs((int)(L->Objects[i])));
        }
        L->CustomSort(MyCompare);
        ListBox1->Count = L->Count;
    }
 
    ListBox1->Refresh();
}
Вот этот самый код при 22 тысячах элементов в ListBox-е даже не притормаживает. Небольшое торможение начинается при 50 тысячах... Реальный индекс выбранного элемента ты всегда можешь вытащить даже из отфильтрованного списка:
C++
1
2
3
4
void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
    Caption = IntToStr(abs((int)(L->Objects[ListBox1->ItemIndex])));
}
2
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
12.10.2014, 18:34  [ТС]
UI, не совсем с виду разобрался в коде.. Дома буду запущу в билдере ._.

Добавлено через 8 минут
P.S. не понялалгоритма с abs()
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33400 / 21510 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
12.10.2014, 19:36
Идея такая. Тем элементам, которые содержат требуемую подстроку, устанавливаем в поле Objects отрицательное значение, тем, которые не содержат - положительное. И пересортировываем StringList так, чтобы все элементы с отрицательным "объектом" были выше положительных (таким образом сверху окажутся требуемые строки, содержащие заданную подстроку)... Ограничиваем число элементов ListBox-а, и вуаля, требуемое поведение реализовано.

Что именно непонятно? Сам алгоритм сортировки? А ты в курсе, что вообще должна возвращать функция, передаваемая в CustomSort? Когда она возвращает 1 а когда (-1)?
0
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
13.10.2014, 09:00  [ТС]
C++
1
obj1 < 0 ? -1 : 1
ну если ты про это, то это знаю :/ теперь понял алгоритм, с телефона просто не сразу понял

Добавлено через 4 часа 26 минут
UI, проверил код. Работает, вообще на УРА. Просто шикарно. Спасибо тебе огромное, дружище!!!

Добавлено через 1 час 23 минуты
UI, но есть 1 минус. Если ты ввёл, а совпадений нету, то при стирании листбокс остаётся пустым..

Добавлено через 7 часов 12 минут
UI, Прошу прощения. Я видимо на ночь глядя сам уже тупить начала, всё отлично работает, косяк был с моей стороны, прошу прощения !
0
0 / 0 / 1
Регистрация: 10.12.2012
Сообщений: 8
09.11.2014, 11:15
UI,на каком билдере работаете? у меня ХЕ 3 выдает ошибку тут L->CustomSort(MyCompare);
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33400 / 21510 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
09.11.2014, 14:16
RAD 2009/XE2/XE3/XE4, ни на одном ошибки нет... А если у тебя выдает ошибку - надо хотя бы ее описание привести, кто знает на что теперь способны программисты. Даже код скопировать/вставить и то не могут нормально...
0
0 / 0 / 1
Регистрация: 10.12.2012
Сообщений: 8
10.11.2014, 19:19
[bcc32 Error] realiz.cpp(33): E2034 Cannot convert 'int (_fastcall * (_closure )(TStringList *,int,int))(TStringList *,int,int)' to 'int (_fastcall *)(TStringList *,int,int)'
[bcc32 Error] realiz.cpp(33): E2342 Type mismatch in parameter 'Compare' (wanted 'int (_fastcall *)(TStringList *,int,int)', got 'void')
Такие вот ошибки выдает
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
10.11.2014, 19:38
MyCompare не надо было делать методом класса. Надо было для начала повторить данный код один в один, а уж потом экспериментировать...
0
0 / 0 / 1
Регистрация: 10.12.2012
Сообщений: 8
10.11.2014, 20:21
Спасибо,все ОК!Невнимательность и спешка)))
0
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
23.02.2015, 22:25  [ТС]
Через какое-то время снова понадобилась это тема...
Но понять никак не могу, в чём дело, что не так Оо...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
TStringList* L;
 
int __fastcall MyCompare(TStringList *List, int Index1, int Index2)
{
    int obj1 = (int)(List->Objects[Index1]);
    int obj2 = (int)(List->Objects[Index2]);
 
    if (obj1 * obj2 > 0)
    {
        return abs(obj1) - abs(obj2);
    }
    else
        return (obj1 < 0 ? -1 : 1);
}
 
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
int count = 0;
    if(!Edit1->Text.Trim().IsEmpty())
    {
        for(int i = 0; i < L->Count; i++)
        {
            L->Objects[i] = (TObject*)(abs((int)(L->Objects[i])));
            if(L->Strings[i].Pos(Edit1->Text))
            {
                L->Objects[i] = (TObject*)(- (int)(L->Objects[i]));
                count += 1;
            }
        }
        L->CustomSort(MyCompare);
        ListBox1->Count = count;
    }
    else
    {
        for(int i = 0; i < L->Count; i++)
        {
            L->Objects[i] = (TObject*)(abs((int)(L->Objects[i])));
        }
        L->CustomSort(MyCompare);
        ListBox1->Count = L->Count;
    }
 
    ListBox1->Refresh();
}
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    ListBox1->Style = lbVirtual;
}
 
void __fastcall TForm1::ListBox1Data(TWinControl *Control, int Index, UnicodeString &Data)
{
    Data = L->Strings[Index];
}
 
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
    L = new TStringList();
    ListBox1->Count = objOne.InsertListBox(L, ComboBox1->ItemIndex ,(int)ComboBox1->Items->Objects[ComboBox1->ItemIndex]); // Тут мы заполняем ListBox и возвращаем Count
 
// Таким образом: L->AddObject(Data<wchar_t>(byte), (TObject*)(byte - skeep)); // То есть просто добавляем объект с именем и "объектом"
}
Все хорошо работает, но как-только ввожу что-нибудь в Edit1, получаю ошибку, а следом вылетает и access... Подскажите что делать..
Миниатюры
Поиск в ListBox  
0
6 / 6 / 3
Регистрация: 04.10.2014
Сообщений: 138
23.02.2015, 23:09  [ТС]
Попытался ещё раз, бывает она начинает искать, а потом тупо зависает..

Добавлено через 34 минуты
Выяснил в каком месте ошибка:
C++
1
L->AddObject(Data<wchar_t>(byte), (TObject*)(byte - skeep));
С (TObject*)i всё хорошо работает. Но как быть в данном случае, данные в (TObject*) важны..
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
23.02.2015, 23:26
Шта? Кто такое byte? Строчки текста что ли хочешь заложить под Objects?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.02.2015, 23:26
Помогаю со студенческими работами здесь

Возможно ли при выборе через opendialog заносить в ListBox имена файлов, а при чтении из ListBox получать путь к файлам?
Возможно ли при выборе через opendialog заносить в ListBox имена файлов, а при чтении из ListBox получать путь к файлам?

Удаление не выделенных строк в ListBox (Поиск в ListBox)
Добрый день! Друзья, подскажите, пожалуйста, как внутри ListBox организовать поиск по записям (фильтр), чтобы остались только валидные...

Поиск в Listbox
Здравствуйте! Как организовать поиск в listbox ? Например ввожу текст в textbox что бы искал-фильтровал в listbox'е?

Поиск в listbox
У меня есть listbox и там написаны имена. На какое-то событие нужно найти в listbox строку с именем и добавить к этой строке...

Поиск в listbox
Добрый день. Необходимо сделать поиск в listbox при указании текста в edit. Необходимо чтобы, было следующего плана: начинаешь вписывать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru