На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> ListBox , Поиск подстроки
    Здравствуйте. Из xls файла загружаю в ListBox некий (достаточно большой) список. Далее в Edit ввожу подстроку. Можно ли организовать некий поиск в ListBox по подстроке. Использовать ListBox не обязательно, можно что-то другое, лишь бы данные отображались и их можно было выделить. Переводить данные в нормальную БД не стоит, т.к. в целом задача не большая.
      Подстрока - с начала строки? Тогда можно SendMessage(LBHandle, LB_FINDSTRING, -1, (LPARAM)substring)
      Иначе - только тупым перебором и strstr() или подобной
        ListBox->Items->Strings - ищи че хочешь.
        Сообщение отредактировано: shm -
          Цитата shm @
          ListBox->Items->Strings

          Получается все строки перебрать надо?
            Цитата
            AnsiString::AnsiPos

            AnsiString See also

            Returns the index at which the specified substring begins.

            int __fastcall AnsiPos(const AnsiString& subStr) const;

            Description

            Returns the index in the AnsiString at which the substring subStr begins, where 1 is the first character in the string, 2 is the second character, and so on. If the substring is not contained in the AnsiString, Pos returns 0. This member function is the same as Pos but supports multibyte character strings.

            Note: See ByteType for more information about multibyte characters.


            Добавлено
            Цитата sten_11 @
            Получается все строки перебрать надо?

            Да. Но если загнать в Мемо то весь текст.
            А не проще при загрузке из xls фильтровать нужное?
              Цитата Bas @
              А не проще при загрузке из xls фильтровать нужное?

              Нет. Я хотел реализовать что-то типа:
              ExpandedWrap disabled
                void __fastcall TForm1::Edit1Change(TObject *Sender)
                {
                POISK = Edit1->Text.Trim();
                ...
                select *from table where param like(%POISK %);
                }
                Создаем второй ListBox2
                ExpandedWrap disabled
                  void __fastcall TForm1::Edit1Change(TObject *Sender)
                  {
                  int i=0;
                  ListBox *LName;
                  LFind= new ListBox();
                   while (i<ListBox1->Items->Count)
                   {
                    if (ListBox1->Items->Strings.AnsiPos( Edit1->Text.Trim())>=0) LFind->Items->Add(ListBox1->Items->Strings[i])
                    i++;
                   }
                  //select *from table where param like(%POISK %);
                  }

                Что то типа? Не забудем удалить после new.
                Сообщение отредактировано: Bas -
                  Цитата sten_11 @
                  select *from table where param like(%POISK %);

                  :) Такое средствами ListBox не сделать. Однако, можно поробовать открыть твою таблицу через ADO, а там есть и SQL и DBListBox.
                    ExpandedWrap disabled
                      select *from table where param like(%POISK %);


                    Я так понимаю это вообще команда к SQL, причем тут ListBox ????
                      ExpandedWrap disabled
                        void __fastcall TForm1::Edit1Change(TObject *Sender)
                        {
                          for(int i = 0; i < ListBox1->Items->Count; i++)
                          {
                            if (ListBox1->Items->Strings.AnsiPos(Edit1->Text.Trim())>=0)
                            {
                              ListBox1->ItemIndex = i;
                              break;
                            }
                          }
                        }
                        Цитата Dem_max @
                        Я так понимаю это вообще команда к SQL, причем тут ListBox ????

                        Дело в том, что я не хочу в рамках этой задачи связываться с БД. Просто на БД я бы использовал скрипт, а тут мне надо реализовать его аналог.
                          ListBox1-исходные данные, невидимый
                          ListBox2-результат выборки, видимый
                          ExpandedWrap disabled
                            void __fastcall TForm1::Edit1Change(TObject *Sender)
                            {
                            int i=0;
                            ListBox2->Items->Clear();
                             while (i<ListBox1->Items->Count)
                             {
                              if (ListBox1->Items->Strings.AnsiPos( Edit1->Text.Trim())>=0) ListBox2->Items->Add(ListBox1->Items->Strings[i])
                              i++;
                             }
                            Цитата Bas @
                            Создаем второй ListBox2

                            Это идея. Попробовал так, но не вышло.
                            ExpandedWrap disabled
                              void __fastcall TForm1::Edit1Change(TObject *Sender)
                              {
                              ListBox2->Clear();
                              int i=0;
                              while (i<ListBox1->Items->Count)
                               {
                                if (ListBox1->Items->Strings[i].AnsiPos( Edit1->Text.Trim())>=0)
                                ListBox2->Items->Add(ListBox1->Items->Strings[i]);
                                i++;
                               }
                               
                              }

                            Создается второй список полностью аналогичный первому.
                              а слона-то никто и не заметил. AnsiPos возвращает > 0, если находит
                                Цитата Relaxander @
                                а слона-то никто и не заметил

                                да ни кто и не смотрел... вроде автора перебор не устраивал, а теперь вроде поменял мнение.
                                  А все получилось, надо было к регистру общему привести
                                    Цитата sten_11 @
                                    Дело в том, что я не хочу в рамках этой задачи связываться с БД

                                    на билдере это нск. строк кода.
                                      Цитата shm @
                                      вроде автора перебор не устраивал, а теперь вроде поменял мнение.

                                      А что делать ))

                                      Добавлено
                                      Итого получилось
                                      ExpandedWrap disabled
                                        void __fastcall TForm1::Edit1Change(TObject *Sender)
                                        {
                                        ListBox2->Clear();
                                        int i=0;
                                        bool compre = false;
                                        while (i<ListBox1->Items->Count)
                                         {
                                          compre = ListBox1->Items->Strings[i].Pos(Edit1->Text.Trim());
                                          if (compre)
                                          {
                                           ListBox2->Items->Add(ListBox1->Items->Strings[i]);
                                          }
                                          compre = false;
                                          i++;
                                         }
                                        }

                                      Принимаю более оптимальные коды.

                                      Добавлено
                                      В догонку. Как в Мемо вывести строку из ListBox на которой активный курсор. Можно по двойному клику на ListBox .
                                        Цитата sten_11 @
                                        более оптимальные коды

                                        а почему compre - bool и зачем compre = false?
                                          Цитата Relaxander @
                                          а почему compre - bool и зачем compre = false?

                                          Справедливо
                                          ExpandedWrap disabled
                                            if (ListBox1->Items->Strings[i].Pos(Edit1->Text.Trim()))
                                            Цитата Relaxander @
                                            а слона-то никто и не заметил. AnsiPos возвращает > 0, если находит

                                            По памяти писал, спутал наверное с -1.
                                            Сообщение отредактировано: Bas -
                                              Народ, простите что тему старую поднимаю. Мне пригодилась эта ветка. Но появился вопрос. Есть ли возможность из этого кода убрать чувствительность к регистру?

                                              У меня получилось только привести всё к нижнему регистру. Но некоторые люди и грамотно пишут и будут писать первую букву большую. Тогда фильтрация уже не срабатывает.

                                              ExpandedWrap disabled
                                                ListBox2->Clear();
                                                int i=0;
                                                bool compre = false;
                                                while (i<ListBox1->Items->Count)
                                                 {
                                                  compre = ListBox1->Items->Strings[i].LowerCase().Pos(Edit1->Text.Trim());
                                                  if (compre)
                                                  {
                                                   ListBox2->Items->Add(ListBox1->Items->Strings[i]);
                                                  }
                                                  compre = false;
                                                  i++;
                                                 }
                                                Убрать чувствительность, это так:
                                                ExpandedWrap disabled
                                                  ListBox2->Clear();
                                                  int i = 0;
                                                  while( i<ListBox1->Items->Count )
                                                  {
                                                      int compre = ListBox1->Items->Strings[i].LowerCase().Pos( Edit1->Text.LowerCase().Trim() );
                                                      if( compre ) ListBox2->Items->Add( ListBox1->Items->Strings[i] );
                                                      i++;
                                                  }
                                                  И как я сам не додумался :D Спасибо. Отлично работает.
                                                  2 пользователей читают эту тему (2 гостей и 0 скрытых пользователей)
                                                  0 пользователей:


                                                  Рейтинг@Mail.ru
                                                  [ Script execution time: 0,0653 ]   [ 15 queries used ]   [ Generated: 8.11.24, 22:44 GMT ]