| 
	 | 
| 
			
			 | 
		#1 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Была подобная задача - получить список ячеек хранения на складе с указанием свободного количества по каждой из ячеек  
		
		
		
		
		
		
		
	(по какой то отдельное номенклатуре) внутри транзакции. Пвтался использовать метод с использованием класса "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). | |
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Спасибо большое Raz и SomeOne! 
		
		
		
		
		
		
		
	Метод с получением двух query для InventSum и InventSumDelta с последубщими добавлениями в них дополнительных источников данных универсален для всех задач. С последующим суммированием результата через inventSum.addInventSumDelta(inventSumDelta); Я все понял. Осталось заставить себя в следующий раз применить этот способ, а не считать по-старинке прямыми запросами ![]() Еще один способ - оптимизировать код таким образом, чтобы алгоритму было без разницы, внутри транзакции идет подсчет остатков или за ее пределами, и в этом случае вынести подсчет остатков за пределы транзакции. Это самый оптимальный вариант, но к сожалению не всегда допустимый. В общем, подсчет остатков - деликатная и объемная тема, достойная диссертации.  
		 | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Извините, что поднимаю старую тему... 
		
		
		
		
		
		
		
	Коллеги, а Вам не кажется, что вот это: Цитата: 
	
Может быть, это исправлено в каком-то SP?  | 
| 
	
 | 
| 
			
			 | 
		#4 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Это не косяк, а так спроектировано. Если сразу добавлять запись (пусть и с пустыми остатками) в InventSum одновременно с созданием InventSumDelta, то можно нарваться на блокировки/конфликт уникального ключа. А InventSumDelta как раз и делали, чтобы этого избежать.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#5 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Подождите, причём тут внесение записи в InventSum? Мне было непонятно, почему InventSumDelta не обрабатывается в классе  InventDimOnHand.
		 
		
		
		
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 Administrator 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
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). | |
| 
			
			 | 
		#7 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Цитата: 
	
(у меня в отношении этого были опасения по блокировкам и они подтвердились    )Вы видите способ штатными средствами аксапты (без редактирования вьюхи в SQL) достичь заявленной цели ? Цитата: 
	
Ого ! А как же правильно тогда ? Что там не так ?  | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Подождите, причём тут InventOnhand? 
		
		
		
		
		
		
		
	Я говорил про InventDimOnHand, и, по крайней мере, в той версии Ax2009, в которой я натолкнулся на проблему, записи InventSumDelta с "новыми" InventDimId не обрабатывались. Поэтому я и спрашивал, не исправлено ли это в каких-то обновлениях. Цитата: 
	
Обновления --- запросто, а вот чтение оттуда без hint-ов, по идее, блокироваться не должно. Ссылками не поделитесь?  | 
| 
	
 | 
| 
			
			 | 
		#9 | 
| 
			
			 Moderator 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Сообщение от 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 просто неправильно используется в стандартном коде.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: Logger (3). | |
| Теги | 
| ax2009, inventsumaggrdeltaview, inventsumdelta, inventsumuniondeltaphysicalqty, как правильно, остатки, транзакции | 
| 
	
	 | 
	
		
  |