AXForum  
Go Back   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Forgotten Your Password?
Register Forum Rules FAQ Members List Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Old 28.09.2009, 12:26   #1  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 28.09.2009
Статистика по каждому коду номенклатуры. Как правильно построить Query?
Добрый день, необходим совет.

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

Click image for larger version

Name:	DeartConsum.jpg
Views:	295
Size:	38.0 KB
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. Группировка по Центру и Цели происходит таким-же образом? и как мне лучще всего выяснить Кол-во и Цену?
Old 28.09.2009, 12:32   #2  
lev is offline
lev
Ищущий знания...
lev's Avatar
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Join Date: 18.01.2005
Location: Москва
X++:
dsForInventTrans.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
я предполагаю что вы вот этой строчкой хотите сделать группировку...
не смог найти какой ds присваивается dsForInventTrans, но судя по названию это InventTrans, а не InventTransPosting, т.е. просто опечатка наверно
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Old 28.09.2009, 12:35   #3  
lev is offline
lev
Ищущий знания...
lev's Avatar
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Join Date: 18.01.2005
Location: Москва
посмотрел внимательнее...
X++:
dsForInventTrans.addSortField(fieldnum(inventTrans, itemId));
        dsForInventTrans.addSortField(fieldId2Ext(fieldnum(InventTransPosting, Dimension), 1));
странные строчки... в один и тот же qbds добавляете группировку полей из разных таблиц.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
This post has been rated by: dynamax (1).
Old 28.09.2009, 12:38   #4  
Murlin is offline
Murlin
Возьми свет!!!
Murlin's Avatar
Самостоятельные клиенты AX
Злыдни
 
291 / 32 (2) +++
Join Date: 22.09.2008
Location: Тюмень, Рашан Федерашан
Легче по мойму рассказать что такое кубы
Old 28.09.2009, 12:41   #5  
Bishop is offline
Bishop
Участник
 
89 / 60 (3) ++++
Join Date: 12.08.2004
Location: Москва
Вам нужно "перестроить" запрос: InventTransPosting join InventTrans join InventDim.
Группировку наложите на поля InventTransPosting - ItemId и необходимую аналитику.
И все будет OK.

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

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

Last edited by Bishop; 28.09.2009 at 12:54.
This post has been rated by: dynamax (1).
Old 28.09.2009, 12:41   #6  
TasmanianDevil is offline
TasmanianDevil
Мрачный тип
TasmanianDevil's Avatar
Злыдни
 
887 / 389 (14) ++++++
Join Date: 24.01.2005
Location: Томск
Повезло Вам, что он вообще заработал ...
Хотите группировку по полям InvnetTransPosting ?
Тогда извольте и dsForInventTransPostingPhysical'у указать sortMode аналогично InventTrans'у. И поле для группировки добавлять на нем, а не InventTrans'е (именно тут повезло, что у InventTrans'а оказалось поле с таким же кодом, как у Dimension[1] у InventTransPosting - обратите внимание group by InventTrans.InvoiceId, который Вы вообще не добавляли )
__________________
Мы летаем, кружимся, нагоняем ужасы ...
This post has been rated by: dynamax (1).
Old 28.09.2009, 12:46   #7  
lev is offline
lev
Ищущий знания...
lev's Avatar
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Join Date: 18.01.2005
Location: Москва
Quote:
Originally Posted by dynamax View Post
Значит так:

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 тоже правильное замечание..
не понял, заработало или нет..
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Old 28.09.2009, 12:49   #8  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 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....

Last edited by dynamax; 28.09.2009 at 13:00.
Old 28.09.2009, 13:09   #9  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 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'}))
Корректное количество строк, но подразделение теперь не видно...
Old 28.09.2009, 13:17   #10  
lev is offline
lev
Ищущий знания...
lev's Avatar
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Join Date: 18.01.2005
Location: Москва
ну у Вас же группировка, значит будут видны данные только в тех полях, по которым выполнена группировка. Значит вам нужно сделать суммирование количества, которое должно выводиться...
(sum(Qty))

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

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

Last edited by dynamax; 28.09.2009 at 13:30.
Old 28.09.2009, 13:38   #13  
TasmanianDevil is offline
TasmanianDevil
Мрачный тип
TasmanianDevil's Avatar
Злыдни
 
887 / 389 (14) ++++++
Join Date: 24.01.2005
Location: Томск
Quote:
Originally Posted by dynamax View Post
Я выполняю группировку по InventTrans.ItemId, TransPosting.Dimension[1], количество строк в форме правильное, но не отобржаются подразделения (InventTransPosting.Dimension[1]).
А вот это уже подлый ExistsJoin поработал
__________________
Мы летаем, кружимся, нагоняем ужасы ...
Old 28.09.2009, 13:40   #14  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 28.09.2009
Quote:
Originally Posted by TasmanianDevil View Post
А вот это уже подлый ExistsJoin поработал
но у меня JoinMode::InnerJoin....
Old 28.09.2009, 14:07   #15  
Vals is offline
Vals
Аманд
Vals's Avatar
Компания АМАНД
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2009
 
1,766 / 507 (20) +++++++
Join Date: 27.02.2002
Location: Pass partout, Москва
Посмотрите Номенклатура/Запросы/Статистика, возможно наведёт вас на мысль.
И OLAP, насколько я помню, под подобную задачу там есть уже готовые примеры.
This post has been rated by: dynamax (1).
Old 28.09.2009, 15:53   #16  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 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'));
    }

то при активации/деактивации подразделения запрос остается одинаковым, хотя отладчик приземляется правильно
Old 14.10.2009, 11:02   #17  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 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, то показываются подразделения. Вернее, то одно на все строки, то другое, хотя их несколько. Где я ошибаюсь?
Old 14.10.2009, 11:27   #18  
dynamax is offline
dynamax
Участник
 
62 / 11 (1) +
Join Date: 28.09.2009
Вопрос снимается!

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

 

Similar Threads
Thread Thread Starter Forum Replies Last Post
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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Рейтинг@Mail.ru
All times are GMT +3. The time now is 23:56.
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Contacts E-mail, Advertising.