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