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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.09.2008, 15:34   #1  
sweeper is offline
sweeper
Участник
 
10 / 12 (1) ++
Регистрация: 17.09.2008
Как сохранить строку только при нажатии кнопки?
Как сделать так чтобы строка которая создана в гриде с Ctrl+N (и строки в других таблицах связанные с этой) , сохранялась толко если я назжимаю какуюто свою кнопку, даже если строка валидируется итд?
Старый 24.09.2008, 15:38   #2  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
salesTable_ds.write()

P.S. Вам нужно пропустить валидацию строки или сохранить ? Если сохранить, то перед salesTable_ds.write()
вызвать validateWrite()

Последний раз редактировалось DSPIC; 24.09.2008 в 15:43.
Старый 24.09.2008, 16:25   #3  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
наверное имеется ввиду что бы не сохранялось автоматически, а только если нажал кнопку. Если так то, необходимо на форму добавить параметр например isClickedButton типа boolean и далее в тех таблицах, которые вам необходимо сохранять только по нажатию кнопки, добавить условие перед super(). Например:
X++:
void write(boolean _isClickedButton = false)
{
if(_isClickedButton)
  super();
}
ну и соответственно при вызове из кнопки метода write() передать параметр.
X++:
void clicked()
{
   SalesTable_ds.write(true);
   super();
}
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем

Последний раз редактировалось lev; 24.09.2008 в 16:29.
Старый 24.09.2008, 16:46   #4  
sweeper is offline
sweeper
Участник
 
10 / 12 (1) ++
Регистрация: 17.09.2008
Lev : Спасибо за ответ. А такие подходы считаюстья нормальными или ето хак? А переопределяя методы можно добавлять параметры - не знал

А как сделать чтобы если нажать другую кнопку, то в гриде сосданная запись исчезает, или ето и будут последствия приведенного Вами кода?

Последний раз редактировалось sweeper; 24.09.2008 в 16:58.
Старый 24.09.2008, 17:03   #5  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
такой подход нормальный
что значит исчезает? удаляется?
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 24.09.2008, 17:50   #6  
sweeper is offline
sweeper
Участник
 
10 / 12 (1) ++
Регистрация: 17.09.2008
Не получается Что я сделал - в датасорце таблицы добавил метод write, как Вы дали в примере. А записи все равно остаются

Вообще же моей задачей является сделать форму в которой есть грид, записи в который можно добавлять толко через другую (детальную) форму, в которой видно все поля однои записи. Если в етой деталной форме нажать Сохранить, то форма закрывается и в гриде появляется запись, если нажать Отменить, то форма закрывается без сохранения записи.
Мне на етом форуме порекомендовали посмотреть пример SalesTable, но он настолько сложный что я не разобрался.
Старый 24.09.2008, 17:54   #7  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Так погодите, тот пример что я написал, это пример для сохранения строки по кнопке.
Что бы записи удалялись только по одной строке нужно перекрывать метод delete().
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 24.09.2008, 20:17   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,318 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от sweeper Посмотреть сообщение
Вообще же моей задачей является сделать форму в которой есть грид, записи в который можно добавлять толко через другую (детальную) форму, в которой видно все поля однои записи. Если в етой деталной форме нажать Сохранить, то форма закрывается и в гриде появляется запись, если нажать Отменить, то форма закрывается без сохранения записи.
Мне на етом форуме порекомендовали посмотреть пример SalesTable, но он настолько сложный что я не разобрался.
Дык когда Вы озвучили что вам надо сделать - так сразу нашлось и решение. Вы изначально задали только часть вопроса. Вам на него и ответили. А в целом картина проясняется только когда ясна вся задача.
Итак, открываем (в коде) форму SalesTable, как Вам порекомендовали. Для начала следует знать две вещи:
1. Best Practice рекомендует минимизировать код на форме. В стандарте это требование реализуется с помощью одного или нескольких классов, в которых размещается весь код, который "хочется" поместить на форме. Для каждого обработчика события на форме должен быть создан соответствующий метод этого "форменного" класса, который вызывается из метода формы и содержит всю обработку этого события. Это условие соблюдается однако далеко не везде - но тем не менее - при создании записи в форме SalesTable это используется.
2. Создание записи в форме вызывает метод create на датасорсе. И если не вызвать super - то создания записи не произойдет. Метод "форменного" класса - salesTableForm.create() - возвращает true, если нажата кнопка ОК в детальной форме и false - в противном случае. Поэтому в методе create формы SalesTable сделан if и super вызывается только если нажата кнопка ОК в детальной форме

Теперь - о том - как в детальной форме сохранять или не сохранять запись.
Кнопки в этой форме (SalesCreateOrder) сделаны типа CommandButton, с командой ОК или отмена. Эти команды примечательны тем, что:
1. Автоматически закрывают форму
2. При закрытии вызывают методы формы closeOk и closeCancel, а также устанавливают флажки (это тоже методы формы) closedOk и closedCancel, т.о. позволяя в коде понять - какая из кнопок нажата. Нажатие кнопки Esc эквивалентно выполнении команды Отмена, т.е. нажатию кнопки Отмена.
Поскольку любое сохранение записи в форме вызывает метод write на датасорсе формы, то на детальной форме SalesCreateOrder в методе write стоит до вызова super() проверка: если не была нажата кнопка ОК (!closedOk) - то super() не вызывать и как следствие - запись не сохранять.

Возвращаясь к форме SalesTable - хочу отметить, что (если из метода create на датасорсе SalesTable перейти в метод "форменного" класса SalesTableForm.create()) форма SalesCreateOrder вызывается во-первых из класса, что дает возможность передать в другую форму этот же экземпляр "форменного" класса, а во-вторых используется метод wait() у формы - что позволяет остановить исполнение кода до закрытия детальной формы SalesCreateOrder, после чего проверить - какая кнопка была нажата (if closedOk).

Попутно - обращаю внимание - что непосредственное сохранение записи в таблице SalesTable происходит в методе write датасорса salesTable формы SalesCreateOrder. Там не вызывается super(), а вызывается непосредственно метод insert() на таблице (почему так сделано - это отдельный вопрос), а затем (смотрим код чуть ниже) новый SalesId сохраняется в "форменном" классе SalesCreateForm (метод newSalesId), который потом "достается" уже в методе create на датасорсе SalesTable формы SalesTable (смотрим строчку SalesTable::find) и курсор на датасорсе устанавливается на свежесозданную запись (строка salesTable.data(newSalesTable)) с последующей перечиткой этой записи датасорса (строка salesTable_ds.reread()). Перечитка нужна потому, что запись физически была создана из кода (метод write формы SalesCreateOrder) и параллельно с этим - виртуально (т.е. без записи в базу) - после вызова super() в методе create формы SalesTable. Перечитка позволяет датасорсу забыть про виртуальную запись и отображать запись из базы

Вот.... Этот механизм хоть и сложный - но он показывает - как в Аксапте правильно делать тот механизм, который Вас попросили сделать.
Сложность данного механизма (в частности, использование "форменного" класса) окупается легкостью обработки кнопок на форме и если форма многофункциональная - то только так и надо делать. Все остальное (использование методов create, write, closedOk, closedCancel) являются всего лишь средствами языка программирования Х++, которые могут и не иметь аналогов в других языках программирования.

Вот такой механизм - задействован в форме SalesTable. Его весьма полезно будет осознать и претворять в жизнь дальше.
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 24.09.2008 в 20:30.
Старый 25.09.2008, 00:26   #9  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Замечу, что для предотвращения навигации по SalesTable в форме SalesCreateOrder предприняты дополнительные шаги (точнее один шаг). У SalesTable установлено в false свойство AutoQuery.
Вследствие этого, при открытии формы на сервер не уходит запрос на выборку данных и в локальном кэше датасорса ничего нет, по-этому нажатие навигационных кнопок в панели инструментов ни к чему не приводит. Кроме кнопки перехода на последнюю запись, которая отправляет на сервер запрос, в результате чего форма начинает работать на редактирование уже существующих записей.
По-моему, в данном случае необходимо перекрывать все навигационные методы на датасорсе (last(), first(), next(), prev(), prevPage(), nextPage()) и комментировать в них вызов super().

Думаю, вызов insert() вместо super() в методе write() датасорса этим и обусловлен. Если бы происходил вызов super(), то могла бы возникнуть ситуация сохранения изменений в уже существующие записи. При вызове insert() в этом случае запись не сохранится с сообщением об уже существующей
__________________
Axapta v.3.0 sp5 kr2
Старый 25.09.2008, 10:44   #10  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от AndyD Посмотреть сообщение
Замечу, что для предотвращения навигации по SalesTable в форме SalesCreateOrder предприняты дополнительные шаги (точнее один шаг). У SalesTable установлено в false свойство AutoQuery.
Вследствие этого, при открытии формы на сервер не уходит запрос на выборку данных и в локальном кэше датасорса ничего нет, по-этому нажатие навигационных кнопок в панели инструментов ни к чему не приводит. Кроме кнопки перехода на последнюю запись, которая отправляет на сервер запрос, в результате чего форма начинает работать на редактирование уже существующих записей.
По-моему, в данном случае необходимо перекрывать все навигационные методы на датасорсе (last(), first(), next(), prev(), prevPage(), nextPage()) и комментировать в них вызов super().
Наверное, лучше для таких диаложиков курсор датасоурса делать временной таблицей.
Старый 25.09.2008, 11:02   #11  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,318 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
и эта идея не нова . Она применяется мастере (Wizard), который является мастером с данными (наследник SysDefaultDataWizard). Обработкой курсора временной таблицы занимается наследник класса SysDefaultData, который по указанию программиста "сливает" содержимое этой временной таблицы в такую же таблицу, но уже в БД.

Так что - есть решения - на любой вкус и цвет
__________________
Возможно сделать все. Вопрос времени
Старый 25.09.2008, 11:15   #12  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от CDR Посмотреть сообщение
Наверное, лучше для таких диаложиков курсор датасоурса делать временной таблицей.
Можно, только все равно надо будет отключать навигацию, во избежании, так сказать.
И еще делать код по переносу из временной в постоянную таблицу
__________________
Axapta v.3.0 sp5 kr2
Старый 25.09.2008, 11:23   #13  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от sweeper Посмотреть сообщение
Как сделать так чтобы строка которая создана в гриде с Ctrl+N (и строки в других таблицах связанные с этой) , сохранялась толко если я назжимаю какуюто свою кнопку, даже если строка валидируется итд?
Можно еще на всех кнопках кроме своей выставить свойство SaveRecord = No

Правда, это слишком кропотливый способ и не гарантирует что все лазейки закроются. Например при закрытии формы по кресту - все равно будет стремиться сохранить запись.
Старый 25.09.2008, 15:22   #14  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от AndyD Посмотреть сообщение
Можно, только все равно надо будет отключать навигацию, во избежании, так сказать.
И еще делать код по переносу из временной в постоянную таблицу
Запретив создание и удаление записей в свойствах датасоурса, проблема навигации отпадет сама собой . А код по переносу данных - пара строчек.
Все-таки временная таблица, имхо, как-то по безопасней будет. Пока не нажал на красную кнопку - все действия во временном буфере, а как нажал - запись попала в базу.
А то мало ли куда пользователь может нажать во время ввода данных...
Старый 26.09.2008, 01:18   #15  
sweeper is offline
sweeper
Участник
 
10 / 12 (1) ++
Регистрация: 17.09.2008
Всем спасибо за ответы! Особенно sukhanchik-у. Попробую употребить на практике. Совсем неожидал такого бурного отклика форумчан, спасибо

Вопрос sukhanchik-у. Для редактирования уже созданной записи тоже должна открыватся детальная форма (после того как активирована какаято запись и нажата кнопка Редактировать). Для етого ещё много надо доделывать?

А способ с временными таблицами проще или нет? Меня как новичка в Ахапте ужасает что шаг налево, шаг на право и ничего не работает и потом понять где ошибка может только человек который уже успел в Ахапте натереть мозоли

Последний раз редактировалось sweeper; 26.09.2008 в 01:42.
Старый 26.09.2008, 12:15   #16  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,318 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
тут-то как раз все просто. Если в Вашей таблице есть ключевое поле с EDT, который смотрит на эту же таблицу (аналогично полю SalesId в таблице SalesTable с EDT SalesId) - то Вы просто делаете форму с тем же датасорсом. При переходе из одной формы в другую - у Вас просто свяжутся две записи по этому ID и ядро физически не позволит перейти на другую запись.

Проблема будет в другом. Аксапта в большинстве своих форм предполагает редактирование непосредственно на форме с автоматическим сохранением - так что если Вам вдруг придет в голову идея добавить кнопки Сохранить-Отмена - то гоните эту идею прочь .
Хотя - вполне можно поступить также как в форме SalesCreateOrder - перекрыть метод write на датасорсе и потом анализировать методы closedOk/closedCancel

Цитата:
Сообщение от sweeper Посмотреть сообщение
А способ с временными таблицами проще или нет?
Он другой. Его может объяснить тяжелее. Идея такова - делается форма с датасорсом. На методе init датасорса после super делается из датасорса временная табличка (MyTable_ds.cursor().setTmp()). Далее - все работает как обычно.
Но в конце надо будет из этой временной таблички - все слить в постоянную табличку (объявляется новая переменная, потом копируются все поля из временной таблички и вызывается метод insert()).
За кажущейся простотой - стоят особенности работы с временными таблицами в аксапте (нельзя терять курсор), возможное отсутствие возможности использовать существующий функционал (если он есть), и вообще сам факт использования временных таблиц. Одно дело - когда все работает стандартно с БД, другое дело - когда Аксапта должна сама создавать еще отдельный файл (пусть временный) - куда чего-то еще записывать.
Плюс - если у вас при формировании записи выделяется номер из номерной серии - то для записи во временной табличке его либо не нужно выделять, либо рисковать потерей выделенного номера (если пользователь нажмет кнопку Отмена).

Поэтому - если Вы новичок - то я бы Вам советовал бы сначала освоить первый способ. Потом - отдельно - познакомиться с особенностью работы с временными таблицами в Аксапте - а потом - сделать вывод - что проще.
В любом случае - с т.з. оценки работы программиста - лучше - когда он пишет в стиле стандартного функционала и по максимуму использует возможности уже написанного кода или поведение ядра для минимизации кода. Нет смысла за Аксапту делать insert(), лучше уж заставить работать метод write на датасорсе - так как надо. Но и палку перегибать не надо. В разобранном мною примере - как раз insert() оправдан в рамках минимизации перекрытия кол-ва методов навигации (см сообщение от AndyD)

Цитата:
Сообщение от sweeper Посмотреть сообщение
Меня как новичка в Ахапте ужасает что шаг налево, шаг на право и ничего не работает и потом понять где ошибка может только человек который уже успел в Ахапте натереть мозоли
Не забывайте - что Аксапта - не затачивалась и не будет затачиваться под среду разработки. Ее цель - это несение функционала. А как этот функционал в МС предподнесут - в открытом коде или в ядре - это уже второй вопрос.
Поэтому ряд методов в ядре слабо оттестирован, либо еще и незадокументирован - поэтому - гарантию работоспособности может дать только тот код, который уже работает в каком-то месте. Поэтому - самый лучший способ программирования в Аксапте - "посмотреть как работает там и сделать по аналогии".
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 26.09.2008 в 12:19.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
как в табличном методе "узнать" о нажатии определенной кнопки на форме Zeppelin DAX: Программирование 12 08.11.2007 20:47
Как програмно сохранить отчет в файле? 111andrei DAX: Программирование 4 17.05.2006 09:52
при построении перекрёстных ссылок выдаётся сообщение об ошибках mmmax DAX: Программирование 10 21.01.2005 12:42
как сохранить отмеченную запись на гриде ? Omeo DAX: Программирование 2 25.03.2004 12:47
Хочу видеть только итоги AKIS DAX: Функционал 1 19.08.2002 11:49

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:33.