Удаление несколько строк в tstringgrid-баг или кривые руки?

Вопросы программирования и использования MSEide + MSEgui.

Модератор: Модераторы

Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение minoshi » 03.06.2011 19:32:22

Доброго времени суток !

Натолкнулся на забавную штуку.
По задаче - в stringgrid нужно выделить диапазон строк (через shift) и удалить их.

Делаю так (sg_ - это tstringgrid)
Код: Выделить всё
  for i := sg_.rowhigh downto 0 do   
  if sg_.datacols[0].selected[i] then
  begin
  sg_.deleterow( i );
  end;

Так вот - если выделять строки снизу вверх - то все нормально, а вот если - сверху вниз - то удаляется только нижняя выделенная строка.

В стрингриде включены следующие опции :
Код: Выделить всё
sg_.datacols.options = [co_readonly,co_focusselect,co_mouseselect,co_keyselect,co_multiselect,
co_resetselectonexit,co_rowselect,co_savevalue,co_savestate,co_mousescrollrow]

sg_.optionsgrid = [og_colsizing,og_focuscellonenter,og_colchangeontabkey,og_wrapcol,og_autopopup,og_mousescrollcol]


баг или кривые руки?
Аватара пользователя
minoshi
постоялец
 
Сообщения: 279
Зарегистрирован: 17.05.2008 21:23:38

Re: Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение скалогрыз » 04.06.2011 04:40:50

кривые руки

проблема даже не в tstringgrid, а в особенностях цикла for (за что он так люто ненавидим сишниками им подобным!).

Почему нельзя чистить TStringList (TList, TListView и т.д. т.п) "сверху вниз":
1) цикл for определяет количество операций только один раз, - перед первой итерацией цикла.
2) цикл for изменяет счётчик цикла самостоятельно, и руками менять его запрещает. Т.е. при удалении сверху в низ, при удалении одного из элементов, все "ниже расположенные" элементы сдвигаются на один шаг вверх. Что приведёт к тому, что "следующий" элемент будет пропущен...
3)...не говоря о выходе за пределы Tstinglist
4) Философский вопрос: при очистке, важен ли порядок очищаемых элементов? и нахрен этим заморачиваться?

хотел подробнее описать, с картинками... но я думаю, тут найдутся добрые люди.

очистка "сверху вниз" хорошо работает при таком использовании:
Код: Выделить всё
var
  t : TList;
  i : Integer;
begin
  for i:=0 to t.Count-1 do
   if del(i) then t[i]:=nil;
  t.pack;//причём на Delphi это НЕ эффективно!
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение minoshi » 04.06.2011 09:35:59

to скалогрыз За теорию спасибо- освежили память, но Вы не вчитались в мой первый пост :

удаление строк в стринггрид я произвожу снизу вверх
Код: Выделить всё
for i := sg_.rowhigh downto 0 do   


Проблема вся в том, в каком порядке выделять строки (щелкнули на первую строку для удаления - зажали shift - щелкнули на последнюю строку) для удаления в самом стринггриде - сверху вниз или снизу вверх ...

Добавлено спустя 23 минуты 12 секунд:
хотя выделенные строки - это же тоже какой-то массив, надо покапать в этом направлении ...
Аватара пользователя
minoshi
постоялец
 
Сообщения: 279
Зарегистрирован: 17.05.2008 21:23:38

Re: Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение vada » 06.06.2011 10:56:59

В каком порядке выделены стоки действительно проблема. Если вы поелозите дебагером примерно в таком коде
Код: Выделить всё
var
  R: TGridRect;
  Row1, Row1: Longint;
begin
  R := StringGrid1.Selection;
  Row1 := R.Top;
  Row2 := R.Bottom;
.........

то у вас окажется, в зависимости от того как вы выделяли строки, значения row1 и row2 не всегда удовлетворяют условию row2 >= row1. Бывает и наоборот row1 >= row2.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение minoshi » 07.06.2011 08:59:28

Так и неразобрался пока .... :(

Как "костыльное" решение - пройтись по стринггриду и номера выделенных ячеек записать в динамический массив. А потом пройтись по этому массиву снизу вверх и удалить строки из стринггрида согласно записанных в массив номерам.
Но это еще терпимо, если строк не слишком много, а я хрен его знает, сколько пользователь создаст строк с стринггриде...
Аватара пользователя
minoshi
постоялец
 
Сообщения: 279
Зарегистрирован: 17.05.2008 21:23:38

Re: Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение vada » 07.06.2011 10:01:14

Я строки из стринггрида не удаляю. Удаляю только содержание. Считываю все значения, например, в лист. (А можно и не считывать значения из выделенного блока.) Удаляю от туда ненужное. Вычишаю грид от мусора. Что осталось в листе назад в стринггрид. Хотя, если вы решили ячейки грида удалить, можно и цикл for в обратную сторону downto делать. Только сначала разобраться надо, какая строка в выделенном блоке первая, какая последняя.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Удаление несколько строк в tstringgrid-баг или кривые руки?

Сообщение debi12345 » 07.06.2011 17:48:19

Есть о чем рапортовать Мартину ?

ПС:
Удаление из последовательностей (гридов, выборок и т.п) иногда содержит логические "подводные камни" - лично я при удалении строк предпочитаю действовать от обратного - сразу иду в конец (EOF) и удаляю вверх начиная от последней - тогда изменение количества строк после удаления текущей строки не сбивает номер следующей обрабатываемой строки.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5752
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)


Вернуться в MSEide + MSEgui

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru