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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 04.01.2012, 11:43   #1  
Rimantas is offline
Rimantas
Участник
 
304 / 16 (1) ++
Регистрация: 30.04.2004
Адрес: Utena , Lithuania
Запрос к InventSum с InventLocationId
*** Вынесено из InventLocationId в InventTrans, sukhanchik ***
Здраствуйте ,

Мы сделали InventLocationId в InventSum'е . Помогло и облегчило дело с рапоратми по складам .

Хотел попросить совета . Бухалтерия требует отчетов складов , в которых были остатки в начяле периода и остатки в конце .

Я сделаю такое в одной из своей классе :
X++:
Query qInvSum1( Query qry )
{
   QueryBuildDataSource    qBSSum, qBSTrn;
   ;

   qBSSum = qry.dataSourceTable( TableNum( InventSum ) );
   qBSSum.addSortIndex( indexnum( InventSum, LocateItemIdx ) );
   qBSSum.indexIsHint( true );

   qBSTrn = qBSSum.addDataSource( tableNum( InventTrans ) );
   qBSTrn.addLink( fieldNum( InventTrans, InventDimId ), fieldNum( InventSum, InventDimId ) );
   qBSTrn.addLink( fieldNum( InventTrans, ItemId ), fieldNum( InventSum, ItemId ) );
   qBSTrn.addSortIndex( indexNum( InventTrans, DimIdIdx ) );
   qBSTrn.indexIsHint( true );
   qBSTrn.joinMode( JoinMode::ExistsJoin );
   qBSTrn.firstOnly( true );
   qBSTrn.fetchMode( QueryFetchMode::One2One );
   qBSTrn.addRange( fieldNum( InventTrans, DatePhysical ) ).value( queryRange( dBgn, dateMax() ) );
   return qry;
}
Обнаружив такое , я подсчитаю приход , отход товара и имею цифры в конце периода и в начяле периода .

Дело в том что некоторые товары из InventSum может быть неподвигались и в InventTrans'e нету записей с ними . Тогда я вынужден сделать второй запрос :

X++:
Query qInvSum2( Query qry )
{
   QueryBuildDataSource    qBSSum, qBSTrn;
   ;

   qBSSum = qry.dataSourceTable( TableNum( InventSum ) );
   qBSSum.addSortIndex( indexnum( InventSum, LocateItemIdx ) );
   qBSSum.indexIsHint( true );
   qBSSum.addRange( fieldNum( InventSum, PhysicalInvent ) ).value( queryvalue( '!= 0' ) );

   qBSTrn = qBSSum.addDataSource( tableNum( InventTrans ) );
   qBSTrn.addLink( fieldNum( InventTrans, InventDimId ), fieldNum( InventSum, InventDimId ) );
   qBSTrn.addLink( fieldNum( InventTrans, ItemId ), fieldNum( InventSum, ItemId ) );
   qBSTrn.addSortIndex( indexNum( InventTrans, DimIdIdx ) );
   qBSTrn.indexIsHint( true );
   qBSTrn.joinMode( JoinMode::NoExistsJoin );
   qBSTrn.firstOnly( true );
   qBSTrn.fetchMode( QueryFetchMode::One2One );
   qBSTrn.addRange( fieldNum( InventTrans, DatePhysical ) ).value( queryRange( dBgn, dateMax() ) );
   qBSTrn.addRange( fieldNum( InventTrans, DatePhysical ) ).value( queryvalue( strfmt( ">=%1", dBgn ) ) );

   return qry;
}
Но ето неудобно . Подскажите пожалуйста , как сделать запрос чтобы за один раз можно было взять всех записей , так со InventTrans'ом и так и без него ...

Заранее спасибо !

Последний раз редактировалось sukhanchik; 06.01.2012 в 00:20.
Старый 04.01.2012, 12:06   #2  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
2 Rimantas

Одним запросом это можно сделать через Outer Join с группировкой, примерно так:

X++:
Select sum(xxxQty), sum(yyyAmount), ... from InventSum
 group by ItemId, InventDimId, ...
outer join InventTrans
 group by ItemId 
where InventTrans.InventDimId == InventSum.InventDimId
    && InventTrans.ItemId         == InventSum.ItemId
    && InventTrans.DatePhysical >= dBgn;
Хинты, условия и нужные поля (там где многоточия) добавить по вкусу...

В цикле проверять заполненность поля InventTrans.ItemId - если есть, то это ваш первый случай, если нет - второй.

Насколько это будет быстрее или медленнее, и, соответсвенно, целесообразно использовать, проверьте сами на своих данных.
__________________
Zhirenkov Vitaly
Старый 04.01.2012, 12:14   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,875 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Мне кажется не стоит гнаться за одним запросом.
Лучше сделать несколько оптимизированных запросов, а промежуточные данные хранить во времянке или в мапе, если их немного.
Старый 04.01.2012, 14:18   #4  
Rimantas is offline
Rimantas
Участник
 
304 / 16 (1) ++
Регистрация: 30.04.2004
Адрес: Utena , Lithuania
Цитата:
Сообщение от ZVV Посмотреть сообщение
2 Rimantas

Одним запросом это можно сделать через Outer Join с группировкой, примерно так:

X++:
Select sum(xxxQty), sum(yyyAmount), ... from InventSum
 group by ItemId, InventDimId, ...
outer join InventTrans
 group by ItemId 
where InventTrans.InventDimId == InventSum.InventDimId
    && InventTrans.ItemId         == InventSum.ItemId
    && InventTrans.DatePhysical >= dBgn;
Хинты, условия и нужные поля (там где многоточия) добавить по вкусу...

В цикле проверять заполненность поля InventTrans.ItemId - если есть, то это ваш первый случай, если нет - второй.

Насколько это будет быстрее или медленнее, и, соответсвенно, целесообразно использовать, проверьте сами на своих данных.
Дело в том что в отчете может так выглядит :
товар кол1 приход отход кол2
тов1 0 10 -10 0 - в инветСумме уже нету , но были движения ,
тов2 10 0 -10 0 - тоже самое ,
тов22 0 10 0 10 - были движения , есть в инвентсумме ,
тов3 10 0 0 10 - нету движении ...

В моем варянте , 2-ом , чтобы неискать я сделал условие "!= 0" для количества в инвентсумме - чтобы поскорее все работало ... А можно как нибудь ещё добавить "или" в query ИнвентСума такое ?
Старый 06.01.2012, 00:00   #5  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Rimantas Посмотреть сообщение
Дело в том что в отчете может так выглядит :
товар кол1 приход отход кол2
тов1 0 10 -10 0 - в инветСумме уже нету , но были движения ,
тов2 10 0 -10 0 - тоже самое ,
тов22 0 10 0 10 - были движения , есть в инвентсумме ,
тов3 10 0 0 10 - нету движении ...

В моем варянте , 2-ом , чтобы неискать я сделал условие "!= 0" для количества в инвентсумме - чтобы поскорее все работало ... А можно как нибудь ещё добавить "или" в query ИнвентСума такое ?
1. Создайте новую ветку, как попросили выше. Или лучше попросить модераторов нужное перенести в отдельную ветку...

2.
Цитата:
А можно как нибудь ещё добавить "или" в query ИнвентСума такое ?
В данном случае речь про мой запрос?
Тогда ответ - Нет. Придётся анализировать внутри цикла, что либо есть InventTrans.ItemId || есть InventSum.PhysicalInvent...
__________________
Zhirenkov Vitaly
Старый 06.01.2012, 14:27   #6  
someOne is offline
someOne
Участник
Аватар для someOne
 
173 / 423 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Хочу предостеречь тех, кто решит добавить поле InventLicationId в таблицу InventSum.

В ранней версии (3,0) делали такое. Это давало (наверное) какие то улучшения по производительности некоторых "самописных" отчетов, едва заметные.

Но с переходом на ax2009 всплыла такая особенность. Дело в том, что для определения (например) остатков номенклатуры внутри транзакции в новых версиях Ax используются данные из двух таблиц
- InventSum
- InventSumDelta

Поэтому делая запрос лишь к InventSum (из собственно написанного кода) внутри транзакции можно получить искаженные данные.

Это конечно, не относится к работе отчетов, которые будут работать нормально.

Но попытка получить остатки по номенклатуре (например при резервировании) делая прямой запрос к inventSum вернет ошибочный результат, если этот запрос делается в транзакции, в которой по данной номенклатуре были изменения в количестве...

Вывод:
Использовать стандартные классы inventOnHand, тогда проблем не будет.

В общем от поля InventLicationId пришлось отказаться.
При этом потери скорости работы старых отчетов не заметно...
За это сообщение автора поблагодарили: Logger (6), Bega (5).
Старый 06.01.2012, 14:46   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,875 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Добавлю - ваше замечание по поводу InventSum и inventOnHand не связано с добавлением поля InventLocationId в InventSum. Это просто особенность работы 2009-й Аксапты, которую надо учитывать при разработке. Пока транзакция незакоммичена - Inventsum находится в состоянии на момент начало транзакции, поэтому для получения корректных остатков в середине транзакции неправильно писать запросы непосредственно к InventSum. (в 3-ке было можно). Надо, как вы справедливо указали, использовать класс inventOnHand, который добавит незакоммиченные изменения из InventSumDelta и вернет корректный остаток независимо от того - начата транзакция или нет.
Старый 06.01.2012, 17:05   #8  
Rimantas is offline
Rimantas
Участник
 
304 / 16 (1) ++
Регистрация: 30.04.2004
Адрес: Utena , Lithuania
Цитата:
Сообщение от Logger Посмотреть сообщение
Добавлю - ваше замечание по поводу InventSum и inventOnHand не связано с добавлением поля InventLocationId в InventSum. Это просто особенность работы 2009-й Аксапты, которую надо учитывать при разработке. Пока транзакция незакоммичена - Inventsum находится в состоянии на момент начало транзакции, поэтому для получения корректных остатков в середине транзакции неправильно писать запросы непосредственно к InventSum. (в 3-ке было можно). Надо, как вы справедливо указали, использовать класс inventOnHand, который добавит незакоммиченные изменения из InventSumDelta и вернет корректный остаток независимо от того - начата транзакция или нет.
Вот , вот .... очень актуально . Есть такое и со старой Ахаптой . Работаем с 3,0 SP 4 Ахаптой . Но бывает такие случаи , когда отстаток некореткный . Никак нинашёл в чем дело с етим . Ето бывает редко , словить трудно . Подскажите пожалуйста , с кем ето связано ...
Старый 07.01.2012, 18:06   #9  
Pustik is offline
Pustik
Участник
 
807 / 372 (14) ++++++
Регистрация: 04.06.2004
Цитата:
Сообщение от Rimantas Посмотреть сообщение
Вот , вот .... очень актуально . Есть такое и со старой Ахаптой . Работаем с 3,0 SP 4 Ахаптой . Но бывает такие случаи , когда отстаток некореткный . Никак нинашёл в чем дело с етим . Ето бывает редко , словить трудно . Подскажите пожалуйста , с кем ето связано ...
Это может быть связано с тем, если у вас построение отчета происходит по алгоритму не сначала времен. А с использованием inventSum. Принцип такой : Получаем остатки на сегодня (InventSum). Вычисляем приход + расход от указанной вами даты до сегодня. Можем вычислить остатки на указанную вами дату. Затем вычисляем приход. Затем расход. А остатки на конец месяца путем сложения остатки на начало + приход - расход.Такой принцип работает быстрее стандартной оборотки в ваших версиях, за счет того, что при выборке данных используется маленький период(а не сначала времен). Но в этом есть подвох (он не частый но иногда происходит).Пока вы получаете остатки в наличии на сегодня, кто-то может разнести журнал, закупку и т.д.Т.е. вы в процессе выполнения получили остаток без учета этого разнесенного журнала. Затем ваш алгоритм переходит к получению приъхода, расхода и т.д. И вот тут вы получите, что в приход(или расход) попало количество этого УЖЕ разнесенного журнала.В итоге данные не корректные. Если вы запустите этот отчет еще раз, все будет нормально. У нас, такое происходит периодически.
__________________
-Ты в гномиков веришь?
-Нет.
-А они в тебя верят, смотри, не подведи их.
Старый 09.01.2012, 10:30   #10  
Rimantas is offline
Rimantas
Участник
 
304 / 16 (1) ++
Регистрация: 30.04.2004
Адрес: Utena , Lithuania
Цитата:
Сообщение от Pustik Посмотреть сообщение
Это может быть связано с тем, если у вас построение отчета происходит по алгоритму не сначала времен. А с использованием inventSum. Принцип такой : Получаем остатки на сегодня (InventSum). Вычисляем приход + расход от указанной вами даты до сегодня. Можем вычислить остатки на указанную вами дату. Затем вычисляем приход. Затем расход. А остатки на конец месяца путем сложения остатки на начало + приход - расход.Такой принцип работает быстрее стандартной оборотки в ваших версиях, за счет того, что при выборке данных используется маленький период(а не сначала времен). Но в этом есть подвох (он не частый но иногда происходит).Пока вы получаете остатки в наличии на сегодня, кто-то может разнести журнал, закупку и т.д.Т.е. вы в процессе выполнения получили остаток без учета этого разнесенного журнала. Затем ваш алгоритм переходит к получению приъхода, расхода и т.д. И вот тут вы получите, что в приход(или расход) попало количество этого УЖЕ разнесенного журнала.В итоге данные не корректные. Если вы запустите этот отчет еще раз, все будет нормально. У нас, такое происходит периодически.
Вы правы на все 110 % ... :-) . И мы так думаем . Ещё могу добавить что есть несовпадение InventSum-а и InventTrans-a . То есть в том смысле , когда програма сделает query в реальном времени , оно хватает данные от InventSum как такие . И вот когда другие делает попрваки , то в тот момент InventTrans пополняеться записями , а InventSum от query - остаеться непоправленным . Вот ето место необновляеться ( например ) :

while ( qr.next() )
{
inventDim = qr.get( tableNum( InventDim ) );
InventSum = qr.get( tableNum( InventSum ) );
... и т.д.
}

Наверно для того , чтобы избежaть такое , надо ещё раз взять переменную inventSum2 . Например - inventSum2 = InventSum::findRecord( inventSum.RecId ) . Вот тогда данные в InventSum-е будет правильные и точка отчета в данный момент тоже правильное ... Все - попробываю ...
Старый 09.01.2012, 19:00   #11  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Rimantas Посмотреть сообщение
есть несовпадение InventSum-а и InventTrans-a . То есть в том смысле , когда програма сделает query в реальном времени , оно хватает данные от InventSum как такие . И вот когда другие делает попрваки , то в тот момент InventTrans пополняеться записями , а InventSum от query - остаеться непоправленным . Вот ето место необновляеться ( например ) :

while ( qr.next() )
{
inventDim = qr.get( tableNum( InventDim ) );
InventSum = qr.get( tableNum( InventSum ) );
... и т.д.
}
Это нормально. Когда вы отправляете запрос на СУБД, последняя готовит вам т.н. ResultSet - слепок с нужными вам данными на основе исходных, удовлетворяющих критериям запроса. Если за время обработки этого результата исходные данные изменились, вы этого не увидите без выполнения подзапросов или повторного выполнения всего запроса.
Цитата:
Сообщение от Rimantas Посмотреть сообщение
Наверно для того , чтобы избежaть такое , надо ещё раз взять переменную inventSum2 . Например - inventSum2 = InventSum::findRecord( inventSum.RecId )
Скорее всего не получится, потому что запросы по InventSum обычно идут с агрегированием, и в результирующей выборке RecId отдельных записей просто нет.
Старый 11.01.2012, 22:30   #12  
Pustik is offline
Pustik
Участник
 
807 / 372 (14) ++++++
Регистрация: 04.06.2004
Цитата:
Сообщение от Rimantas Посмотреть сообщение
Наверно для того , чтобы избежaть такое , надо ещё раз взять переменную inventSum2 . Например - inventSum2 = InventSum::findRecord( inventSum.RecId ) . Вот тогда данные в InventSum-е будет правильные и точка отчета в данный момент тоже правильное ... Все - попробываю ...
Для исправления такой погрешности, мы использовали фиксированное сальдо. Т.е. после каждого закрытия месяца, заполняется табличка, где фиксируется сальдо. Четко знаем, что закрытый период, и уж тем более эту табличку (насколько я знаю она есть и в 2009), никто не испортит , можно плясать от нее. Идея в том, что любой разнесенный документ (журнал, закупка и т.д.) в любом случае, повлияет на inventSum, а на эту табличку нет.Поэтому можно плясать не от inventSum, а от этой таблички. Например, заказываете вы обороту от 01.01.2012 по 31.01.2012. За старт мы возьмем не InventSum, а нашу табличку (где уже есть закрытый декабрь).И конечное сальдо декабря, как равно начальное сальдо января не поменяется. Дальше дело техники. Погрешность минимизируется.
У нас, почти во все важные оборотки встроена такая возможность.
__________________
-Ты в гномиков веришь?
-Нет.
-А они в тебя верят, смотри, не подведи их.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Dynamics AX Sustained Engineering: Fields modifiedDateTime and modifiedBy on Table InventSum Blog bot DAX Blogs 0 30.12.2010 00:12
DAX 2009 InventSum Кнопка запрос - ошибка f18 DAX: Программирование 0 09.04.2010 14:51
Разница NotInTTS и Found Logger DAX: База знаний и проекты 6 18.09.2008 12:35
Ошибка при разноске складских движений Starling DAX: Администрирование 9 12.10.2007 14:21
Временная таблица + RLS leshy DAX: Программирование 6 27.04.2006 12:39

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

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

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