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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 14.09.2012, 14:34   #1  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Правда все равно остаются ограничения у такого механизма по сравнению с прямым запросом к InvenSum-InventDim.

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

В следующий раз когда потребуется сложное манипулирование остатками, попробую использовать этот механизм. А пока-что в моем случае остатки достаточно было вычислить всего один раз в разрезе каждой номенклатуры и группы складких аналитик, поэтому транзакционность оказалась не помехой.

Последний раз редактировалось Ace of Database; 14.09.2012 в 14:45.
Старый 14.09.2012, 15:13   #2  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,496 / 1071 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
Цитата:
Сообщение от Ace of Database Посмотреть сообщение
Правда все равно остаются ограничения у такого механизма по сравнению с прямым запросом к InvenSum-InventDim.
А сравни результат через класс и так:
X++:
    queryRun = new QueryRun(InventSum::newQuery(null, itemId, inventDimCriteriaLocal, inventDimParmLocal, inventDimParmGroupByLocal));

    while (queryRun.next())
    {
        inventSumLocal = queryRun.get(tableNum(InventSum));
        inventDimLocal = queryRun.get(tableNum(InventDim));

        if (InventUpdateOnhandGlobal::mustAddInventSumDeltaOnhand(itemId))
        {
            select #inventSumFields from inventSumDeltaLocal
                where inventSumDeltaLocal.ItemId        == itemId    &&
                      inventSumDeltaLocal.IsAggregated  == NoYes::No &&
                      inventSumDeltaLocal.TTSId         == appl.inventUpdateOnhandGlobal().inventUpdateOnhand().tTSId()
                #InventDimExistsJoin(inventSumDeltaLocal.inventDimId,inventDim2Local,inventDimLocal,inventDimParmLocal);

            inventSumLocal.addInventSumDelta(inventSumDeltaLocal);
        }

        .......

    }
За это сообщение автора поблагодарили: Ace of Database (2), SRF (1).
Старый 14.09.2012, 15:17   #3  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
376 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от ice Посмотреть сообщение
поиск остатков с помощью двух таблиц конечно хорош, но вот если нужно, например, разнести в одной транзакции приход и расход, вот тут начинаются сложности
А в чем принципиальная разница поиска по двум таблицам и использования класса InventOnHand - он же делает те же самые 2 select'а, по тем же таблицам. Кстати о какой сложности идет речь ?

Цитата:
Сообщение от Ace of Database Посмотреть сообщение
Правда все равно остаются ограничения у такого механизма по сравнению с прямым запросом к InvenSum-InventDim.

В реальной жизни приходится еще делать сортировку\фильтрацию\группировку во всяким дополнительным полям в складах, ячейках, палетах, партиях. Подцеплять побочные таблицы.
Так используйте стандартные методы InventSum::newQuery(...) и InventSumDelta::newQueryAggregated(...) - они вернут вам Query, а дальше какие хотите условия такие и добавляйте.
__________________
Sergey Nefedov
Старый 17.09.2012, 13:09   #4  
someOne is offline
someOne
Участник
Аватар для someOne
 
174 / 432 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Была подобная задача - получить список ячеек хранения на складе с указанием свободного количества по каждой из ячеек
(по какой то отдельное номенклатуре) внутри транзакции.

Пвтался использовать метод с использованием класса "inventDimParmOnHandLevel".
Остался пример кода.
X++:
    inventDim.InventLocationId = "Склад";
    inventDim = inventDim::findDim(inventDim);

    inventDimParm.InventLocationIdFlag = true;

    inventDimParmOnHandLevel.ItemIdFlag = true;
    inventDimParmOnHandLevel.InventLocationIdFlag = true;
    inventDimParmOnHandLevel.WMSLocationIdFlag = true;

    hand = InventDimOnHand::newAvailPhysical('29530', inventDim, inventDimParm, InventDimOnHandLevel::DimParm, inventDimParmOnHandLevel);

    iterator = hand.onHandIterator();

    while (iterator.more())
    {
        member = iterator.value();


        info(member.parmInventQty());

        info(InventDim::find(member.parmInventDimId()).wMSLocationId);

        iterator.next();
    }
Но такой способ работает очень медленно. (у меня по крайней мере...). Запрос по каждой номенклатуре длится более секунды!!!.
Может в настройках классов указал что то не правильно ?

Так как мне нужно было это использовать при резервировании, то есть довольно активно, такой способ оказался не приемлем.

В общем переделал все на прямые запросы к таблицам
- InventSum
- InventSumDelta

(Что то на подобие того как предложил raz). Так все "летает".

Только нужно учесть что вариант с циклом по текущим остаткам (inventSum) с прибавлением к нему InventSumDelta по аналитикам
группкировки inventSum может дать искаженный результат.

Так как в InventSumDelta могут быть остатки по аналитикам, которых нет в inventSum.

Правильный результат будет если:

1. Получить остатки в разрезе ячеек по InventSum, например так (для моей задачи):
X++:
    inventDimParm.initFromInventDim(inventDim);
    inventDimParm.ItemIdFlag = NoYes::Yes;
    inventDimParm.ClosedQtyFlag = NoYes::Yes;

    inventDimParmGroupBy.WMSLocationIdFlag = NoYes::Yes;

    query = inventSum::newQuery(query, itemId, inventDim, inventDimParm, inventDimParmGroupBy);

    queryRange = query.dataSourceTable(tableNum(inventSum)).addRange(FieldNum(InventSum, ClosedQty));
    queryRange.value(queryValue(0));

    queryRun = new QueryRun(query);

    while (queryRun.next())
    {
        inventSum = queryRun.get(tableNum(inventSum));
        inventDimLoc = queryRun.get(tableNum(inventDim));

        if (inventSum.AvailPhysical != 0)
        {
		//Тут текущий остаток в ячейках хранения
        }
    }

2. Получить остатки в разрезе ячеек InventSumDelta, например так (для моей задачи)


X++:
    while select sum(AvailPhysical) from inventSumDelta
    where inventSumDelta.ItemId         == itemId    &&
          inventSumDelta.IsAggregated   == NoYes::No &&
          inventSumDelta.ttsId          == appl.inventUpdateOnhandGlobal().inventUpdateOnhand().ttsId()
    join inventDimLoc
    group by WMSLocationId
    where (inventDimLoc.inventDimId      == inventSumDelta.InventDimId) &&
          (inventDimLoc.InventLocationId == "Склад")
    {
        if (inventSumDelta.AvailPhysical != 0)
        {
		//Тут изменнный остаток в ячейках хранения в данной транзакции
        }
    }

3. Объеденить два этих набора записей ("сложить" результат).

Это кроме того и самый производительный способ - всего два запроса к БД.
За это сообщение автора поблагодарили: Logger (5), Ace of Database (4).
Старый 17.09.2012, 13:46   #5  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Спасибо большое Raz и SomeOne!

Метод с получением двух query для InventSum и InventSumDelta с последубщими добавлениями в них дополнительных источников данных универсален для всех задач. С последующим суммированием результата через inventSum.addInventSumDelta(inventSumDelta);

Я все понял. Осталось заставить себя в следующий раз применить этот способ, а не считать по-старинке прямыми запросами

Еще один способ - оптимизировать код таким образом, чтобы алгоритму было без разницы, внутри транзакции идет подсчет остатков или за ее пределами, и в этом случае вынести подсчет остатков за пределы транзакции. Это самый оптимальный вариант, но к сожалению не всегда допустимый.

В общем, подсчет остатков - деликатная и объемная тема, достойная диссертации.
Старый 10.03.2016, 13:50   #6  
Ярослав Щекин is offline
Ярослав Щекин
Участник
 
78 / 174 (6) ++++++
Регистрация: 16.03.2009
Извините, что поднимаю старую тему...

Коллеги, а Вам не кажется, что вот это:
Цитата:
Сообщение от someOne Посмотреть сообщение
Только нужно учесть что вариант с циклом по текущим остаткам (inventSum) с прибавлением к нему InventSumDelta по аналитикам
группкировки inventSum может дать искаженный результат.

Так как в InventSumDelta могут быть остатки по аналитикам, которых нет в inventSum.
вообще говоря, косяк в стандартном InventDimOnHand (Ax2009), или я чего-то не понимаю?
Может быть, это исправлено в каком-то SP?
Старый 18.05.2017, 13:50   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,984 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Ярослав Щекин Посмотреть сообщение
Извините, что поднимаю старую тему...

Коллеги, а Вам не кажется, что вот это:

вообще говоря, косяк в стандартном InventDimOnHand (Ax2009), или я чего-то не понимаю?
Может быть, это исправлено в каком-то SP?
Это не косяк, а так спроектировано. Если сразу добавлять запись (пусть и с пустыми остатками) в InventSum одновременно с созданием InventSumDelta, то можно нарваться на блокировки/конфликт уникального ключа. А InventSumDelta как раз и делали, чтобы этого избежать.
Старый 19.05.2017, 19:37   #8  
Ярослав Щекин is offline
Ярослав Щекин
Участник
 
78 / 174 (6) ++++++
Регистрация: 16.03.2009
Цитата:
Сообщение от Logger Посмотреть сообщение
Это не косяк, а так спроектировано. Если сразу добавлять запись (пусть и с пустыми остатками) в InventSum одновременно с созданием InventSumDelta, то можно нарваться на блокировки/конфликт уникального ключа. А InventSumDelta как раз и делали, чтобы этого избежать.
Подождите, причём тут внесение записи в InventSum? Мне было непонятно, почему InventSumDelta не обрабатывается в классе InventDimOnHand.
Старый 02.06.2017, 01:31   #9  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 646 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Цитата:
Сообщение от Ярослав Щекин Посмотреть сообщение
Мне было непонятно, почему InventSumDelta не обрабатывается в классе InventDimOnHand.
Обрабатывается. См. InventOnhand.addInventSumDelta().

someOne имел в виду, что надо быть аккуратным, когда не используется InventDimOnHand, а остатки выбираются прямыми запросами к InventSum/InventSumDelta.

Кстати, в AX 2012 R3 появились View (InventSumAggrDeltaView и InventSumUnionDeltaPhysicalQty), в которых InventSum и InventSumDelta уже связаны. Идея была в том, чтобы читать остатки из этих View, и не заморачиваться с классами InventOnhand. Идея, вероятно, была неплохая, но реализация подкачала: во View забыли добавить TTSId, и теперь любые запросы к ним блокируют и InventSum, и InventSumDelta целиком. Используются эти View в новом Warehouse Management. В блогах и на форумах есть несколько статей, в которых люди пытаются что-то шаманить с индексами на InventSumDelta, чтобы блокировки уменьшить, но корень проблемы в том, что InventSumDelta просто неправильно используется в стандартном коде.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
За это сообщение автора поблагодарили: Logger (10).
Теги
ax2009, inventsumaggrdeltaview, inventsumdelta, inventsumuniondeltaphysicalqty, как правильно, остатки, транзакции

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Epic Fail Остатки на дату InventSumDateValueReportDim Evgeniy2020 DAX: Программирование 15 13.08.2014 19:22
Проблемы с обновлением записи, выбранной для обновления внутри транзакции Oz DAX: Программирование 13 02.07.2008 16:24
Учёт остатков в разрезе фин. аналитики miklenew DAX: Программирование 11 06.11.2007 20:01
Остатки dog37 DAX: Программирование 6 02.06.2005 11:25
Сверка остатков по счетам учета материалов и складские остатки tolstjak DAX: Функционал 5 05.04.2005 13:51

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

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

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