![]() |
| ||
|
|
Новости |
Поиск |
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 предотвращает рекурсивный бесконечный вызов.
Работает очень хорошо. Но можно ли так поступать? Не слишком ли это выглядит по-идиотски? Дело в том, что я описываю пример склада в документации к своей системе и рекомендую там такой код... Использовать другие компоненты нежелательно.
Кто что может сказать?
MsGuns (2003-10-07 18:51:00) [21]
>Sandman25 © (07.10.03 18:42) [11]
Я так делал скубентом, когда лабы сдавал. А если строчек 200 (Редко, но бывает) ? А если табла - парадокс и юзается 15 челами ? А слетит на перенумерации ? Да мне совесть не позволит лепить такую лабуду.
MsGuns (2003-10-07 18:47:00) [22]
>Sandman25 © (07.10.03 18:36) [9]
>Что имеется в виду?
Запись i-я Запись i+1-я Запись новая
------------------------------------------------
23 26 24 (25)
1 2 1.9 (1.1)
1.1 1.2 1.19 (1.11)
>Vlad © (07.10.03 18:38) [10]
>Если данные хранить в таблице в иерархическом виде (т.е. ID,PARENT_ID).
Иерархия для линейного множества линейных объектов ? Речь идет о последовательности строк документа, необходимой только для визуального отображения. И больше абсолютно ни для чего !
Т.е. это самое поле Ordering не используется нигде кроме оператора ORDER BY или индекса. НИГДЕ И НИКОГДА ! Это чисто клиентская проблема. Причем здесь иерархические данные в БД ?
Sandman25 (2003-10-07 18:42:00) [23]
1. пробежаться по всем записям dataset и увеличить nomer на 1, если он больше вставляемого.
2. вставить нужную запись.
Vlad (2003-10-07 18:38:00) [24]
>MsGuns © (07.10.03 18:31) [8]
Алгоритм достаточно несложен.
Если данные хранить в таблице в иерархическом виде (т.е. ID,PARENT_ID).
Тогда, если тебе нужно вставить запись между двумя другими, достаточно в следующей записи поменять ссылку на родительскую запись.
Оракл легко позволяет работать с иерархическими таблицами, в IB c этим конечно более проблемно, но тем не менее можно.
Sandman25 (2003-10-07 18:36:00) [25]
> алгоритма определения этого самого номера по двум смежным
Что имеется в виду?
MsGuns (2003-10-07 18:31:00) [26]
1. DBNavigator - полный отстой (с месяца 2 назад я подробно описывал большинство его недостатков, главный из которых - корявость и негибкость визуализации)
2. Нельзя однозначно заменять Insert на Append, т.к. юзеру иногда надо именно вставить запись между двумя смежными. Лучше всего иметь 2 кнопки: "Новая перед", "Новая после". Или даже 3 ("Новая в конце"). Это решает все проблемы удобства интерфейса редактирования документов(выделено специально для АП)
3. Проблема последовательности записей в документе не есть такая праздная как многим представляется. Некоторые документы (к примеру, счета-фактуры) заполняются внешними контрагентами вручную и ни о какой упорядоченности по наименованию, цене и т.д. речи итти не может. Упорядоченность типа "как Маше было удобно". Но трабла в том, что частенько ее-то и надо сохранить в БД ! И я лично понимаю того юзера, который вынужден с карандашом в руках сверять электронную накладную с ее бумажным оригиналом (самому приходилось не раз, как вспомню-так вздрогну !)
Я ничего лучшего не придумал, как ввести в таблицу фактуры (к примеру) доп.поле "Ordering", в которое записываю № записи внутри курсора (фактуры). Алгоритм его определения несколько замудрен, но работает ! А вот если б кто мне показал пример эффективного алгоритма определения этого самого номера по двум смежным, я б был в большом долгу (свой алгоритм я оптимальным не считаю).
Anatoly Podgoretsky (2003-10-07 18:28:00) [27]
Может быть, ну тогда мой пост недействителен.
Sandman25 (2003-10-07 18:26:00) [28]
[5] Anatoly Podgoretsky © (07.10.03 18:25)
Наверное, в гриде нужен Append - добавление в конец, чтобы новая запись была самой нижней.
Anatoly Podgoretsky (2003-10-07 18:25:00) [29]
Johnmen © (07.10.03 18:15) [3]
А уточнить, а то я в недоумении?
Sandman25 (2003-10-07 18:20:00) [30]
Insert не является Virtual, поэтому переписать его не получится.
В данных условиях Ваше решение самое лучшее ИМХО.
Johnmen (2003-10-07 18:15:00) [31]
>Anatoly Podgoretsky © (07.10.03 18:13)
Нет, здесь дело несколько в другом...:)
Anatoly Podgoretsky (2003-10-07 18:13:00) [32]
Для большинства баз данных, нет такого понятия, как физический номер записи, исключение dBase/FoxPro
А уж для IB6 совсем нет этого понятия, при выборке непредсказуема последовательность записей (без упорядочивания) одна и таже выборка в разные моменты времени может выдать разные последовательности.
Очень плохо, что ты используешь навигационный методы, они просто тебя сбивают с толку, на самом деле на сервер будет послан запрос примерно следующего типа - INSERT INTO TABLE данные, никаких позиций и в помине нет.
Если тебе нужны позиции в накладной, то введи поле номер позиции.
Johnmen (2003-10-07 18:13:00) [33]
Пока читал пост, до кода, мне тоже пришло такое решение, т.е. подменять, где надо, инсерт на аппенд. В том же гриде можно просто обработать клаву...:) и по кл.инсерт сделать Append.
Может и в навигаторе можно перехватить нажатие (не знаю не работал с ним).
По поводу кода - думаю, нормально.
:)