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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.09.2009, 12:26   #1  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
Статистика по каждому коду номенклатуры. Как правильно построить Query?
Добрый день, необходим совет.

дело в следующем: заказчик захотел форму в которой будет отображаться расход по подразделениям, центрам, целям (физически). Форма выглядит следующим образом:

Нажмите на изображение для увеличения
Название: DeartConsum.jpg
Просмотров: 290
Размер:	38.0 Кб
ID:	5180

У формы три DataSources: InventTrans, InventTransPosting, InventDim.

Я сделал на Datasource InventTrans методу SetupRange (посмотрел в smmActivities), вот код:

X++:
public void setupRanges()
{
    ;
    dsForInventTrans                    = InventTrans_ds.query().dataSourceTable(tablenum(InventTrans));


    if(!dsForInventDim)
    dsForInventDim                      = dsForInventTrans.addDataSource(tablenum(InventDim));
    else inventTrans_DS.query().dataSourceTable(tablenum(InventDim));
    dsForInventDim.relations(true);
    dsForInventDim.joinMode(JoinMode::ExistsJoin);

    if(!dsForInventTransPostingPhysical)
    dsForInventTransPostingPhysical     = dsForInventTrans.addDataSource(tablenum(inventTransPosting));
    else inventTrans_ds.query().dataSourceTable(tablenum(inventTransPosting));
    dsForInventTransPostingPhysical.relations(true);
    dsForInventTransPostingPhysical.joinMode(JoinMode::ExistsJoin);

    rangeForItemId          = SysQuery::findOrCreateRange(dsForInventTrans, fieldnum(InventTrans, itemId));
    rangePeriod            = SysQuery::findOrCreateRange(dsForInventTransPostingPhysical, fieldnum(InventTransPosting, TransDate));
}
executeQuery на етом же DataSource :

X++:
public void executeQuery()
{

    InventSum       inventSum;
    InventTable     inventTable;
    ;

    inventTrans_DS.setupRanges();

    // Enable/Disable ranges
    if (ItemId && department.value() == true)
    {
        rangeForItemId.enabled(true);
        rangePeriod.enabled(true);
        rangeForItemId.value(itemIdFilter);
        rangePeriod.value(SysQuery::range(StartDate, EndDate));

        dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
        dsForInventTrans.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
        dsForInventTrans.orderMode(OrderMode::GroupBy);
    }
    super();    
}
и вот SQL-запрос, который формируется:

X++:
SELECT * FROM InventTrans GROUP BY InventTrans.ItemId ASC, InventTrans.InvoiceId ASC WHERE ((ItemId = N'M0001')) EXISTS JOIN * FROM InventDim WHERE InventTrans.inventDimId = InventDim.inventDimId EXISTS JOIN * FROM InventTransPosting WHERE InventTrans.InventTransId = InventTransPosting.InventTransId AND ((TransDate>={ts '2008-09-01 00:00:00.000'} AND TransDate<={ts '2009-09-28 00:00:00.000'}))
по каким-то причинам не происходит группировка по InventTransPosting.Dimension[1]. Если у кого-нибудь есть идеи, буду благодарен.


P.S. Группировка по Центру и Цели происходит таким-же образом? и как мне лучще всего выяснить Кол-во и Цену?
Старый 28.09.2009, 12:32   #2  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
X++:
dsForInventTrans.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
я предполагаю что вы вот этой строчкой хотите сделать группировку...
не смог найти какой ds присваивается dsForInventTrans, но судя по названию это InventTrans, а не InventTransPosting, т.е. просто опечатка наверно
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 28.09.2009, 12:35   #3  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
посмотрел внимательнее...
X++:
dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
        dsForInventTrans.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
странные строчки... в один и тот же qbds добавляете группировку полей из разных таблиц.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
За это сообщение автора поблагодарили: dynamax (1).
Старый 28.09.2009, 12:38   #4  
Murlin is offline
Murlin
Возьми свет!!!
Аватар для Murlin
Самостоятельные клиенты AX
Злыдни
 
291 / 32 (2) +++
Регистрация: 22.09.2008
Адрес: Тюмень, Рашан Федерашан
Легче по мойму рассказать что такое кубы
Старый 28.09.2009, 12:41   #5  
Bishop is offline
Bishop
Участник
 
89 / 60 (3) ++++
Регистрация: 12.08.2004
Адрес: Москва
Вам нужно "перестроить" запрос: InventTransPosting join InventTrans join InventDim.
Группировку наложите на поля InventTransPosting - ItemId и необходимую аналитику.
И все будет OK.

В текущем варианте вы вообще используете exists join для InventTransPosting и хотите увидеть какие-то данные этой таблицы - это некорректно.

Хотя... моя подсказка неверна - из InventTransPosting однозначно в InventTrans не перейти в случае разбиения лота на несколько проводок. Так что так не делайте ))
Если не нужна складская аналитика (я в вашем случае не увидел необходимости ее применения), то переделайте запрос в InventTrans join InventTransPosting, кол-во - сумма по полю InventTrans.Qty, стоимость - сумма по полю InventTrans.CostAmountPosted плюс сумма по InventTrans.CostAmountAdjustment.

Последний раз редактировалось Bishop; 28.09.2009 в 12:54.
За это сообщение автора поблагодарили: dynamax (1).
Старый 28.09.2009, 12:41   #6  
TasmanianDevil is offline
TasmanianDevil
Мрачный тип
Аватар для TasmanianDevil
Злыдни
 
886 / 389 (14) ++++++
Регистрация: 24.01.2005
Адрес: Томск
Повезло Вам, что он вообще заработал ...
Хотите группировку по полям InvnetTransPosting ?
Тогда извольте и dsForInventTransPostingPhysical'у указать sortMode аналогично InventTrans'у. И поле для группировки добавлять на нем, а не InventTrans'е (именно тут повезло, что у InventTrans'а оказалось поле с таким же кодом, как у Dimension[1] у InventTransPosting - обратите внимание group by InventTrans.InvoiceId, который Вы вообще не добавляли )
__________________
Мы летаем, кружимся, нагоняем ужасы ...
За это сообщение автора поблагодарили: dynamax (1).
Старый 28.09.2009, 12:46   #7  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от dynamax Посмотреть сообщение
Значит так:

X++:
dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
        //dsForInventTrans.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
        dsForInventTrans.orderMode(OrderMode::GroupBy);

        dsForInventTransPostingPhysical.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
        dsForInventTransPostingPhysical.orderMode(OrderMode::GroupBy);
какие результаты?
кстати про existjoin тоже правильное замечание..
не понял, заработало или нет..
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 28.09.2009, 12:49   #8  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
Значит так ? :

X++:
dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));        
        dsForInventTrans.orderMode(OrderMode::GroupBy);

        dsForInventTransPostingPhysical.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
        dsForInventTransPostingPhysical.orderMode(OrderMode::GroupBy);
Вот SQL-запрос:

X++:
SELECT * FROM InventTrans GROUP BY InventTrans.ItemId ASC WHERE ((ItemId = N'M0001')) EXISTS JOIN * FROM InventDim WHERE InventTrans.inventDimId = InventDim.inventDimId EXISTS JOIN * FROM InventTransPosting GROUP BY InventTransPosting.Dimension[1] ASC WHERE InventTrans.InventTransId = InventTransPosting.InventTransId AND ((TransDate>={ts '2008-09-01 00:00:00.000'} AND TransDate<={ts '2009-09-28 00:00:00.000'}))
вроде бы все правильно, но в форме вижу только одну строчку, как-будто группирую по InvnetTrans.ItemId


Не увидел замечание про ExistJoin....

Последний раз редактировалось dynamax; 28.09.2009 в 13:00.
Старый 28.09.2009, 13:09   #9  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
JoinMode::InnerJoin

и SQL-запрос:

X++:
SELECT * FROM InventTrans GROUP BY InventTrans.ItemId ASC WHERE ((ItemId = N'M0001')) JOIN * FROM InventDim WHERE InventTrans.inventDimId = InventDim.inventDimId JOIN * FROM InventTransPosting GROUP BY InventTransPosting.Dimension[1] ASC WHERE InventTrans.InventTransId = InventTransPosting.InventTransId AND ((TransDate>={ts '2008-09-01 00:00:00.000'} AND TransDate<={ts '2009-09-28 00:00:00.000'}))
Корректное количество строк, но подразделение теперь не видно...
Старый 28.09.2009, 13:17   #10  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
ну у Вас же группировка, значит будут видны данные только в тех полях, по которым выполнена группировка. Значит вам нужно сделать суммирование количества, которое должно выводиться...
(sum(Qty))

P.S. напишите какое поле, какой таблицы должно показывать кол-во в Вашей форме
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем

Последний раз редактировалось lev; 28.09.2009 в 13:19.
Старый 28.09.2009, 13:22   #11  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
вот пример:
X++:
qbds.addSelectionField(fieldNum(InventTrans, Qty), SelectionField::Sum);
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 28.09.2009, 13:27   #12  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
Цитата:
Сообщение от lev Посмотреть сообщение
значит будут видны данные только в тех полях, по которым выполнена группировка.
P.S. напишите какое поле, какой таблицы должно показывать кол-во в Вашей форме
Я выполняю группировку по InventTrans.ItemId, TransPosting.Dimension[1], количество строк в форме правильное, но не отобржаются подразделения (InventTransPosting.Dimension[1]).

Последний раз редактировалось dynamax; 28.09.2009 в 13:30.
Старый 28.09.2009, 13:38   #13  
TasmanianDevil is offline
TasmanianDevil
Мрачный тип
Аватар для TasmanianDevil
Злыдни
 
886 / 389 (14) ++++++
Регистрация: 24.01.2005
Адрес: Томск
Цитата:
Сообщение от dynamax Посмотреть сообщение
Я выполняю группировку по InventTrans.ItemId, TransPosting.Dimension[1], количество строк в форме правильное, но не отобржаются подразделения (InventTransPosting.Dimension[1]).
А вот это уже подлый ExistsJoin поработал
__________________
Мы летаем, кружимся, нагоняем ужасы ...
Старый 28.09.2009, 13:40   #14  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
Цитата:
Сообщение от TasmanianDevil Посмотреть сообщение
А вот это уже подлый ExistsJoin поработал
но у меня JoinMode::InnerJoin....
Старый 28.09.2009, 14:07   #15  
Vals is offline
Vals
Аманд
Аватар для Vals
Компания АМАНД
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2009
 
1,766 / 507 (20) +++++++
Регистрация: 27.02.2002
Адрес: Pass partout, Москва
Посмотрите Номенклатура/Запросы/Статистика, возможно наведёт вас на мысль.
И OLAP, насколько я помню, под подобную задачу там есть уже готовые примеры.
За это сообщение автора поблагодарили: dynamax (1).
Старый 28.09.2009, 15:53   #16  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
Кол-во, цена, значение - все отображается нормально. Но подразделение (центр затрат, цель), к сожалению остаются незаполнены

и еще, если добавляю такой код:

X++:
inventTrans_DS.setupRanges();

    // Enable/Disable ranges
    if (ItemId && department.value() == false && costCenter.value() == false && purpose.value() == false)
    {
        rangeForItemId.enabled(true);
        //rangeForDepartment.enabled(false);
        rangePeriod.enabled(true);
        rangeForItemId.value(itemIdFilter);
        rangePeriod.value(SysQuery::range(StartDate, EndDate));

        dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
        dsForInventTrans.orderMode(OrderMode::GroupBy);
        info(strfmt("%1", 'First'));
    }

    else if (ItemId && department.value() == true && costCenter.value() == false && purpose.value() == false)
    {
        rangeForItemId.enabled(true);
        //rangeForDepartment.enabled(true);
        rangePeriod.enabled(true);
        rangeForItemId.value(itemIdFilter);
        rangePeriod.value(SysQuery::range(StartDate, EndDate));

        dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
        dsForInventTrans.orderMode(OrderMode::GroupBy);

        dsForInventTransPostingPhysical.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
        dsForInventTransPostingPhysical.orderMode(OrderMode::GroupBy);


        dsForInventTrans.addSelectionField(fieldnum(InventTrans, Qty), SelectionField::Sum);
        info(strfmt("%1", 'Second'));
    }

то при активации/деактивации подразделения запрос остается одинаковым, хотя отладчик приземляется правильно
Старый 14.10.2009, 11:02   #17  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
вернулся вчера опять к теме, переменил методу executeQuery(). Теперь выглядит вот-так:

X++:
public void executeQuery()
{
    Query query                                                 = new Query();
    QueryRun                queryRun;
    QueryBuildDatasource    dsForInventTrans                    = query.addDataSource(tablenum(InventTrans));
    QueryBuildDatasource    dsForInventTransPosting             = dsForInventTrans.addDataSource(tablenum(InventTransPosting));

    QueryBuildRange         rangeForItemId                      = dsForInventTrans.addRange(fieldnum(InventTrans,ItemId));
    QueryBuildRange         rangeForPeriod                      = dsForInventTransPosting.addRange(fieldnum(InventTransPosting, TransDate));
    ;

    dsForInventTransPosting.relations(true);
    dsForInventTransPosting.joinMode(JoinMode::InnerJoin);
    
    rangeForItemId.enabled(true);
    rangeForPeriod.enabled(true);
    rangeForItemId.value(itemIdFilter);
    rangeForPeriod.value(SysQuery::range(StartDate, EndDate));
        
        
    //ItemId
    dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
    dsForInventTrans.addSelectionField(fieldnum(InventTrans, Qty), SelectionField::Sum);
    dsForInventTrans.addSelectionField(fieldnum(InventTrans, CostAmountPosted), SelectionField::Sum);
    dsForInventTrans.orderMode(OrderMode::GroupBy);
        
    //Dimension
    dsForInventTransPosting.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
    dsForInventTransPosting.addSelectionField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
    dsForInventTransPosting.orderMode(OrderMode::GroupBy);
    
    this.query(query);
    super();

}
Это SQL-запрос:

X++:
SELECT SUM(Qty), SUM(CostAmountPosted) FROM InventTrans GROUP BY InventTrans.ItemId ASC WHERE ((ItemId = N'M0003')) JOIN Dimension[1] FROM InventTransPosting GROUP BY InventTransPosting.Dimension[1] ASC WHERE InventTrans.InventTransId = InventTransPosting.InventTransId AND ((TransDate>={ts '2008-10-01 00:00:00.000'} AND TransDate<={ts '2009-10-14 00:00:00.000'}))
Вроде все правильно, но подразделение остается пустым. Если делаю refresh - F5, то показываются подразделения. Вернее, то одно на все строки, то другое, хотя их несколько. Где я ошибаюсь?
Старый 14.10.2009, 11:27   #18  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Регистрация: 28.09.2009
Вопрос снимается!

я перегрузил init() и еxecuteQuery() второрго dataSource. Все работает!
Теги
query, запрос (query), финансовая аналитика

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
palleagermark: Sample union query from AX 2009 Blog bot DAX Blogs 0 11.07.2008 20:05
Сводное планирование и статистика номенклатуры slava09 DAX: Функционал 6 22.01.2007 10:39
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 28.10.2006 16:40
Как построить Query? Bukovka DAX: Программирование 9 26.03.2004 16:35
Как правильно построить Query Bukovka DAX: Программирование 0 25.03.2004 11:55

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

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

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