Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.04.2013, 19:26
xbron xbron вне форума
Прохожий
 
Регистрация: 15.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Не получается сравнение элементов в списке listbox

Работает только по первому добавлению в список, а потом работает не правильно. О задаче: Есть пустой список, добавляю туда из Грида, а после если добавляется уже существующее в списке, то выводится сообщение о добавлении.
Код:
procedure Tform_books.Button4Click(Sender: TObject);
var i:integer;
begin
listbox1.Items.Add(adoquery1.fieldbyname('Название_книги').AsString);
if listbox1.Items.Count<>0 then
 for i:=1 to listbox1.Items.Count-1 do
   if listbox1.Items.Strings[i]=listbox1.Items.strings[i]
      then
        begin
         if MessageDlg('Вы действительно хотите добавить существующую книгу?',
         mtConfirmation, [mbYes, mbNo], 0) = mrYes
           then
            begin
             break;
            end
           else
            begin
              listbox1.Items.Delete(i);
            end;
         end;
end;
Ответить с цитированием
  #2  
Старый 15.04.2013, 19:32
xbron xbron вне форума
Прохожий
 
Регистрация: 15.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Попробовал это, но теперь после 2-й добавленной строки, не сравнивается...
Код:
if listbox1.Items.Count<>0 then
 for i:=1 to listbox1.Items.Count-1 do
 begin
  f:=listbox1.Items.IndexOf(listbox1.Items.strings[i]);
   if f=1
      then
        begin
         if MessageDlg('Хотите добавить уже добавленную книгу?',
         mtConfirmation, [mbYes, mbNo], 0) = mrYes
           then
            begin
             break;
            end
           else
            begin
              listbox1.Items.Delete(i);
            end;
         end;
 end;

Последний раз редактировалось xbron, 15.04.2013 в 19:35.
Ответить с цитированием
  #3  
Старый 16.04.2013, 02:33
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Если добавление из БД, соответсвенно, регистр будет одинаковый для любой попытки, то можно так:
Код:
procedure AddItemToListBox(AListBox : TListBox; AItem : String);
begin
  If AListBox.Items.IndexOf(AItem) = -1
    Then AListBox.Items.Add(AItem)
    Else
      If MessageDlg('Элемент уже есть. Добавляем?',mtConfirmation,[mbYes,mbNo],0) = mrYes 
       Then AListBox.Items.Add(AItem);
end;

Если надо проверять без учета регистра, то можно сделать свою функцию IndexOf, например:
Код:
function IndexOfText(AList : TStringList; AStr : String) : Integer;
var
  I : Integer;
begin
  Result := -1;
  For I := 0 To AList.Count-1 Do
    If AnsiCompareText(AList[i],AStr) = 0 Then
      Begin
        Result := I;
        Break;
      End;
end;
Ответить с цитированием
  #4  
Старый 16.04.2013, 10:57
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Так работать с живым списком нельзя. Вы же для цикла определили границы в цикле. В Дельфи для цикла for границы задаются константно, а не динамически. Затем изменили их произвольно удалив элемент из списка. Хотите удалять таким способом - ради бога, но просматривать тогда надо список не с начала, а с конца.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #5  
Старый 16.04.2013, 16:41
xbron xbron вне форума
Прохожий
 
Регистрация: 15.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Страдалецъ
Так работать с живым списком нельзя. Вы же для цикла определили границы в цикле. В Дельфи для цикла for границы задаются константно, а не динамически. Затем изменили их произвольно удалив элемент из списка. Хотите удалять таким способом - ради бога, но просматривать тогда надо список не с начала, а с конца.
Можно как-нибудь по подробнее, всё же тема создана новичком )
Ответить с цитированием
  #6  
Старый 16.04.2013, 16:43
xbron xbron вне форума
Прохожий
 
Регистрация: 15.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Если добавление из БД, соответсвенно, регистр будет одинаковый для любой попытки, то можно так:
Код:
procedure AddItemToListBox(AListBox : TListBox; AItem : String);
begin
  If AListBox.Items.IndexOf(AItem) = -1
    Then AListBox.Items.Add(AItem)
    Else
      If MessageDlg('Элемент уже есть. Добавляем?',mtConfirmation,[mbYes,mbNo],0) = mrYes 
       Then AListBox.Items.Add(AItem);
end;

Если надо проверять без учета регистра, то можно сделать свою функцию IndexOf, например:
Код:
function IndexOfText(AList : TStringList; AStr : String) : Integer;
var
  I : Integer;
begin
  Result := -1;
  For I := 0 To AList.Count-1 Do
    If AnsiCompareText(AList[i],AStr) = 0 Then
      Begin
        Result := I;
        Break;
      End;
end;
О каких регистров идёт речь? ) Простите , но я начинающий и для меня это что-то новое )
Ответить с цитированием
  #7  
Старый 16.04.2013, 17:25
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Цитата:
Сообщение от xbron
Можно как-нибудь по подробнее, всё же тема создана новичком )
Все довольно просто. В конструкции for задаются границы определяющие значение счетчика на каждой цикле. В вашем случае:
Код:
for i:=1 to listbox1.Items.Count-1 do
(Кстати, с границами вы тоже наврали. Элементы в listbox1 начинаются с 0, а не с 1.)
Так вот, for вычисялет значение для правой границы только один раз, при входе в цикл. Т.е. если у вас при входе в цикл было 10 элементов в listbox1.Items.Count, то 10 раз он и будет выполнятся, независимо от того что вы будете делать внутри цикла с listbox1. И если в результате удаления элементов из listbox1 у вас их станет меньше 10, то вы получите ошибку выхода за границы. Но! Если цикл работает в обратную сторону, т.е:
Код:
for i:=listbox1.Items.Count-1 downto 0 do
то тут уже ничего страшного не произойдети если вы удалите текущий элемент, ведь на следующем проходе он будет двигаться к началу, и никакой ошибки выхода за границы быть уже не может.

Надеюсь теперь понятно.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #8  
Старый 16.04.2013, 17:45
xbron xbron вне форума
Прохожий
 
Регистрация: 15.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Страдалецъ
Все довольно просто. В конструкции for задаются границы определяющие значение счетчика на каждой цикле. В вашем случае:
Код:
for i:=1 to listbox1.Items.Count-1 do
(Кстати, с границами вы тоже наврали. Элементы в listbox1 начинаются с 0, а не с 1.)
Так вот, for вычисялет значение для правой границы только один раз, при входе в цикл. Т.е. если у вас при входе в цикл было 10 элементов в listbox1.Items.Count, то 10 раз он и будет выполнятся, независимо от того что вы будете делать внутри цикла с listbox1. И если в результате удаления элементов из listbox1 у вас их станет меньше 10, то вы получите ошибку выхода за границы. Но! Если цикл работает в обратную сторону, т.е:
Код:
for i:=listbox1.Items.Count-1 downto 0 do
то тут уже ничего страшного не произойдети если вы удалите текущий элемент, ведь на следующем проходе он будет двигаться к началу, и никакой ошибки выхода за границы быть уже не может.

Надеюсь теперь понятно.
Теперь да, но задача-то не решена )) Всё равно не проверяет на повторения ((
И кое-что ,
Код:
 f:=listbox1.Items.IndexOf(listbox1.Items.strings[i]);
F принимает значения от 0 до 2, но никак не -1, если существует повторение , что не так?

Последний раз редактировалось xbron, 16.04.2013 в 17:50.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:41.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter