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

Поиск в ListBox

11.10.2014, 18:55. Показов 6438. Ответов 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
33399 / 21509 / 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
33399 / 21509 / 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
33399 / 21509 / 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
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru