При доработке алгоритмов проведения документов в конфигурации «Управление производственным предприятием» (УПП 1.3) разработчики часто сталкиваются с ситуацией: процедура списания партий УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров() отработала успешно, но при обращении к свойству Движения.ПартииТоваровНаСкладах коллекция оказывается пустой. Разберем причины такого поведения платформы и рассмотрим рабочие способы получения сформированных записей прямо в процессе проведения.
Проанализируем внутренний механизм работы партионного учета в УПП. Процедура списания партий выполняет запись движений автономно. Внутри общего модуля создаются отдельные экземпляры наборов записей через вызов РегистрыНакопления.ПартииТоваровНаСкладах.СоздатьНаборЗаписей(). Эти наборы заполняются рассчитанной себестоимостью, партиями и сразу же записываются в базу данных в рамках текущей транзакции.
Платформа 1С:Предприятие не выполняет автоматическую обратную синхронизацию записанных в базу наборов с коллекцией Движения объекта документа, находящегося в оперативной памяти. До явной команды на считывание коллекция Движения.ПартииТоваровНаСкладах остается неинициализированной (пустой).
Самый простой способ загрузить сформированные движения в контекст текущего документа — вызвать метод Прочитать() для нужного регистра сразу после вызова партионного модуля.
// Выполняем типовое списание партий
УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(Ссылка, Движения.СписанныеТовары.Выгрузить());
// Загружаем сформированные движения из базы данных в коллекцию объекта
Движения.ПартииТоваровНаСкладах.Прочитать();
// Теперь таблица движений заполнена и доступна для обхода
Для Каждого Движение Из Движения.ПартииТоваровНаСкладах Цикл
// Обработка полученных записей
КонецЦикла;
Если мы не хотим менять состояние внутренней коллекции документа или работаем в контексте внешней процедуры, где нет прямого доступа к свойству Движения, прочитаем данные через отдельный набор записей с отбором по текущему документу.
НаборПартий = РегистрыНакопления.ПартииТоваровНаСкладах.СоздатьНаборЗаписей();
НаборПартий.Отбор.Регистратор.Установить(Ссылка);
НаборПартий.Прочитать();
Для Каждого Запись Из НаборПартий Цикл
// Обработка движений
КонецЦикла;
Так как формирование партий происходит внутри единой транзакции проведения, СУБД позволяет прочитать только что созданные строки регистра стандартным запросом. Этот способ удобен, если данные необходимо сгруппировать, отфильтровать или соединить с другими таблицами.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Партии.Номенклатура КАК Номенклатура,
| Партии.ДокументОприходования КАК Партия,
| Партии.Количество КАК Количество,
| Партии.Стоимость КАК Стоимость
|ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах КАК Партии
|ГДЕ
| Партии.Регистратор = &Регистратор";
Запрос.УстановитьПараметр("Регистратор", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Работа с выборкой
КонецЦикла;
При работе с движениями партионного учета в УПП 1.3 обязательно учитываем следующие нюансы:
Движения.ПартииТоваровНаСкладах.Записывать принудительно присвоить значение Истина без предварительного выполнения метода Прочитать(), при фиксации транзакции платформа перезапишет движения пустым набором, и списанные партии будут удалены.ДвижениеПартийТоваров не делает движений в момент проведения. В этом случае документ лишь регистрируется в последовательности партионного учета, а расчет себестоимости выполняется позже регламентной обработкой.ПартииТоваровНаСкладах не используется вовсе — все движения формируются по регистрам учета затрат (УчетЗатрат, УчетЗатратРегламентированный).ПартииТоваровНаСкладахБухгалтерскийУчет).