Как организовать запись из одного документа в два разных регистра сведений на основе значения перечисления

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

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

Шаг 1. Подготовка метаданных и назначение регистратора

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

  1. Откроем в конфигураторе дерево метаданных и найдем наши регистры сведений (например, Поощрения и Взыскания).
  2. Для каждого регистра перейдем на закладку Регистраторы.
  3. В представленном списке документов найдем наш документ и установим напротив него галочку.

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

Шаг 2. Проверка структуры перечисления

Для управления логикой записи мы используем объект типа Перечисление. Предположим, у нас есть перечисление ТипыПоощренийВзысканий со значениями Поощрение и Взыскание. В табличной части документа (назовем ее Состав) есть реквизит ВидОперации, который ссылается на это перечисление.

Рассмотрим ситуацию: нам нужно перебрать все строки таблицы и, в зависимости от выбранного вида, «разложить» их по разным папкам (регистрам). Для этого мы будем использовать стандартную процедуру ОбработкаПроведения, которая располагается в модуле объекта документа.

Шаг 3. Реализация алгоритма проведения

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

Разберем пример кода:


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

КонецПроцедуры

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

Шаг 4. Работа с измерениями и ресурсами

Выясним причину, по которой иногда данные не отображаются в регистре. Чаще всего это связано с незаполненными ключевыми полями. Проанализируем важные моменты:

Шаг 5. Оптимизация для больших документов

Рассмотрим ситуацию, когда в документе не 10 строк, а 10 000. Использование цикла с методом Добавить() может замедлить работу системы. В профессиональной разработке для таких случаев рекомендуется использовать запросы.

Посмотрим на алгоритм оптимизации:

  1. Выгружаем табличную часть документа в запрос.
  2. В запросе разделяем данные (или используем условие ГДЕ, либо просто выбираем все данные с группировкой).
  3. Выгружаем результат запроса во временную таблицу.
  4. Используем метод Загрузить() для набора записей регистра.

Пример использования метода Загрузить:


// Допустим, ТаблицаПоощрений - это результат запроса, выгруженный в таблицу значений
Движения.Поощрения.Загрузить(ТаблицаПоощрений);

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

Резюме

Мы проанализировали, как распределять записи по разным регистрам из одного документа. Ключевые правила здесь: всегда проверять настройки регистратора в метаданных, использовать явную проверку значений перечислений через Перечисления.Имя.Значение и не забывать про заполнение обязательного поля Период для периодических регистров. Соблюдение этих правил обеспечит стабильную работу ваших механизмов проведения и целостность данных в системе.

← На главную