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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 17.09.2012, 13:09   #1  
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   #2  
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   #3  
Ярослав Щекин is offline
Ярослав Щекин
Участник
 
78 / 174 (6) ++++++
Регистрация: 16.03.2009
Извините, что поднимаю старую тему...

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

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

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

вообще говоря, косяк в стандартном InventDimOnHand (Ax2009), или я чего-то не понимаю?
Может быть, это исправлено в каком-то SP?
Это не косяк, а так спроектировано. Если сразу добавлять запись (пусть и с пустыми остатками) в InventSum одновременно с созданием InventSumDelta, то можно нарваться на блокировки/конфликт уникального ключа. А InventSumDelta как раз и делали, чтобы этого избежать.
Старый 19.05.2017, 19:37   #5  
Ярослав Щекин is offline
Ярослав Щекин
Участник
 
78 / 174 (6) ++++++
Регистрация: 16.03.2009
Цитата:
Сообщение от Logger Посмотреть сообщение
Это не косяк, а так спроектировано. Если сразу добавлять запись (пусть и с пустыми остатками) в InventSum одновременно с созданием InventSumDelta, то можно нарваться на блокировки/конфликт уникального ключа. А InventSumDelta как раз и делали, чтобы этого избежать.
Подождите, причём тут внесение записи в InventSum? Мне было непонятно, почему InventSumDelta не обрабатывается в классе InventDimOnHand.
Старый 02.06.2017, 01:31   #6  
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).
Старый 02.06.2017, 09:01   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
Кстати, в AX 2012 R3 появились View (InventSumAggrDeltaView и InventSumUnionDeltaPhysicalQty), в которых InventSum и InventSumDelta уже связаны. Идея была в том, чтобы читать остатки из этих View, и не заморачиваться с классами InventOnhand.
Вот именно! Схожие идеи возникают у разных людей.

Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
Идея, вероятно, была неплохая, но реализация подкачала: во View забыли добавить TTSId, и теперь любые запросы к ним блокируют и InventSum, и InventSumDelta целиком.
Похоже не забыли, а поимели сложности с фильтрацией по TTSid. И в итоге пронадеялись на то что можно без фильтрации обойтись - все равно в табличке только незакоммиченные данные лежат, а сессия по идее должна увидеть только свои данные.
(у меня в отношении этого были опасения по блокировкам и они подтвердились )

Вы видите способ штатными средствами аксапты (без редактирования вьюхи в SQL) достичь заявленной цели ?

Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
В блогах и на форумах есть несколько статей, в которых люди пытаются что-то шаманить с индексами на InventSumDelta, чтобы блокировки уменьшить,
Не поделитесь ссылочками ? Интересно посмотреть.

Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
но корень проблемы в том, что InventSumDelta просто неправильно используется в стандартном коде.
Ого ! А как же правильно тогда ? Что там не так ?
Старый 02.06.2017, 18:00   #8  
Ярослав Щекин is offline
Ярослав Щекин
Участник
 
78 / 174 (6) ++++++
Регистрация: 16.03.2009
Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
Обрабатывается. См. InventOnhand.addInventSumDelta().
Подождите, причём тут InventOnhand?
Я говорил про InventDimOnHand, и, по крайней мере, в той версии Ax2009,
в которой я натолкнулся на проблему, записи InventSumDelta с "новыми" InventDimId не обрабатывались.
Поэтому я и спрашивал, не исправлено ли это в каких-то обновлениях.

Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
Идея, вероятно, была неплохая, но реализация подкачала: во View забыли добавить TTSId, и теперь любые запросы к ним блокируют и InventSum, и InventSumDelta целиком.
Вот знаете, просто не верится про любые запросы.
Обновления --- запросто, а вот чтение оттуда без hint-ов, по идее, блокироваться не должно.
Ссылками не поделитесь?
Старый 04.06.2017, 09:02   #9  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,913 / 5736 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
Обрабатывается. См. 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 просто неправильно используется в стандартном коде.
А никто не пробовал ручками подредактировать эти самые view в SQL Management Studio и добавить hint READPAST для InventSumDelta ? В теории, это должно проблему решить раз и навсегда. InventSum будет читаться как и положено - целиком, а в InventSumDelta чужие записи будут проскипаны не из за TTSID, а из за того что эти самые записи заблокированы в чужих транзакциях...
За это сообщение автора поблагодарили: Logger (3).
Теги
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:57.