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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.10.2020, 18:22   #1  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1630 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Получение остатков при включенном складе
Такая задача
Нужно получить запросом(т.е. быстро, без создания класса для каждой строки) список с полями
Номенклатура, Склад, Значение AvailPhysical(то которое выводится в стандартной форме В наличии
Название: OnhandData.png
Просмотров: 675

Размер: 23.2 Кб
Какой вообще правильный и наиболее быстрый способ получения такого списка?
Я так понимаю при включенном складе часть остатков хранится в WHSInventReserve, часть в InventSum, как это все соединить вместе?
Версия Ax2012R3 последний CU
Старый 07.10.2020, 22:34   #2  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
InventAvailabilityProvider:
X++:
        InventAvailabilityByUnit    result;

        if (_search.isItemWHSEnabled())
        {
            WHSInventReserveQty whsInventReserveQty = WHSInventReserveQty::newFromParms(_search.inventTable(), _search.inventDimCriteria(), _search.inventDimCriteriaParm(), _search.inventSum());
            result = InventAvailabilityByUnit::newFromParms(whsInventReserveQty, whsInventReserveQty);
        }
        else if (_search.isInventSumSet())
        {
            InventSumAvailability inventSumAvailability = InventSumAvailability::newFromInventSum(_search.inventSum());
            result = InventAvailabilityByUnit::newFromParms(inventSumAvailability, inventSumAvailability);
        }
        else
        {
            InventOnHandQty inventOnHandQty = InventOnHandQty::newParameters(_search.itemId(), _search.inventDimCriteria(), _search.inventDimCriteriaParm());
            result = InventAvailabilityByUnit::newFromParms(inventOnHandQty, inventOnHandQty);
        }

        return result;
Т.е. не И И , а ИЛИ ИЛИ. В одной компании могут быть номенклатуры как с поддержкой WHS, так и без оной. Получается UNION.
Старый 08.10.2020, 00:57   #3  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1630 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Ну да, это дисплей метод AvailPhysical . Вопрос - как эти данные получить запросом, сразу для всех номенклатур, без создания класса для каждой номенклатуры.
В варианте "без склада" это будет типа того что написано ниже
X++:
while select ItemId, sum(AvailPhysical) from inventSum 
group by ItemId
join InventLocationId from inventDim
group by InventLocationId
where inventSum.InventDimId == inventDim.InventDimId
..
Старый 08.10.2020, 08:22   #4  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
А чем union не устраивает ? В том плане, что как писал Евгений - для номенклатуры используется ИЛИ, т.е. остатки либо по inventsum считать, либо по WHSInventReserve.

Интересует сам запрос по WHSInventReserve ?

C WHS опыта мало, но я бы смотрел в сторону следующих методов(если уровень склада одинаков во всех иерархиях)
WhsInventOnHand\getReserveAvailQty
WhsInventOnHand\getAvailPhysicalForLevel

Либо запрос из SP, в случае, если до склада есть другие аналитики (например у вас иерархия [статус, сайт, склад]), возможно запрос можно использовать и более универсально - для всех данных, правда по производительности может быть хуже
чем из классов AX 2012 R3. Ускорение sp_WHSOnHand и sp_WHSOnHandWithDelta


В итоге должно получится примерно следующее :
X++:
//ваш запрос по inventsum
union 
 //думаю здесь запрос по inventReserve в реальности будет по сложнее
        select ItemId, minOf(AvailPhysical) from inventReserve
            group by ItemId
             where inventReserve.HierarchyLevel >= locationLevel
            join InventLocationId from inventDim
group by InventLocationId
where inventReserve.InventDimId == inventDim.InventDimId
//или
        select ItemId, sum(AvailPhysical) from inventReserve
            group by ItemId
             where inventReserve.HierarchyLevel == locationLevel
            join InventLocationId from inventDim
group by InventLocationId
where inventReserve.InventDimId == inventDim.InventDimId
// или запрос из SP
Как правильно не знаю, но опять таки в стандарте на inventSum есть метод newQuery, где ItemId не обязательный параметр, аналогично и на табличке WHSInventReserve есть метод newAvailQuery(правда в нём не делается группировка по ItemId, если пустое, но может быть где в других методах затем её вызывают)
__________________
Sergey Nefedov
За это сообщение автора поблагодарили: trud (1).
Старый 08.10.2020, 08:46   #5  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1630 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от SRF Посмотреть сообщение
если уровень склада одинаков во всех иерархиях)
where inventReserve.HierarchyLevel >= locationLevel
А если уровень склада не одинаков? Это же настраиваемый параметр
Т.е. у меня скорее вопрос - как правильно то делать, чтобы покрыть все случаи. Как разграничивать этот union - где-то делается с WHSInventEnabled(таблица содержащая одно поле ItemId), где-то с WHSInventReserve

Нашел документ, который описывает структуру, но в нем только обращение через API
https://www.microsoft.com/en-gb/down....aspx?id=43284
За это сообщение автора поблагодарили: Vadik (1), Logger (3).
Старый 08.10.2020, 09:33   #6  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Про не одинаков - это характеристика номенклатуры, ну т.е. для ItemId уровень определяется однозначно.

Но я скорее о том, что если уровень склада в иерархии 1-2 то получить можно условно простым запросом по whsinventReserve(т.к. нет пустых аналитик перед складом), а вот если склад уже ниже, то у нас есть пустые аналитики в иерархии и в таких случаях система лезет за получением остатка в SP и запрос нужно скорее всего из неё брать за базу и менять, можно ли как то получить просто запросом из WHSInventRerserve - типа select ItemId, sum(AvailPhysical) from inventReserve where HierarchyLevel = locationLevel не ясно.
__________________
Sergey Nefedov
Старый 08.10.2020, 14:12   #7  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от trud Посмотреть сообщение
Какой вообще правильный и наиболее быстрый способ получения такого списка?
Критерии "правильности" и "лучшести" зависят от задачи. Если нужно быстро получить остатки по нескольким / многим / всем номенклатурам и 100% актуальность данных некритична, можно посмотреть как в D365 в ритейле product availability считается. Там снэпшот остатков который инкрементно батчем обновляется, а потом агрегируется и отправляется в channel DB. Понятно что есть отставание от реального склада, но зато быстро и в оффлайне работает
__________________
-ТСЯ или -ТЬСЯ ?

Последний раз редактировалось Vadik; 08.10.2020 в 14:15.
Старый 13.10.2020, 10:37   #8  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1630 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
В итоге сделал так - в начале получаются остатки из InventSum
X++:
    while select sum(AvailPhysical), sum(PhysicalInvent), sum(OnOrder), sum(ReservOrdered), sum(ReservPhysical) from inventSum
        group by ItemId
        where inventSum.ClosedQty           == NoYes::No
    join InventLocationId from inventDim
        group by InventLocationId
        where inventDim.InventDimId         == inventSum.InventDimId
        &&    inventDim.InventLocationId    == _inventLocationId
Потом получаются остатки из WHSInventReserve и в цикле объединяются с теми что есть в InventSum (через временную таблицу)
X++:
    while select sum(AvailPhysical), sum(ReservOrdered), sum(ReservPhysical) from WHSInventReserve
        group by ItemId
    join  WHSReservationHierarchyItem
        group by ItemId
        where WHSReservationHierarchyItem.ItemId      == WHSInventReserve.ItemId &&
              WHSReservationHierarchyItem.ItemDataAreaId  == WHSInventReserve.dataAreaId
    join WHSReservationHierarchyElement
        group by DimensionFieldId
        where WHSReservationHierarchyElement.DimensionFieldId          == fieldNum(InventDim, InventLocationId) &&
              WHSReservationHierarchyElement.ReservationHierarchy      == WHSReservationHierarchyItem.ReservationHierarchy &&
              WHSReservationHierarchyElement.ReservationHierarchyLevel == WHSInventReserve.HierarchyLevel
    join InventLocationId from inventDim
        group by InventLocationId
        where inventDim.InventDimId         == WHSInventReserve.InventDimId
        &&    inventDim.InventLocationId    == _inventLocationId
...
Второй цикл работает в 6 раз медленнее чем первый, но все равно в целом получается в 10 раз быстрее чем получать остатки по каждой номенклатуре
За это сообщение автора поблагодарили: fed (5), EVGL (5), raz (5), sukhanchik (8), Logger (5), SRF (1).
Старый 13.10.2020, 10:53   #9  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
700 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
А насколько быстрее работает group by inventlocationid по сравнению с exist join? Там же и так есть фильтр по складу.
Старый 13.10.2020, 14:48   #10  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1630 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
не думаю что есть какая-то разница
Старый 13.10.2020, 21:25   #11  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
700 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от trud Посмотреть сообщение
не думаю что есть какая-то разница
Интересный подход к написанию запросов особенно когда надо "побыстрее".
Теги
документация

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Контроль остатков на складе поставщика при планировании Starling DAX: Функционал 10 07.03.2013 12:13
Статья о новом механизме блокировок складских остатков в Ax 4.0 lev DAX: Программирование 3 01.06.2011 10:56
Критический минимум остатков на складе Pustik DAX: Функционал 2 25.07.2005 15:48
Красные остатки на складе ERx DAX: Функционал 7 01.07.2004 15:18
Учет остатков сырья на складе akvi DAX: Функционал 7 02.04.2003 00:11

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

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

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