13.02.2013, 11:16 | #1 |
Участник
|
Странное поведение метода last в источнике данных формы
Добрый день!
Вопрос такой: в чем может быть причина того, что при выполнении insert'а в таблицу и последующего вызова метода last для установки курсора на последнюю добавленную запись происходит ВСТАВКА ЕЩЕ ОДНОЙ ТАКОЙ ЖЕ ЗАПИСИ В ТАБЛИЦУ? Код X++: ... if (!_flightScheduleRow) { _nVAOMAFlightSchedule_new.insert(); _flightScheduleRow = _nVAOMAFlightSchedule_new.RecId; //Выводим в форму, то шо получилось NVAOMAFlightScheduleDS_DS.last(); //NVAOMAFlightScheduleDS_DS.prev(); } ... Если вызов этого метода убрать, то ЗАПИСЬ ДОБАВЛЯЕТСЯ ПРИ ЗАКРЫТИИ ФОРМЫ! Объясните, в чем тут магия? |
|
13.02.2013, 11:18 | #2 |
Участник
|
Метод last нигде не перекрыт(датасоурс,форма, грид)?
Последний раз редактировалось user_ax; 13.02.2013 в 11:22. |
|
13.02.2013, 11:24 | #3 |
Участник
|
Неа, точно нет, нигде не перекрыт
Причем такая еще особеность: данной код является частью кода обработчика события modified для контрола, которому назначен датасорс и датафилд, разумеется. И такая фигня происходит. А если перенести этот код, скажем, чтоб работал по нажатию кнопки - такой проблемы нет... Контрол, для которого сейчас выполняется сей код - это стрингЭдит с выпадающим списком. В свою очередь, физически, датафилд данного контрола является внешним ключом таблицы. Вывод этой таблицы (набор столбцов) определен через группу AutoLookup. Может поможет, скорее всего дело в этом Последний раз редактировалось Vasiliusis; 13.02.2013 в 11:39. |
|
13.02.2013, 11:38 | #4 |
Участник
|
А этот самый контрол, на котором вы перекрыли modified() не привязан к датасорсу, на котором вы вызываете last()?
|
|
13.02.2013, 11:41 | #5 |
Участник
|
|
|
13.02.2013, 11:50 | #6 |
Участник
|
|
|
13.02.2013, 11:52 | #7 |
Участник
|
|
|
13.02.2013, 12:38 | #8 |
Участник
|
В общем, товарищи, я вообще ума не приложу, в чем дело, но при добавлении вызова NVAOMAFlightScheduleDS.clear(); перед вызовом NVAOMAFlightScheduleDS_DS.last(); начало пахать.
Итого: X++: ... if (!_flightScheduleRow) { ttsbegin; _nVAOMAFlightSchedule_new.insert(); ttscommit; _flightScheduleRow = _nVAOMAFlightSchedule_new.RecId; //Выводим в форму, то шо получилось NVAOMAFlightScheduleDS.clear(); //<---------------- вот он, спаситель! :) NVAOMAFlightScheduleDS_DS.last(); //NVAOMAFlightScheduleDS_DS.prev(); //delete_from _nVAOMAFlightSchedule_new //where _nVAOMAFlightSchedule_new.RecId == _flightScheduleRow+1; } ... |
|
13.02.2013, 12:40 | #9 |
Участник
|
Я так думаю, что имеет место где-то в датасорсе некий буфер, который хранит либо данные, либо саму команду, либо и то и другое, и при вызове last, а также при закрытии формы он выполняет команду и этот буфер сбрасывает... чортишто
|
|
13.02.2013, 13:40 | #10 |
Участник
|
Т.е. вы сразу как только, пользователь изменил значение поля на форме (изменения произошли только на форме, не в БД), производите вставку новой записи в таблицу и ещё на форме прерываете процесс редактирования пользователем записи и переводите курсор на другую... По идее при потере курсора редактируемая запись должна будет сохраниться, но что если сохранение(метод write) проведённых изменений по каки-либо причинам не отработает? Что будет с целостностью данных?
|
|
13.02.2013, 14:48 | #11 |
Участник
|
Цитата:
В форме, точнее в объекте формы, сохраняется айдишник записи. Гридов на этой форме нет. Одно открытие формы - работа только с одной записью. Т.к. запись одна, то соответственно все манипуляции в форме отражаются только в ней одной, т.к. позиция записи в ДС не меняется. Кроме этого, если будут возникать эксепшены - я отслежу почему и устраню, а так - многие данные выбираются из связанных таблиц, следовательно, целостность данных не пострадает. Если я Вас правильно понял. |
|
13.02.2013, 15:12 | #12 |
Участник
|
Вместо last() используйте reread()/refresh().
Не понимаю, зачем вы это делаете?
__________________
// no comments |
|
14.02.2013, 05:51 | #13 |
Участник
|
|
|
14.02.2013, 05:53 | #14 |
Участник
|
Короче, дело закрыто, всем спасибо
|
|
14.02.2013, 10:24 | #15 |
Участник
|
X++: if (!_flightScheduleRow) { _nVAOMAFlightSchedule_new.insert(); _flightScheduleRow = _nVAOMAFlightSchedule_new.RecId; //ставим курсор на созданную запись NVAOMAFlightScheduleDS_DS.research(); NVAOMAFlightScheduleDS_DS.findRecord(_nVAOMAFlightSchedule_new); } Последний раз редактировалось LeonDerCom; 14.02.2013 в 10:29. |
|
|
За это сообщение автора поблагодарили: S.Kuskov (1). |
14.02.2013, 12:13 | #16 |
Участник
|
Не работает, в БД появляется дублирующая запись. К тому же, даже невооруженным глазом видно, что этот метод работает медленнее, т.к. ... ну там много записей и много столбцов
|
|
14.02.2013, 12:34 | #17 |
Участник
|
Vasiliusis, что-то вы намудрили, по-моему.
На сколько я смог догадаться, вы делаете отдельную форму для редактирования или вставки записи в таблицу? Или нет? До сих пор не понятно почему изменение данных в БД происходит из метода modified, который для этого совсем не предназначен? |
|
14.02.2013, 12:50 | #18 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Vasiliusis, что-то вы намудрили, по-моему.
На сколько я смог догадаться, вы делаете отдельную форму для редактирования или вставки записи в таблицу? Или нет? До сих пор не понятно почему изменение данных в БД происходит из метода modified, который для этого совсем не предназначен? Почему в modified? 1. Только в методе modified я могут автоматически копировать данные из одного поля в другое, при условии, что эти поля на форме представлены стрингЭдитом с выпадающим список (допустим, А и В соответственно). Это по Вашей рекомендации. 2. Запись/перезапись в БД должна осуществляться при присваивании/изменении значения в вышеуказанном контроле А. По требованию пункта 1, я не могу этого (копирования из А в В) сделать в modified контрола А (был у меня такой пост...), то я делаю это в методах ДС. Я думаю, что нужно будет убедить нашего начальника в том, чтобы вносить данные только при нажатии кнопки сохранить перед закрытием, а то это больно накладно каждый раз выполнять тучу кода и писать в БД... Не отрицаю, возможно где-то чересчур лихо написал В конце концов, мой опыт производственной работы с аксаптой составляет не более 2-ух недель. Последний раз редактировалось Vasiliusis; 14.02.2013 в 12:59. |
|
14.02.2013, 13:02 | #19 |
Участник
|
Цитата:
Если вы хотите сохранить изменения в текущей записи, то вам нужно вызвать метод write() датасурса. И курсор после этого не нужно никуда двигать он останется на этой же обновлённой/сохранённой записи. Последний раз редактировалось S.Kuskov; 14.02.2013 в 13:04. |
|
|
За это сообщение автора поблагодарили: Vasiliusis (1). |
14.02.2013, 13:15 | #20 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Для этого совсем не нужно вручную вызывать метод insert табличного курсора, т.к. он не делает вставку или тем более обновление текущей (редактируемой) записи, а делает как раз вставку новой (ещё одной) записи - отсюда у вас и задвоение.
Если вы хотите сохранить изменения в текущей записи, то вам нужно вызвать метод write() датасурса. И курсор после этого не нужно никуда двигать он останется на этой же обновлённой/сохранённой записи. Видимо после вызова метода last(), т.к. я все-таки написал что-то в датасорс, аксапта пишет эту запись в таблицу, чтоб не потерять, а перед этим я инсертом вставляю еще одну. Вызов метода clear() удаляет, забывает просто напросто новую запись из ДС, что и решает мою проблему. Пролучается, что я создаю свою собственную запись, им удаляю ту, что создает сама аксапта, как только я присваиваю что-нибудь в какое-либо поле ДС, я так понял? Кстати, в пользу того, что акспата записывает запись, чтобы не забыть говорит и то, что при закрытии формы дублирующая запись также записывается (если метод last не вызывать) Тогда получается, что когда мы обращаемся к датасорсу в формате <название>_ds - это мы обращаемся ко всему хранилищу, а когда просто к <название> - это к текущей строке, на которую установлен курсор Последний раз редактировалось Vasiliusis; 14.02.2013 в 13:49. |
|
Теги |
волшебство, колдовство, магия |
|
|