Как исправить ошибку «Не установлен отбор по регистратору» в 1С при записи движений?

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке механизмов проведения документов в 1С:Предприятие 8, особенно в крупных типовых решениях вроде УПП (Управление производственным предприятием), программисты часто сталкиваются с ошибкой: «Ошибка записи! Не установлен отбор по регистратору». Эта ситуация может поставить в тупик, когда вы работаете с одним регистром, а система сообщает об ошибке в совершенно другом. В данной статье мы подробно разберем, почему возникает эта коллизия и как правильно организовать запись движений в модулях документов или подписках на события.

Суть проблемы и механизм работы коллекции движений

Разберем ситуацию на примере. Программист создает подписку на событие или пишет код в модуле документа для формирования движений по конкретному регистру накопления. При вызове метода Записать() платформа выбрасывает исключение. Самое странное в этой ошибке то, что она часто указывает на регистр, к которому текущий код вообще не обращался (например, в нашем примере это был регистр «Свободные остатки», хотя работа велась с регистром «ДокументыОВПпоЗакупу»).

Для понимания причины нужно рассмотреть, как 1С работает с объектом ДокументОбъект.Движения. Коллекция Движения содержит в себе наборы записей всех регистров, для которых данный документ может быть регистратором. Когда вы обращаетесь к какому-либо регистру через эту коллекцию, например Движения.ИмяРегистра, платформа инициализирует объект НаборЗаписей.

Если в процессе выполнения программного кода (в типовых процедурах, общих модулях или других подписках) произошло обращение к набору записей регистра «Свободные остатки», этот набор помечается как модифицированный. Когда вызывается метод Движения.Записать() (без указания конкретного регистра) или когда процедура ОбработкаПроведения завершается, система пытается записать все наборы записей, у которых свойство Записывать установлено в значение Истина. Если для какого-то из этих «активированных» наборов не был установлен отбор по текущему документу (ссылке), возникает критическая ошибка.

Анализ кода и исправление типичных ошибок

Рассмотрим фрагмент кода, который часто приводит к подобным проблемам, и исправим его. Проанализируем типичную последовательность действий:


// Получаем ссылку на документ
СсылкаДокумента = Документ.Ссылка;

// Обращаемся к конкретному набору записей
ДвиженияДокумента = Документ.Движения.ДокументыОВПпоЗакупу;

// Блокируем и очищаем существующие записи
ДвиженияДокумента.БлокироватьДляИзменения = Истина;
ДвиженияДокумента.Очистить();

// Подготавливаем данные для новой записи
РеквизитыДвижения = Новый Структура();
РеквизитыДвижения.Вставить("Регистратор", СсылкаДокумента);
РеквизитыДвижения.Вставить("Период", СсылкаДокумента.Дата);
РеквизитыДвижения.Вставить("ВидДвижения", ВидДвиженияНакопления.Приход);
// ... заполнение остальных реквизитов

// ВАЖНО: Добавляем запись именно в нужный набор
НовоеДвижение = ДвиженияДокумента.Добавить();
ЗаполнитьЗначенияСвойств(НовоеДвижение, РеквизитыДвижения);

// Записываем ТОЛЬКО этот набор записей
ДвиженияДокумента.Записать();

Обратите внимание на ключевой момент: в коде выше используется ДвиженияДокумента.Записать(). Если использовать просто Движения.Записать() (обращение к глобальной коллекции документа), система попытается сбросить в базу данных все наборы, которые были инициализированы в памяти ранее. Если какой-то другой программный модуль «зацепил» регистр «Свободные остатки» и не установил там отбор, выполнение прервется ошибкой.

Пошаговое решение проблемы

Если вы столкнулись с ошибкой отбора по регистратору, выполните следующие шаги для локализации и устранения проблемы:

  1. Проверьте явную установку отбора. Для каждого набора записей, который вы планируете записывать вручную, обязательно должна быть выполнена установка фильтра. В контексте документа это обычно происходит автоматически, но при создании набора через РегистрыНакопления...СоздатьНаборЗаписей() это нужно делать явно:
    
    Набор = РегистрыНакопления.СвободныеОстатки.СоздатьНаборЗаписей();
    Набор.Отбор.Регистратор.Установить(СсылкаДокумента);
    
  2. Изолируйте запись. Вместо записи всей коллекции Движения.Записать(), всегда используйте запись конкретного регистра: Движения.ИмяВашегоРегистра.Записать(). Это убережет вас от ошибок в чужом или типовом коде.
  3. Проверьте свойство «Записывать». Если вы не хотите, чтобы платформа пыталась записать записи по конкретному регистру, принудительно установите флаг в ложь: Движения.СвободныеОстатки.Записывать = Ложь; Это особенно полезно в конфигурациях типа УПП, где типовые механизмы могут ошибочно помечать наборы к записи.
  4. Анализ «наследия». Если ошибка возникает в регистре, который вы не используете, воспользуйтесь глобальным поиском по конфигурации. Ищите обращение к этому регистру в модуле документа, в модуле объекта и во всех подписках на события, связанных с этим документом. Часто старый код содержит «пустые» вызовы, которые инициализируют набор без установки параметров.
  5. Проверка типов. Убедитесь, что документ, с которым вы работаете, действительно является регистратором для регистра, на который ругается система. Если в метаданных связь отсутствует, любая попытка записи вызовет ошибку прав или структуры.

Особенности работы в серверном варианте и УПП

В серверном варианте 1С отладка может быть затруднена. Если ошибка плавающая или возникает только на сервере, рекомендуется использовать замер производительности или технологический журнал. Выясним причину: часто в УПП логика разнесена по общим модулям (например, ПроведениеСервер), и инициализация набора происходит глубоко в типовом коде при проверке остатков. Если ваша кастомная логика прерывает стандартный поток выполнения, типовой код может оставить набор записей в «подвешенном» состоянии без установленного отбора.

Помните, что метод Движения.Очистить() также помечает набор как модифицированный. Если вы очистили набор записей какого-то регистра «на всякий случай», платформа обязательно потребует установить для него отбор по регистратору перед фиксацией транзакции.

Проанализировав ситуацию, можно сделать вывод: всегда работайте с наборами записей максимально адресно. Не используйте общие методы записи коллекции движений, если не уверены в чистоте кода всего модуля документа. Это гарантирует стабильную работу ваших доработок даже в условиях сложной, многократно модифицированной конфигурации.

← На главную