Как правильно реализовать запись из справочника в регистр сведений и избежать ошибок

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

В практике разработки на платформе 1С нередко возникают задачи, когда данные, вводимые в справочнике, должны дублироваться или фиксироваться в регистре сведений. Несмотря на то что термин «движения» традиционно относится к документам, программная запись в регистры из справочников — это стандартная задача для хранения настроек, цен, дополнительных характеристик или истории изменений объекта. Рассмотрим подробнее, как реализовать этот механизм корректно, избегая типичных ошибок новичков.

Разберем причину ошибки «Не установлен отбор по регистратору»

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

В системе 1С существует два режима записи в регистр сведений:

  1. Подчинение регистратору: записи могут создаваться только документами, которые указаны в списке «Регистраторы» данного регистра. В этом случае у каждой записи есть обязательное поле Регистратор.
  2. Независимый режим: записи могут создаваться программно из любого места (обработки, справочники, модули) без привязки к документу.

Если вы пытаетесь писать в регистр из справочника и получаете вышеуказанную ошибку, это означает, что ваш регистр имеет режим записи «Подчинение регистратору». Помните: справочник не может быть регистратором. Единственный способ записывать данные в такой регистр из справочника — это создавать вспомогательный документ, что архитектурно не всегда оправдано. Поэтому для работы со справочником в свойствах регистра на вкладке «Основные» должен быть установлен режим записи «Независимый».

Выбор между Менеджером записи и Набором записей

Посмотрим на два основных инструмента для работы с записями регистра. Программисту доступны РегистрСведенийМенеджерЗаписи и РегистрСведенийНаборЗаписей. Выбор зависит от конкретной задачи.

Менеджер записи удобен, если нам нужно работать с одной-единственной строкой регистра. Он ведет себя подобно объекту (как справочник или документ): мы можем его прочитать, изменить ресурсы и записать. Однако при работе из справочника, особенно если у одного элемента справочника может быть несколько строк в регистре, использование менеджера записи становится неэффективным.

Набор записей — это более мощный инструмент. Проанализируем ситуацию: когда мы нажимаем кнопку «Записать» в справочнике, нам нужно актуализировать данные в регистре. Набор записей позволяет одним вызовом метода Записать() удалить старые данные по конкретному объекту и записать новые.

Правильная работа с Набором записей и установка отбора

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


НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Номенклатура = СсылкаНаСправочник;
НоваяЗапись.Цена = 100;
НаборЗаписей.Записать(); // ВНИМАНИЕ: Это удалит ВСЕ записи в регистре перед записью одной новой!

Чтобы не «похерить» все данные, мы обязательно должны использовать Отбор. Метод Записать() без установленного отбора очищает весь регистр.

Разберем правильный алгоритм по шагам:

  1. Создаем объект НаборЗаписей.
  2. Устанавливаем фильтр (отбор) по измерению, которое связывает регистр со справочником (например, Номенклатура или Владелец).
  3. Заполняем набор данными.
  4. Вызываем метод Записать().

Посмотрим на корректный пример реализации:


// Код в модуле объекта справочника
Набор = РегистрыСведений.ДополнительныеСведения.СоздатьНаборЗаписей();
// Устанавливаем жесткий отбор по текущему объекту
Набор.Отбор.Объект.Установить(ЭтотОбъект.Ссылка);

// Если нужно добавить новые записи из табличной части справочника
Для Каждого СтрокаТЧ Из ЭтотОбъект.Состав Цикл
    НоваяЗапись = Набор.Добавить();
    НоваяЗапись.Объект = ЭтотОбъект.Ссылка;
    НоваяЗапись.Свойство = СтрокаТЧ.Свойство;
    НоваяЗапись.Значение = СтрокаТЧ.Значение;
КонецЦикла;

// Система удалит старые записи только по ЭТОМУ объекту и запишет новые
Набор.Записать();

Где именно писать код: выбор обработчика событий

Часто новички пишут логику в Модуле формы (например, в событии ПослеЗаписиНаСервере). Это допустимо, но не является хорошей практикой.

Почему лучше использовать Модуль объекта? Если данные в справочник будут загружаться программно, код в форме просто не сработает. Чтобы данные в регистре всегда были актуальными, используйте обработчик ПриЗаписи. Однако, если вам требуется сложная логика, выполняемая строго после завершения транзакции, можно внедрить самодельный обработчик ПослеЗаписи объекта.

Также не забывайте про ПередУдалением — это обязательное место для очистки регистра. В отличие от подчиненных регистров, данные в независимом регистре не удаляются автоматически при удалении элемента справочника.

Особенности периодических регистров

Если ваш регистр сведений является периодическим, важно помнить о поле Период. При записи из справочника вы должны явно указать дату (например, ТекущаяДата() или реквизит объекта). Если не заполнить период, 1С запишет данные на 01.01.0001, что приведет к ошибкам в отчетах.

Проблема «задвоения» и контроль уникальности

В независимом регистре уникальность записи определяется набором его Измерений. Если вы используете НаборЗаписей с установленным отбором по ключевому измерению, задвоение вам не грозит, так как набор полностью перезаписывает данные по этому фильтру. Всегда проверяйте, чтобы набор измерений в регистре был достаточным для обеспечения уникальности ваших данных в контексте одного элемента справочника.

← На главную