|
09.07.2008, 19:40 | #1 |
Модератор
|
Обновление DataSource из формы Печать\Новый отчет.
Есть интересный вопрос, как и откуда этот вопрос появился.. надеюсь обсуждать не будем. Чтоб время не тратить.
Есть Управление запасами \ Журналы \ Складские проводки\ Проводка У этой форму есть DataSource InventJournalTable его как раз и надо обновить (текущую строку перечитать с БД) Обновление должно происходить после изменения поля формы, которое редактируется в форме вызванной с отчета Печать \ Новый Отчет. На форме отчета есть кнопка которая и вызывает дополнительную форму. A форме редактирую значение, и по нажатию Ок происходит измение в строке журнала в таблице InventJournalTable. Таблица то обновилась, а чтоб увидеть новое значение в форме журнала Проводка, приходится переоткрывать форму журнала Проводки. Как сделать так чтоб по нажатию Ок строка DataSource InventJournalTable обновлялась? |
|
09.07.2008, 20:23 | #2 |
Участник
|
После выполнения ваших действий в отчете(хотя что это за отчет, который меняет данные) делайте следующее
X++: currentCursor = InventJournalTable_ds.cursor(); InventJournalTable_ds.research(); InventJournalTable_ds.findRecord(currentCursor); |
|
|
За это сообщение автора поблагодарили: alex55 (1). |
10.07.2008, 08:55 | #3 |
Участник
|
Если нужно обновить только одну запись, то лучше сделать так:
X++: InventJournalTable_ds.reread(); InventJournalTable_ds.refresh(); |
|
10.07.2008, 09:57 | #4 |
Участник
|
Если нужно это выполнять из вашего RunBase, а не в методе clicked формы вызова (например, обновление нужно только если нажата ОК, а не Отмена), то можно выполнить что-то подобное в методе main:
X++: static void main(Args _args) { FormDataSource fdsCaller; ... if (importEngenie.prompt()) { importEngenie.run(); if (_args && _args.dataset() && _args.record().dataSource()) { fdsCaller = _args.record().dataSource(); fdsCaller.reread(); fdsCaller.refresh(); } } } |
|
|
За это сообщение автора поблагодарили: Poleax (1). |
12.04.2011, 10:35 | #5 |
MCP
|
[QUOTE=Raven Melancholic;171974]Если нужно это выполнять из вашего RunBase, а не в методе clicked формы вызова (например, обновление нужно только если нажата ОК, а не Отмена), то можно выполнить что-то подобное в методе main:
Хороший способ, но тогда придется искать запись на которой стоял курсор предложенными выше способами. Иногда это долго. Предлагаю так: X++: static void main(Args _args) { FormDataSource fdsCaller; InventJournalTable InventJournalTable; ... if (importEngenie.prompt()) { importEngenie.run(); if (_args && _args.record() && _args.record().tableId == tablenum(InventJournalTable)) { InventJournalTable = _args.record(); if(InventJournalTable.isFormDataSource()) { fdsCaller = InventJournalTable.dataSource(); fdsCaller.reread(); fdsCaller.activate(); // Тогда запись перечитается и курсор не слетит с текущей записи в гриде } } } } Последний раз редактировалось kornix; 12.04.2011 в 10:40. |
|
10.07.2008, 09:58 | #6 |
SAP
|
Цитата:
В отличие от варианта, предложенного _scorp_, данный код вызовет обновление не всего датасорса, а только текущей записи.
Второй вариант подходит когда происходит изменение во многих строках, их необходимо обновить и спозицианировать курсор на нужной записи |
|
10.07.2008, 10:57 | #7 |
Модератор
|
Наверно вы немного не поняли суть вопроса. Команду обновления dataSource я знаю.
А вот как до него добраться из 3 формы. ;-) 1 форма - складской журнал Проводка 2 форма (создается классом) - сам отчет. 3 форма Таблица со значениями и сопоставлением должностей. в 3 форме при нажатии Ок (cliked) нахожу нужное значение из всех введенных если такое есть я в InventJournalTable обновляю одно поле, если нет выхожу. Так получается при нажатии в 3 форме Ок и должен вызываться обновление строки на форме складского журнала Проводка. Сейчас подумаю над предложением Raven Melancholic думаю смотреть надо в сторону _args.record().dataSource(); |
|
10.07.2008, 11:35 | #8 |
SAP
|
Цитата:
А вот как до него добраться из 3 формы. ;-)
|
|
10.07.2008, 11:49 | #9 |
Модератор
|
Спасибо вопрос закрыт.
помог совет Raven Melancholic _args.record().dataSource(); и т.д. |
|
11.04.2011, 20:17 | #10 |
Участник
|
Подобная задача, только проще: как обновить DataSource из самой формы
Имею связанные по InnerJoin датасорсы и общий грид на них. По обычной Button вызывается (в Clicked()) обработка, меняющая значения в нескольких записях в подчиненной таблице. Хочу увидеть их обновленными в гриде. Если делаю: X++: _ds.reread(); _ds.refresh(); Если добавляю к этому X++: _ds.refreshEx(); Если делаю X++: _ds.executeQuery(); Если делаю, как написано в это теме: X++: anytype currentCursor; currentCursor = _ds.cursor(); // обработка... _ds.research(); _ds.findRecord(currentCursor); С подчиненным датасорсом тоже всё это пробовал - вообще ничего не обновляется. Никак не удается обновить записи и при этом остаться на текущей |
|
12.04.2011, 09:25 | #11 |
Участник
|
Какая версия AX? Если 2009, то у метода FormDataSource.research() появился булевый параметр _retainPosition, который позволяет сохранить позицию при обновлении данных формы.
Если версия более ранняя, то вроде так должно сработать: X++: Common common;
common.data();
// обработка...
_ds.research();
_ds.findRecord(common); X++: anytype uniqueValue; uniqueValue = x.UniqueField; // обработка... _ds.research(); _ds.findValue(fieldnum(X, UniqueField), SysQuery::value(uniqueValue)); Еще можно использовать element.args().lookupField() и element.args().lookupValue(): X++: anytype uniqueValue; uniqueValue = x.UniqueField; // обработка... element.args().lookupField(fieldnum(X, UniqueField)); element.args().lookupValue(SysQuery::value(uniqueValue)); _ds.research(); |
|
|
За это сообщение автора поблагодарили: Poleax (1), Geo (2), jeky (1). |
12.04.2011, 18:56 | #12 |
Участник
|
|
|
12.04.2011, 19:06 | #13 |
Участник
|
Здесь же спрошу, поскольку было в примере.
Есть ли какая-то разница между SysQuery::value() и queryValue() ? |
|
13.04.2011, 09:28 | #14 |
Участник
|
Цитата:
\Classes\Global\queryValue: X++: static str queryValue(anytype A) { return SysQuery::value(a); } |
|
12.04.2011, 11:37 | #15 |
Участник
|
А просто ххх_ds.active() не поможет?
__________________
Ivanhoe as is.. |
|
12.04.2011, 13:01 | #16 |
MCP
|
|
|
12.04.2011, 22:20 | #17 |
Участник
|
Не знаю, актуально ли еще, но чтобы не изобретать велосипеды с ds.reread()/refresh(), локализаторы в 2009-й сделали в Global метод dsRefresh_RU(). При необходимости его можно допилить под собственные нужды, главное, что его вызов намного компактнее, чем copy-paste кусков кода, которые непосредственно работают с FormDataSource.
|
|
|
За это сообщение автора поблагодарили: kornix (1). |
12.04.2011, 22:37 | #18 |
Участник
|
|
|
12.04.2011, 23:22 | #19 |
Участник
|
X++: static void dsRefresh_RU(Common _record, DSRefreshAction_RU _action = DSRefreshAction_RU::RereadRefresh, NoYes _retainPosition = NoYes::Yes, NoYes _forceActive = NoYes::Yes) { FormDataSource formDataSource = _record.dataSource(); FormDataSource parentDataSource = formDataSource; Common retainPositionRecord; void refresh() { switch (_action) { case DSRefreshAction_RU::RereadRefresh: parentDataSource.reread(); parentDataSource.refresh(); break; case DSRefreshAction_RU::Research: parentDataSource.research(); break; case DSRefreshAction_RU::ExecuteQuery: if (_retainPosition) { retainPositionRecord = parentDataSource.cursor().data(); } parentDataSource.executeQuery(); if (_retainPosition) { parentDataSource.findRecord(retainPositionRecord); } break; } if (_forceActive) { parentDataSource.active(); } } ; if (formDataSource) { refresh(); while (parentDataSource.joinSource() && parentDataSource.linkType() == FormLinkType::InnerJoin) { parentDataSource = formGetParentDatasource(parentDataSource); refresh(); } } } |
|
|
За это сообщение автора поблагодарили: Molchun (1), kpoxa (1). |
13.04.2011, 04:02 | #20 |
Участник
|
Спасибо.
|
|
|
|