AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.02.2013, 11:16   #1  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Странное поведение метода last в источнике данных формы
Добрый день!

Вопрос такой: в чем может быть причина того, что при выполнении insert'а в таблицу и последующего вызова метода last для установки курсора на последнюю добавленную запись происходит ВСТАВКА ЕЩЕ ОДНОЙ ТАКОЙ ЖЕ ЗАПИСИ В ТАБЛИЦУ?

Код
X++:
...

if (!_flightScheduleRow)
    {
        _nVAOMAFlightSchedule_new.insert();
        _flightScheduleRow = _nVAOMAFlightSchedule_new.RecId;

        //Выводим в форму, то шо получилось
        NVAOMAFlightScheduleDS_DS.last();
        //NVAOMAFlightScheduleDS_DS.prev();
    }

...
В результате, после выполнения метода OMAFlightScheduleDS_DS.last(); в таблицу добавляется еще одна запись...
Если вызов этого метода убрать, то ЗАПИСЬ ДОБАВЛЯЕТСЯ ПРИ ЗАКРЫТИИ ФОРМЫ!

Объясните, в чем тут магия?
Старый 13.02.2013, 11:18   #2  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Метод last нигде не перекрыт(датасоурс,форма, грид)?

Последний раз редактировалось user_ax; 13.02.2013 в 11:22.
Старый 13.02.2013, 11:24   #3  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от user_ax Посмотреть сообщение
Метод last нигде не перекрыт?
Неа, точно нет, нигде не перекрыт

Причем такая еще особеность: данной код является частью кода обработчика события modified для контрола, которому назначен датасорс и датафилд, разумеется. И такая фигня происходит. А если перенести этот код, скажем, чтоб работал по нажатию кнопки - такой проблемы нет...

Контрол, для которого сейчас выполняется сей код - это стрингЭдит с выпадающим списком. В свою очередь, физически, датафилд данного контрола является внешним ключом таблицы. Вывод этой таблицы (набор столбцов) определен через группу AutoLookup. Может поможет, скорее всего дело в этом

Последний раз редактировалось Vasiliusis; 13.02.2013 в 11:39.
Старый 13.02.2013, 11:38   #4  
Xardas is offline
Xardas
Участник
 
28 / 13 (1) ++
Регистрация: 19.09.2012
А этот самый контрол, на котором вы перекрыли modified() не привязан к датасорсу, на котором вы вызываете last()?
Старый 13.02.2013, 11:41   #5  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от Xardas Посмотреть сообщение
А этот самый контрол, на котором вы перекрыли modified() не привязан к датасорсу, на котором вы вызываете last()?
Да, к датасорсу привязан, но modified перекрыт не на контроле, а на поле датасорса. вот
Старый 13.02.2013, 11:50   #6  
Xardas is offline
Xardas
Участник
 
28 / 13 (1) ++
Регистрация: 19.09.2012
Цитата:
Сообщение от Vasiliusis Посмотреть сообщение
Да, к датасорсу привязан, но modified перекрыт не на контроле, а на поле датасорса. вот
Возможно, это и есть причина. Поставьте точку останова внутри метода modified() и посмотрите, сколько раз он вызывается.
Старый 13.02.2013, 11:52   #7  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от Xardas Посмотреть сообщение
Возможно, это и есть причина. Поставьте точку останова внутри метода modified() и посмотрите, сколько раз он вызывается.
А тут самое интересное: я эту ситуацию уже обработал. Да, как-бы-рекурсия происходит, но я ее уже решил методом научного самотыка
Старый 13.02.2013, 12:38   #8  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
В общем, товарищи, я вообще ума не приложу, в чем дело, но при добавлении вызова 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  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Я так думаю, что имеет место где-то в датасорсе некий буфер, который хранит либо данные, либо саму команду, либо и то и другое, и при вызове last, а также при закрытии формы он выполняет команду и этот буфер сбрасывает... чортишто
Старый 13.02.2013, 13:40   #10  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Vasiliusis Посмотреть сообщение
данной код является частью кода обработчика события modified для контрола
Т.е. вы сразу как только, пользователь изменил значение поля на форме (изменения произошли только на форме, не в БД), производите вставку новой записи в таблицу и ещё на форме прерываете процесс редактирования пользователем записи и переводите курсор на другую... По идее при потере курсора редактируемая запись должна будет сохраниться, но что если сохранение(метод write) проведённых изменений по каки-либо причинам не отработает? Что будет с целостностью данных?
Старый 13.02.2013, 14:48   #11  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Т.е. вы сразу как только, пользователь изменил значение поля на форме (изменения произошли только на форме, не в БД), производите вставку новой записи в таблицу и ещё на форме прерываете процесс редактирования пользователем записи и переводите курсор на другую...
Эммм... пользователь меняет значение на форме, я пишу новое значение в БД (создаю, если контрол устанавливается впервые, либо редактирую, если наоборот). Далее, курсор переводится на новую запись, либо на отредактированную и данные отображаются в связанных с ДС контролах.

Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
По идее при потере курсора редактируемая запись должна будет сохраниться, но что если сохранение(метод write) проведённых изменений по каки-либо причинам не отработает? Что будет с целостностью данных?
В форме, точнее в объекте формы, сохраняется айдишник записи. Гридов на этой форме нет. Одно открытие формы - работа только с одной записью. Т.к. запись одна, то соответственно все манипуляции в форме отражаются только в ней одной, т.к. позиция записи в ДС не меняется. Кроме этого, если будут возникать эксепшены - я отслежу почему и устраню, а так - многие данные выбираются из связанных таблиц, следовательно, целостность данных не пострадает. Если я Вас правильно понял.
Старый 13.02.2013, 15:12   #12  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
643 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Вместо last() используйте reread()/refresh().
Цитата:
Сообщение от Vasiliusis Посмотреть сообщение
Эммм... пользователь меняет значение на форме, я пишу новое значение в БД (создаю, если контрол устанавливается впервые, либо редактирую, если наоборот).
Не понимаю, зачем вы это делаете?
__________________
// no comments
Старый 14.02.2013, 05:51   #13  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от dech Посмотреть сообщение
Вместо last() используйте reread()/refresh().

Не понимаю, зачем вы это делаете?
чтобы все изменения сразу сохранялись, вот для чего

рерид/рефреш не пашет, т.к. при инсерте курсор не встает на добавленную запись, а стоит на первой, проверял неоднократно
Старый 14.02.2013, 05:53   #14  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Короче, дело закрыто, всем спасибо
Старый 14.02.2013, 10:24   #15  
LeonDerCom is offline
LeonDerCom
Участник
 
45 / 20 (1) +++
Регистрация: 08.10.2012
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  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от LeonDerCom Посмотреть сообщение
X++:
if (!_flightScheduleRow)
    {
        _nVAOMAFlightSchedule_new.insert();
        _flightScheduleRow = _nVAOMAFlightSchedule_new.RecId;

        //ставим курсор на созданную запись
        NVAOMAFlightScheduleDS_DS.research();
        NVAOMAFlightScheduleDS_DS.findRecord(_nVAOMAFlightSchedule_new);
    }
Не работает, в БД появляется дублирующая запись. К тому же, даже невооруженным глазом видно, что этот метод работает медленнее, т.к. ... ну там много записей и много столбцов
Старый 14.02.2013, 12:34   #17  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Vasiliusis, что-то вы намудрили, по-моему.
На сколько я смог догадаться, вы делаете отдельную форму для редактирования или вставки записи в таблицу? Или нет?
До сих пор не понятно почему изменение данных в БД происходит из метода modified, который для этого совсем не предназначен?
Старый 14.02.2013, 12:50   #18  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Vasiliusis, что-то вы намудрили, по-моему.
На сколько я смог догадаться, вы делаете отдельную форму для редактирования или вставки записи в таблицу? Или нет?
До сих пор не понятно почему изменение данных в БД происходит из метода modified, который для этого совсем не предназначен?
Да, отдельная форма и для того и для другого. У пользователя будет только одна попытка на работу с записью, т.е.: открыл форму, ввел, отредактировал пока форму не закрыл, как только закрыл - все, жизненный цикл записи в части создание/редактирование грубо говоря завершен. Потом только через бюрократию отредактировать запись, такой режим.

Почему в modified?

1. Только в методе modified я могут автоматически копировать данные из одного поля в другое, при условии, что эти поля на форме представлены стрингЭдитом с выпадающим список (допустим, А и В соответственно). Это по Вашей рекомендации.
2. Запись/перезапись в БД должна осуществляться при присваивании/изменении значения в вышеуказанном контроле А. По требованию пункта 1, я не могу этого (копирования из А в В) сделать в modified контрола А (был у меня такой пост...), то я делаю это в методах ДС.

Я думаю, что нужно будет убедить нашего начальника в том, чтобы вносить данные только при нажатии кнопки сохранить перед закрытием, а то это больно накладно каждый раз выполнять тучу кода и писать в БД...

Не отрицаю, возможно где-то чересчур лихо написал В конце концов, мой опыт производственной работы с аксаптой составляет не более 2-ух недель.

Последний раз редактировалось Vasiliusis; 14.02.2013 в 12:59.
Старый 14.02.2013, 13:02   #19  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Vasiliusis Посмотреть сообщение
Запись/перезапись в БД должна осуществляться при присваивании/изменении значения в вышеуказанном контроле.
Для этого совсем не нужно вручную вызывать метод insert табличного курсора, т.к. он не делает вставку или тем более обновление текущей (редактируемой) записи, а делает как раз вставку новой (ещё одной) записи - отсюда у вас и задвоение.

Если вы хотите сохранить изменения в текущей записи, то вам нужно вызвать метод write() датасурса.

И курсор после этого не нужно никуда двигать он останется на этой же обновлённой/сохранённой записи.

Последний раз редактировалось S.Kuskov; 14.02.2013 в 13:04.
За это сообщение автора поблагодарили: Vasiliusis (1).
Старый 14.02.2013, 13:15   #20  
Vasiliusis is offline
Vasiliusis
Участник
 
225 / 13 (1) ++
Регистрация: 30.01.2013
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Для этого совсем не нужно вручную вызывать метод insert табличного курсора, т.к. он не делает вставку или тем более обновление текущей (редактируемой) записи, а делает как раз вставку новой (ещё одной) записи - отсюда у вас и задвоение.

Если вы хотите сохранить изменения в текущей записи, то вам нужно вызвать метод write() датасурса.

И курсор после этого не нужно никуда двигать он останется на этой же обновлённой/сохранённой записи.
Где Вы были раньше Лан, я понял Вас полностью, переделаю.
Видимо после вызова метода last(), т.к. я все-таки написал что-то в датасорс, аксапта пишет эту запись в таблицу, чтоб не потерять, а перед этим я инсертом вставляю еще одну. Вызов метода clear() удаляет, забывает просто напросто новую запись из ДС, что и решает мою проблему. Пролучается, что я создаю свою собственную запись, им удаляю ту, что создает сама аксапта, как только я присваиваю что-нибудь в какое-либо поле ДС, я так понял?

Кстати, в пользу того, что акспата записывает запись, чтобы не забыть говорит и то, что при закрытии формы дублирующая запись также записывается (если метод last не вызывать)

Тогда получается, что когда мы обращаемся к датасорсу в формате <название>_ds - это мы обращаемся ко всему хранилищу, а когда просто к <название> - это к текущей строке, на которую установлен курсор

Последний раз редактировалось Vasiliusis; 14.02.2013 в 13:49.
Теги
волшебство, колдовство, магия

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Недоступность источника данных формы в display/edit-методах таблицы - баг или фича с глубоким смыслом? TasmanianDevil DAX: Программирование 10 03.08.2012 15:00
разная скорость отработки display методов на источнике данных формы wojzeh DAX: Программирование 10 05.05.2008 23:53
Странное поведение формы Создание строк vc DAX: Функционал 10 22.03.2006 10:32
Обновление данных формы из другой формы DiZ DAX: Программирование 4 14.10.2004 11:39
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:14.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.