Была подобная задача - получить список ячеек хранения на складе с указанием свободного количества по каждой из ячеек
(по какой то отдельное номенклатуре) внутри транзакции.
Пвтался использовать метод с использованием класса "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. Объеденить два этих набора записей ("сложить" результат).
Это кроме того и самый производительный способ - всего два запроса к БД.