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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.01.2011, 16:39   #1  
greench is offline
greench
Участник
Oracle
 
425 / 74 (3) ++++
Регистрация: 12.07.2007
Адрес: Киев
Группировка в лукапе
День добрый всем, не знаю проскакивала ли подобная тема, по поиску не нашел.

У контрола формы, основанного на EDT, перекрыт метод lookup. Примерный код выглядит так:
X++:
public void lookup()
{
    Query                            query = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    SysTableLookup             sysTableLookup;
    tableId                            tableId;
    fieldId                            fieldId;
    ;
    tableId        = tableNum(Table1);
    sysTableLookup = SysTableLookup::newParameters(tableId, this,false);
    fieldId         = fieldnum(Table1, Field1);
    sysTableLookup.addLookupfield(fieldId);
   
    queryBuildDataSource = query.addDataSource(tableId);

    queryBuildDataSource.addRange(fieldnum(Table1,     Field2)).value(SysQuery::value(RangeValue));
    queryBuildDataSource.addGroupByField(fieldnum(Table1,Field1));
   
    sysTableLookup.parmQuery(query);

    sysTableLookup.performFormLookup();

}
Значения Field1 в таблице, которая является источником данных для лукапа, не уникальные, поэтому по ним производится группировка. Все работает корректно. Но если мы попробуем сделать сортировку в выпадающем списке, то групппировка слетает.

Как с этим бороться, может кто подскажет?
Старый 28.01.2011, 16:48   #2  
samolalex is offline
samolalex
Участник
Аватар для samolalex
Самостоятельные клиенты AX
 
259 / 107 (4) +++++
Регистрация: 18.06.2010
Адрес: Москва
Насколько я знаю, в Axapta возможна либо группировка, либо сортировка (во всяком случае в 3-ей версии).
Если же вы хотите задать сортировку по группировочному полю, то, скорее всего, следует сделать так:
X++:
public void lookup()
{
    Query                            query = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    SysTableLookup             sysTableLookup;
    tableId                            tableId;
    fieldId                            fieldId;
    ;
    tableId        = tableNum(Table1);
    sysTableLookup = SysTableLookup::newParameters(tableId, this,false);
    fieldId         = fieldnum(Table1, Field1);
    sysTableLookup.addLookupfield(fieldId);
   
    queryBuildDataSource = query.addDataSource(tableId);

    queryBuildDataSource.addRange(fieldnum(Table1,     Field2)).value(SysQuery::value(RangeValue));
    queryBuildDataSource.orderMode(orderMode::GroupBy);
    queryBuildDataSource.addSortField(fieldnum(Table1,     Field1), sortOrder::Ascending);
   
    sysTableLookup.parmQuery(query);

    sysTableLookup.performFormLookup();

}
__________________
С уважением, Александр.

Последний раз редактировалось samolalex; 28.01.2011 в 17:02.
За это сообщение автора поблагодарили: greench (1).
Старый 28.01.2011, 17:03   #3  
greench is offline
greench
Участник
Oracle
 
425 / 74 (3) ++++
Регистрация: 12.07.2007
Адрес: Киев
Точно, спасибо.
Старый 28.01.2011, 20:44   #4  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,275 / 3476 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Небольшое замечание. Если вдруг в лукапе потом захочется вывести поля, к которым нужно применить агрегатную функцию (Sum, Count и т.д.), то можно столкнуться с неприятным моментом, когда пропадает группировка.
Связано это с тем, что в рамках оптимизации исполнения запроса выбираются не все поля, а только те, что определены в лукапе (для которых был вызван метод addLookupField).
Соответственно, выполняется следующий код (\Classes\SysTableLookup\buildSelectionList):
X++:
        for (i = 1; i <= conlen(lookupItems); i++)
        {
            [fieldId, returnItem, method] = conpeek(lookupItems, i);
            queryBuildDataSource.addSelectionField(fieldId);
        }
И тут, как несложно заметить - метод addSelectionField вызывается без агрегатных функций. Соответственно, все наши Sum-ы пропадают и по этим полям начинает работать группировка (т.е. фактически, она слетает).

Лечится это простым условием:
X++:
    if (queryBuildDataSource.orderMode() == OrderMode::OrderBy) // Ограничение числа полей актуально только для выборки без группировок    
    {
        for (i = 1; i <= conlen(lookupItems); i++)
        {
            [fieldId, returnItem, method] = conpeek(lookupItems, i);
            queryBuildDataSource.addSelectionField(fieldId);
        }
    }
после чего суммирование начинает работать нормально.

Справедливо для всех версий (3.0 - 2009 RU5)
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 29.01.2011 в 12:37.
За это сообщение автора поблагодарили: konopello (1), jonny (3), IKA (1), player (1).
Старый 15.03.2011, 16:10   #5  
vallys is offline
vallys
Developer
 
146 / 108 (0) +++++
Регистрация: 18.01.2005
Добавлю, что в этом методе (\Classes\SysTableLookup\buildSelectionList) не корректно определяется наличие методов (проявляется как пустые значения дисплэй методов в лукапе):
X++:
    // Test that all are fields (no methods)
    for (i = 1; i <= conlen(lookupItems); i++)
    {
        [fieldId, returnItem, method] = conpeek(lookupItems, i);

        if (method)
        {
            return;
        }
    }
При выполнении строки
X++:
[fieldId, returnItem, method] = conpeek(lookupItems, i);
боулевская переменная method всегда принимает значение false независимо от значений (AX 2009 RU5).
Для исправления достаточно изменить тип локальной переменной method с boolean на str.

Последний раз редактировалось vallys; 15.03.2011 в 16:12.
Старый 05.04.2016, 17:53   #6  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
Цитата:
Сообщение от vallys Посмотреть сообщение
Добавлю, что в этом методе (\Classes\SysTableLookup\buildSelectionList) не корректно определяется наличие методов (проявляется как пустые значения дисплэй методов в лукапе):
X++:
    // Test that all are fields (no methods)
    for (i = 1; i <= conlen(lookupItems); i++)
    {
        [fieldId, returnItem, method] = conpeek(lookupItems, i);

        if (method)
        {
            return;
        }
    }
Почему-то в HFR8 (а также в Ax2012R3) тип переменной method изменили, но использовать её перестали. То есть при наличии display-методов в лукапе поля в нём всё равно оптимизируются и селектятся не все. Что сильно мешает в том случае когда отображаемый display-метод основан на полях, не выводящихся в лукап.
В Ax2009 были проблемы с лукапами, основанными на запросах с применением Union. Как раз метод \Classes\SysTableLookup\buildSelectionList портил всё. В Ax2012 вроде попытались исправить и учесть Union, но опять же не до конца. Если union состоит из двух одинаковых таблиц, то проблем нет. Но если к одной из таблиц в union приджойнена ещё какая-нибудь таблица (ExistsJoin например), то лукап перестаёт работать.
__________________
Дмитрий
Старый 05.04.2016, 18:36   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
А не проще ли для такого лукапа сделать View?
Старый 05.04.2016, 18:42   #8  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Damn Посмотреть сообщение
при наличии display-методов в лукапе поля в нём всё равно оптимизируются и селектятся не все. Что сильно мешает в том случае когда отображаемый display-метод основан на полях, не выводящихся в лукап.
В sysTableLookup просится метод для явного добавления полей в выборку через queryBuildDataSource.addSelectionField(), но не отображающий их. Наверное не сложно такой костыль реализовать.
Старый 05.04.2016, 19:06   #9  
Damn is offline
Damn
Участник
 
436 / 154 (6) ++++++
Регистрация: 28.05.2003
Адрес: в глуши
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
В sysTableLookup просится метод для явного добавления полей в выборку через queryBuildDataSource.addSelectionField(), но не отображающий их. Наверное не сложно такой костыль реализовать.
Да я чтоб сильно не мучиться просто вернул на место этот программный код из ранних версий :
X++:
    // Test that all are fields (no methods)
    for (i = 1; i <= conlen(lookupItems); i++)
    {
        [fieldId, returnItem, method] = conpeek(lookupItems, i);

        if (method)
        {
            return;
        }
    }
Для лукапов, содержащих display-методы, селектятся все поля и все довольны.
И для использования union в лукапах тоже класс SysTableLookup подкорректировал в нужных местах.
__________________
Дмитрий
Теги
group by, lookup, order by, query

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Группировка по полю GUID sukhanchik DAX: Программирование 6 21.12.2010 14:43
Группировка сводной таблицы Excel AlexeyVS DAX: Программирование 4 29.07.2010 12:13
Группировка в Lookup maze DAX: Программирование 6 18.11.2009 17:08
Группировка временной таблицы Андрей К. DAX: Программирование 3 20.01.2009 08:45
Группировка в отчетах Pegiy DAX: Программирование 14 22.10.2004 10:44

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

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

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