Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Зацените дурацкое решение [D6, IB6.x]


Страницы:   1 2

kaif ©   (2003-10-07 18:01:00) 

Метод Insert наследников DataSet вставляет запись передтекущей записью в наборе. При наборе накладной пользователю привычнее вставлять запись в конец набора, то есть использовать метод Append. Тем более, что наборы в накладных бывают не столь уж обширные.
Однако компонент DBNavigator умеет делать только Insert, как впрочем и DBGrid при нажатии клавиши <Insert> именно инсертит, а не аппендит, к сожалению.
Желая использовать стандартный DBNavigator и ища приемлемое практическое решение этой проблемы я написал такой обработчик для события AfterInsert компонента IBDataSet:

var
lock_insert: boolean;

procedure TStockInForm.qryDetailAfterInsert(DataSet: TDataSet);
begin
if not lock_insert then
begin
lock_insert := True;
qryDetail.Cancel; //отменяем режим вставки
qryDetail.Append; //вставляем в конец набора
end;
lock_insert := False;
end;

Переменная lock_insert предотвращает рекурсивный бесконечный вызов.

Работает очень хорошо. Но можно ли так поступать? Не слишком ли это выглядит по-идиотски? Дело в том, что я описываю пример склада в документации к своей системе и рекомендую там такой код... Использовать другие компоненты нежелательно.

Кто что может сказать?


Sandman25   (2003-10-08 11:36:00) [1]

[32] Johnmen © (08.10.03 11:27)

Может и так. Я много об этом не думал :)


Johnmen   (2003-10-08 11:27:00) [2]

>Sandman25 © (08.10.03 11:08) [31]

Я так понимаю, что не больше 63
:)


Sandman25   (2003-10-08 11:08:00) [3]

[29] Johnmen © (08.10.03 11:04)

Наксолько я понимаю, при использовании int64 невозможно подобрать N так, чтобы можно было сделать больше чем 64 вставки подряд.


Sandman25   (2003-10-08 11:07:00) [4]

[29] Johnmen © (08.10.03 11:04)

Наксолько я понимаю, при использовании int54 невозможно подобрать N так, чтобы можно было сделать больше чем 64 вставки подряд.


Johnmen   (2003-10-08 11:04:00) [5]

>Sandman25 © (08.10.03 10:20) [26]
>И есть небольшое ограничение ...

Да у нас весь мир построен на ограничениях :)
Важно заранее опрелелиться с параметрами так, чтобы не выходить на граничные значения...


Sandman25   (2003-10-08 11:02:00) [6]

[13] MsGuns © (07.10.03 18:51)

Сначала не заметил это сообщение.

Если пользователей много, и все они редактируют один документ, то без проблем все равно не обойдется. Простейший случай - после последнего пункта двое пользователей одновременно добавляют строку. Строку второго пользователя добавлять после строки первого пользователя или до?

Если в документе 200 строк, ничего страшного - отключаем все гриды, и обработчики, и за пару миллисекунд все записи изменены.


Жук   (2003-10-08 10:24:00) [7]


> Deniz © (08.10.03 07:30) [24]

"Очень правильная постановка вопроса !"(с) :-)))


Sandman25   (2003-10-08 10:20:00) [8]

[18] MsGuns © (07.10.03 19:13)

Да нет, у меня тоже будет все нормально.

1 2 > 1.1
1.1 2 > 1.2
1.2 2 > 1.3
...
1.9 2 > 1.91

А вообще я тоже делаю как [24] Deniz © (08.10.03 07:30)
И проблем с точностью не бывает :)

Способ [19] Johnmen © (08.10.03 00:24) тоже хорош, но только если не нужно эти идентификаторы отображать для пользователя.
И есть небольшое ограничение - нельзя добавлять log(2)N записей между двумя соседними. При N=100000 нельзя добавлять больше 16 записей.


Alexandr   (2003-10-08 08:05:00) [9]

таки непонял.
Попробуйте в гриде нажать стрелку вниз на последней записи...
вот вам и визуальное добавление в конец датасета.
Другой вопрос, как быть после переоткрытия, но это изврат.


Deniz   (2003-10-08 07:30:00) [10]

Мож я не так понял, но если требуется вставить № между 1 и 2( как в примере MsGuns © (07.10.03 19:13) [18]), можно сделать чуть по другому(если конечно логика позволяет) 2-мя операциями:
update Table set
N = N + 1
where N >=2
Insert into Table(N) values (2)
Где N - № записи в документе по порядку, у меня такой алгоритм работает


Johnmen   (2003-10-08 01:24:00) [11]

>kaif © (08.10.03 01:14) [22]

>А integer всего до 2000 потянет, если только отрицательные числа не использовать.

Да. Это я погорячился ;-)

>... а есть ли такой CAST в IB

Да вроде неоткуда ему там взяться...:)
А если версия позволяет и есть желание, то можно и int64.


kaif   (2003-10-08 01:14:00) [12]

2 Johnmen © (08.10.03 01:10) [21]

Так это о счет-фактуре речь шла... Я думал, о дереве каком-то плоском и испугался. А integer всего до 2000 потянет, если только отрицательные числа не использовать. Кстати, а есть ли такой CAST в IB, чтобы типа usigned integer получился? Типа от нуля и выше и так до 4*10^9 ?


Johnmen   (2003-10-08 01:10:00) [13]

>kaif © (08.10.03 01:04) [20]

:)))

Это для примера 1 млн. Можно и 100 000.
Лично я не видел счетов-фактур на количества более 1 тыс.
Кстати, не 2000, а 4000 :)


kaif   (2003-10-08 01:04:00) [14]

2 Johnmen © (08.10.03 00:24) [19]
Ашот, если мне не изменяет память, мы с тобой давно на "ты" :)

Извини, засиделся в "Потрепаться". :)
...у меня манера в том форуме всегда использовать "Вы".

Каждая вновь добавленная запись отстоит от последней (по этому самому номеру N, где N - integer) на 1000000 (1 млн).

А что там всего 2000 новых записей намечается?
Я как бы не спорю (боюсь), но просто... интересно


Johnmen   (2003-10-08 00:24:00) [15]

>kaif ©

Ашот, если мне не изменяет память, мы с тобой давно на "ты" :)

>MsGuns © (07.10.03 18:31) [8]

> А вот если б кто мне показал пример эффективного алгоритма
>определения этого самого номера по двум смежным

Предлагаю простой, понятный и эффективный алгоритм.
Каждая вновь добавленная запись отстоит от последней (по этому самому номеру N, где N - integer) на 1000000 (1 млн). Номер вновь вставляемой = ближайшее целое среднеарифметического соседних.

>...я б был в большом долгу

Все, Серега, ты попал :))))))))))))))))))))))))

PS Все, кто хочет поспорить по поводу данного алгоритма, прошу учесть специфику данной таблицы, указанную MsGuns ©.


MsGuns   (2003-10-07 19:13:00) [16]

>Sandman25 © (07.10.03 18:55) [17]
Я с этого начинал когда-то ;)) Типа метод добавления разряда ?

Недостаток (при вставке нескольких подряд, как они (Машки) часто делают):

1 2 > 1.1
1.1 2 > 1.11
1.11 2 > 1.111
....
Через относительно небольшое кол-во вставок происходят понятные проблемы с погрешностью.

У меня так
1 2 > 1.9
1 1.9 > 1.8
...
1 1.1 > 1.09
1 1.09 > 1.08
...

Работает безотказно ! С учетом женской психологии и некоторой мамы ;))


Sandman25   (2003-10-07 18:55:00) [17]

Delta, Nomer1, Nomer2: real;
...
Delta := 10;
repeat
Delta := Delta/10;
NewNomer := Nomer1 + Delta;
until NewNomer < Nomer2;


kaif   (2003-10-07 18:53:00) [18]

2 Anatoly Podgoretsky © (07.10.03 18:13) [1]
Я знаю, как работает SQL. Проблема у меня в другом.

2 Johnmen © (07.10.03 18:13) [2]
Спасибо! Именно Ваше мнение я очень ждал услышать и рад, что Вы находите решение приемлемым.

2 MsGuns © (07.10.03 18:31) [8]
Вы совершенно правы. Последовательность записей в счетах фактурах имеет огромное значение, так как часто менеджеры по телефону, обсуждая те или иные вопросы, отыскивают позиции в портянках, длиной более 200 строк их именно по номеру позиции.
Но я пишу пример "простейшего" склада в виде примера. И мне достаточнорешить проблему с добавлением в конец. Перед посылкой строки у меня генерится первичный ключ подчиненной таблицы документа (поле N). Таким образом, так как при SELECT я запрашиваю ORDER BY N, то порядок будет всегда одинаков, как при вводе, так и при выводе. Нумерацию я делаю в вычисляемом поле просто выводя RecNo. Чтобы "дырка" не возникла в RecNo после удаления строки, переоткрываю весь набор.
Вставку в середину документа не планирую вообще. Максимум, что я использую, это перестановка соседних строк внутри документа относительно друг друга (обмен ключами N через третье состояние, равное минус N). Кстати, все это очень неплохо работает с помощью кнопочек "вверх" "вниз" в реальных приложениях. В примере я перестановку показывать не буду. И так там много сложного материала.
В общем, я чувствую, что я нашел достаточно оптимальное и не очень сложное решение. Хотя дурацкое, конечно. :)


Sandman25   (2003-10-07 18:53:00) [19]

Я так понимаю, что номер имеет тип real или BCD? Иначе бы сортировка не работала.

Сейчас я уже ухожу, а завтра попытаюсь чего-нибудь придумать.


Vlad   (2003-10-07 18:52:00) [20]

>Иерархия для линейного множества линейных объектов
Именно линейного множества.
Год назад у меня была задача показывать в гриде некие данные, причем так, чтоб пользователь мог перетаскивать мышкой строки на ту позицию, которую ему нужно. Естественно, при close/open позиция должна сохраняться. Я тоже много изобретал, и такой способ ка ты использовал, но в конце концов пришел к иерархическому хранению, как ты говоришь, линейного множества.
Работало все четко и красиво.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо