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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.03.2017, 11:47   #1  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Как по объекту 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());
    }
Смысл в том, что мне надо воссоздать запрос, который бы возвращал все строки заказов в зависимости от наложенного фильтра на заголовки заказов. И эту задачу надо решить не только для заказов, а для любой формы ListPage.
Старый 27.03.2017, 12:09   #2  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Метод 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  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
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)))
Как видно, отсуствует окончание AND ((SalesId = N'ЗК000000094' OR SalesId = N'ЗК000000091'))
То есть, в АХ2012 пользовательские фильтры можно получить только через localQuery.queryFilter(i)

Последний раз редактировалось Ace of Database; 27.03.2017 в 12:21.
Старый 27.03.2017, 12:31   #4  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Стоп! метод localQuery.datasourceNo(1).toString() в AX2012 генерирует такой же текст как и в AX 2009, мой третий пост неправильный.
Но главное вот что: метод localQuery.dataSourceNo(1).range(i) не показывает пользовательские фильтры в AX2012, а метод localQuery.queryFilter(i) работает только в том случае, если текущий FormRun ссылается на заголовки заказов.
Мне надо получить пользовательские фильтры для случая, когда текущий FormRun - строки заказов.
Старый 27.03.2017, 12:38   #5  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Вот такой код в 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  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Еще отредактировал мой второй пост.
Подведу итоги этой вакханалии:
1) localQuery.queryFilter(i) не показывает пользовательские фильтры, наложенные на заголовки заказов, если текущий FormRun получен из строк заказов. Для этого надо каким-то образом получить часть формы SalesTableListPage, которая отображает заголовки заказов.
2) localQuery.dataSourceNo(1).range(i) не показывает пользовательские фильтры, но я бы мог обойтись и пунктом 1).
Старый 27.03.2017, 13:33   #7  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Думаю, что можно примерно так :

1. Определяем является ли текущий объект FormRun Part'ом формы, код можно смотреть вот тут Refreshing form parts

2. Если это part, то через вызов formRun().args().caller() получаем основной экземпляр объекта формы типа ListPage
__________________
Sergey Nefedov
За это сообщение автора поблагодарили: Ace of Database (10).
Старый 27.03.2017, 14:25   #8  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Спасибо! Вы решили мою задачу.
Получается, что дочерние части формы связаны с родителькой частью через 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  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
873 / 649 (23) +++++++
Регистрация: 14.10.2004
Вот так получается универсально получить пользовательские фильтры из родительской части формы. Исключаются "случайные связи", если форма просто была вызвана из другой формы, для которой она не является частью.

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).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Формы типа ListPage Artikov DAX: Программирование 1 14.06.2016 16:21
как узнать имя открываемый формы???? Didar DAX: Программирование 4 24.01.2008 19:23
как узнать имя открываемый формы???? Daido DAX: Программирование 9 02.08.2007 17:20
Передача ссылки на формы через SysInfoAction_FormRun Artem Mikhailov DAX: Программирование 3 12.01.2007 07:17
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

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

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

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