Показать сообщение отдельно
Старый 17.09.2012, 13:09   #13  
someOne is offline
someOne
Участник
Аватар для someOne
 
173 / 423 (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).