![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Зацените дурацкое решение [D6, IB6.x]
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 позиция должна сохраняться. Я тоже много изобретал, и такой способ ка ты использовал, но в конце концов пришел к иерархическому хранению, как ты говоришь, линейного множества.
Работало все четко и красиво.