27.03.2017, 11:47 | #1 |
Участник
|
Как по объекту FormRun узнать, является ли он частью формы ListPage
Привет!
AX2012 R2. На входе имеем FormRun, полученный, к примеру, из той части формы SalesTableListPage, на которой отображаются строки заказов на продажу. Вопрос: как получить FormRun, в котором отображаются заголовки заказов? При этом модифировать уже имеющиеся формы и классы нельзя. Я перехватываю метод task в классе SysSetupFormRun. В этот момент в переменной this сидит FormRun, который либо ссылается на заголовки заказов, либо на строки заказов, в зависимости от того, в каком месте была нажата клавиша. Мне надо узнать фильтр, наложенный пользователем на заголовки заказов. Это можно узнать только получив FormRun с заголовками заказов. Пользовательский фильтр я получаю так: X++: localQuery = _formDatasource.queryRun().Query(); for (i = 1; i <= localQuery.queryFilterCount(); i++) { info(localQuery.queryFilter(i).toString()); if (localQuery.queryFilter(i).dataSource().name() == qbds.name()) Query.addQueryFilter(qbds, localQuery.queryFilter(i).field()).value(localQuery.queryFilter(i).value()); } |
|
27.03.2017, 12:09 | #2 |
Участник
|
Метод range() больше не возвращает пользовательские фильтры.
Для пояснения того, что мне надо вот пример. _callerFormRun - это объект this в классе SysSetupFormRun. Пример выводит в инфолог две строки. В первой строке выводится запрос. Во второй строке выводятся заданные пользователем фильтры. Отредактировано: заданные пользователем фильтры попадают в первую строку моего примера, но их нельзя получить через объект localQuery.dataSourceNo(1).range(i). Теперь их можно получить только через метод queryFilter. Если приведенный мною метод вызван из шапки заказов, то в инфолог выводятся пользовательские фильтры. Если метод вызван из строк заказа - то в инфолог не выводится заданные пользователями фильтры. X++: void new(FormRun _callerFormRun) //_callerFormRun - это объект this в классе SysSetupFormRun { Query localQuery; FormDatasource formDatasource; int i; ; formDatasource = _callerFormRun.dataSource(1); localQuery = formDatasource.queryRun().Query(); info(localQuery.datasourceNo(1).toString()); //отредактировано: вот эта строка показывает заданные пользователем фильтры только если _callerFormRun ссылается на заголовки заказов for (i = 1; i <= localQuery.queryFilterCount(); i++) { info(localQuery.queryFilter(i).toString()); //вот эта строка показывает фильтры только если _callerFormRun ссылается на заголовки заказов } } Последний раз редактировалось Ace of Database; 27.03.2017 в 12:46. |
|
27.03.2017, 12:19 | #3 |
Участник
|
AX2009 в методе localQuery.datasourceNo(1).toString() генерирует вот такой текст
X++: SELECT * FROM SalesTable USING INDEX SalesIdx WHERE ((NOT (ReturnStatus = 4) AND NOT (ReturnStatus = 1))) AND ((SalesId = N'ЗК000000094' OR SalesId = N'ЗК000000091')) AX2012 в методе localQuery.datasourceNo(1).toString() генерирует вот такой текст X++: SELECT * FROM SalesTable USING INDEX SalesIdx WHERE ((NOT (ReturnStatus = 4) AND NOT (ReturnStatus = 1))) То есть, в АХ2012 пользовательские фильтры можно получить только через localQuery.queryFilter(i) Последний раз редактировалось Ace of Database; 27.03.2017 в 12:21. |
|
27.03.2017, 12:31 | #4 |
Участник
|
Стоп! метод localQuery.datasourceNo(1).toString() в AX2012 генерирует такой же текст как и в AX 2009, мой третий пост неправильный.
Но главное вот что: метод localQuery.dataSourceNo(1).range(i) не показывает пользовательские фильтры в AX2012, а метод localQuery.queryFilter(i) работает только в том случае, если текущий FormRun ссылается на заголовки заказов. Мне надо получить пользовательские фильтры для случая, когда текущий FormRun - строки заказов. |
|
27.03.2017, 12:38 | #5 |
Участник
|
Вот такой код в AX2012 выводит в инфолог две строки. В самом конце первой строки виден пользовательский фильтр WHERE ((SalesTable(SalesTable).SalesId = N'SO00011745' OR SalesId = N'SO00011746')).
1) SELECT FIRSTFAST * FROM SalesTable(SalesTable) ORDER BY SalesTable.SalesId ASC WHERE ((NOT (ReturnStatus = 4) AND NOT (ReturnStatus = 1))) OUTER JOIN Person, Person FROM HcmWorker(Ref_HcmWorker_WorkerSalesTaker_FK) ON SalesTable.WorkerSalesTaker = HcmWorker.RecId OUTER JOIN Name, RecId FROM DirPerson(Ref_DirPerson_WorkerSalesTaker_FK_DirPerson_FK) ON HcmWorker.Person = DirPerson.RecId WHERE ((SalesTable(SalesTable).SalesId = N'SO00011745' OR SalesId = N'SO00011746')) Во второй строке выводятся range, пользовательские фильтры в range не попадают. 2) !Отменено, !Создано X++: void new(FormRun _callerFormRun,) { Query localQuery; FormDatasource formDatasource; int i; ; formDatasource = _callerFormRun.dataSource(1); localQuery = formDatasource.queryRun().Query(); info(localQuery.datasourceNo(1).toString()); for (i = 1; i <= localQuery.dataSourceNo(1).rangeCount(); i++) { info(localQuery.dataSourceNo(1).range(i).value()); } } |
|
27.03.2017, 12:49 | #6 |
Участник
|
Еще отредактировал мой второй пост.
Подведу итоги этой вакханалии: 1) localQuery.queryFilter(i) не показывает пользовательские фильтры, наложенные на заголовки заказов, если текущий FormRun получен из строк заказов. Для этого надо каким-то образом получить часть формы SalesTableListPage, которая отображает заголовки заказов. 2) localQuery.dataSourceNo(1).range(i) не показывает пользовательские фильтры, но я бы мог обойтись и пунктом 1). |
|
27.03.2017, 13:33 | #7 |
Участник
|
Думаю, что можно примерно так :
1. Определяем является ли текущий объект FormRun Part'ом формы, код можно смотреть вот тут Refreshing form parts 2. Если это part, то через вызов formRun().args().caller() получаем основной экземпляр объекта формы типа ListPage
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: Ace of Database (10). |
27.03.2017, 14:25 | #8 |
Участник
|
Спасибо! Вы решили мою задачу.
Получается, что дочерние части формы связаны с родителькой частью через args.caller() Вот так можно получить пользовательские фильтры, установленные на шапках заказа, находясь в той части формы, которая относится к строкам заказов: X++: void new(FormRun _callerFormRun) { Query localQuery; FormDatasource formDatasource; int i; PartList partList; Object obj; ; partList = new PartList(_callerFormRun); if (!partList.partCount()) //если на форме нет частей, то предполагаем, что эта форма - часть родительскрй формы, которая находится в args().caller() { obj = _callerFormRun.args(); if (obj) obj = obj.caller(); //получаем родительскую форму if (obj) { formDatasource = obj.dataSource(1); localQuery = formDatasource.queryRun().Query(); info(localQuery.datasourceNo(1).toString()); //достаем запрос родительской формы for (i = 1; i <= localQuery.queryFilterCount(); i++) { info(localQuery.queryFilter(i).toString()); //достаем пользовательские фильтры из родительской формы //if (localQuery.queryFilter(i).dataSource().name() == qbds.name()) // Query.addQueryFilter(qbds, localQuery.queryFilter(i).field()).value(localQuery.queryFilter(i).value()); } } } } Последний раз редактировалось Ace of Database; 27.03.2017 в 14:27. |
|
27.03.2017, 14:57 | #9 |
Участник
|
Вот так получается универсально получить пользовательские фильтры из родительской части формы. Исключаются "случайные связи", если форма просто была вызвана из другой формы, для которой она не является частью.
X++: void new(FormRun _callerFormRun) { Query localQuery; FormDatasource formDatasource; int i; PartList partList; Object obj; boolean partExists(FormRun _formRun, str _name) { PartList partListLocal = new PartList(_formRun); FormRun part; int j; for(j = 1; j <= partListLocal.partCount(); j++) { part = partListLocal.getPartById(j); if (part && part.name() == _name) { return true; } } return false; } ; partList = new PartList(_callerFormRun); if (!partList.partCount()) //если на форме нет частей, то предполашаем, что эта форма - часть родительскрй формы, которая находится в args().caller() { obj = _callerFormRun.args(); if (obj) obj = obj.caller(); //получаем родительскую форму if (obj && (obj is FormRun)) { if (partExists(obj, _callerFormRun.name())) //проверяем, что текущая форма действительно является частью родительской формы, а не просто вызвана из другой формы { formDatasource = obj.dataSource(1); localQuery = formDatasource.queryRun().Query(); info(localQuery.datasourceNo(1).toString()); //достаем запрос родительской формы for (i = 1; i <= localQuery.queryFilterCount(); i++) { info(localQuery.queryFilter(i).toString()); //достаем пользовательские фильтры из родительской формы //if (localQuery.queryFilter(i).dataSource().name() == qbds.name()) // Query.addQueryFilter(qbds, localQuery.queryFilter(i).field()).value(localQuery.queryFilter(i).value()); } } } } } |
|
|
За это сообщение автора поблагодарили: Jorj (1). |