Как записать данные в регистр накопления без использования регистратора в 1С

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

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

Выясним причину: почему регистратор обязателен?

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

Рассмотрим основные технические причины этой связи:

  1. Целостность данных: Поле Регистратор входит в состав уникального индекса таблицы движений в СУБД. На физическом уровне запись не может существовать, если это поле пустое.
  2. Автоматическая очистка: Платформа берет на себя управление жизненным циклом записей. Если документ удаляется или помечается на удаление, связанные с ним записи в регистрах накопления автоматически очищаются. Без регистратора такие записи стали бы «мусором», который невозможно удалить стандартными средствами.
  3. Механизм итогов: Регистры накопления хранят агрегированные данные (итоги). Расчет этих итогов неразрывно связан с хронологией документов.

Давайте посмотрим на типичный ошибочный код, который вызывает данную проблему:


&НаСервере
Функция ПровестиПроводки()
    Набор = РегистрыНакопления.НачисленныеШтрафыИПремии.СоздатьНаборЗаписей();
    Набор.Записывать = Истина;
    
    Для Каждого Стр Из СписокСотрудников Цикл
        Движение = Набор.Добавить();
        Движение.Период = ТекущаяДата();
        Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
        Движение.Сотрудник = Стр.Сотрудник;
        Движение.Сумма = Стр.Сумма;
        // Здесь отсутствует установка регистратора, что приведет к ошибке при записи
    КонецЦикла;
    
    Набор.Записать(); 
КонецФункции

При вызове метода Набор.Записать() система проверит наличие ссылки в поле Регистратор. Если ссылка пустая или не задан фильтр по регистратору, выполнение прервется с ошибкой.

Вариант 1: Использование технического документа (Корректировка записей)

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

Рассмотрим подробнее, как реализовать это в самописной конфигурации. Нам необходимо создать новый документ, назовем его ФиксацияНачислений. В свойствах документа на вкладке «Движения» нужно отметить наш регистр НачисленныеШтрафыИПремии.

Теперь изменим наш код, чтобы он сначала создавал документ, а затем записывал в него движения:


&НаСервере
Процедура ЗаписатьДвиженияЧерезДокумент()
    // 1. Создаем новый документ-регистратор
    ДокОбъект = Документы.ФиксацияНачислений.СоздатьДокумент();
    ДокОбъект.Дата = ТекущаяДата();
    ДокОбъект.Комментарий = "Запись создана обработкой начисления премий";
    ДокОбъект.Записать(); // Получаем ссылку
    
    // 2. Формируем набор записей с фильтром по новому документу
    Набор = РегистрыНакопления.НачисленныеШтрафыИПремии.СоздатьНаборЗаписей();
    Набор.Отбор.Регистратор.Установить(ДокОбъект.Ссылка);
    
    Для Каждого Стр Из СписокСотрудников Цикл
        Движение = Набор.Добавить();
        Движение.Регистратор = ДокОбъект.Ссылка;
        Движение.Период = ДокОбъект.Дата;
        Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
        Движение.Сотрудник = Стр.Сотрудник;
        Движение.Сумма = Стр.Сумма;
    КонецЦикла;
    
    Набор.Записать();
КонецПроцедуры

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

Вариант 2: Переход на независимый регистр сведений

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

Регистры сведений бывают двух типов: подчиненные регистратору и независимые. Рассмотрим преимущества независимого регистра сведений:

Если вам все же нужно получать итоги (суммировать данные), вы всегда сможете сделать это с помощью простого запроса к регистру сведений. Разберем пример записи в независимый регистр:


Набор = РегистрыСведений.НачисленныеШтрафыНезависимый.СоздатьНаборЗаписей();
// Фильтр по периоду или сотруднику, если нужно заменить старые данные
Набор.Отбор.Сотрудник.Установить(ВыбранныйСотрудник); 

НоваяЗапись = Набор.Добавить();
НоваяЗапись.Период = ТекущаяДата();
НоваяЗапись.Сотрудник = ВыбранныйСотрудник;
НоваяЗапись.Сумма = 5000;

Набор.Записать();

Опасные методы и «костыли»: почему не стоит использовать УстановитьСсылкуНового()

Некоторые разработчики пытаются обмануть систему, используя метод УстановитьСсылкуНового(). Суть метода заключается в генерации ссылки на документ без фактической записи самого документа в базу данных. Технически это позволит записать набор записей регистра, указав эту «несуществующую» ссылку в качестве регистратора.

Последствия использования такого метода плачевны:

Никогда не используйте этот метод для постоянного хранения данных. Это считается грубейшей ошибкой проектирования в среде 1С.

Резюме и рекомендации

Подводя итог нашему разбору, можно выделить четкий алгоритм действий при возникновении ошибки записи без регистратора:

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

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

← На главную