Как создать запись в справочнике на основе данных документа в 1С:Предприятие 8.3

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

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

Анализ проблемы: почему программный код может не срабатывать (поможет анализ конфигурации)

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


&НаСервере
Процедура ПолучательПереводаПриИзмененииНаСервере()
    НовыйЭлемент = Справочники.ИсторияОпераций.СоздатьЭлемент();
    НовыйЭлемент.Наименование = "Запись на основании документа";
    НовыйЭлемент.Дата = Объект.Дата;
    НовыйЭлемент.Клиент = Объект.Клиент;
    НовыйЭлемент.ТипОперации = Объект.ТипОперации;
    НовыйЭлемент.СуммаПеревода = Объект.СуммаПеревода;
    НовыйЭлемент.Записать();
КонецПроцедуры

&НаКлиенте
Процедура ПолучательПереводаПриИзменении(Элемент)
    ПолучательПереводаПриИзмененииНаСервере();
КонецПроцедуры

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

Решение №1: Использование механизма «Ввод на основании»

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

  1. Откроем справочник ИсторияОпераций в дереве метаданных.
  2. Перейдем на вкладку «Ввод на основании».
  3. В списке «Является основанием для» (или в окне конструктора копирования) выберем наш документ ЗаявкаНаПеревод.
  4. Нажмем кнопку «Конструктор ввода на основании». Система предложит сопоставить реквизиты документа и справочника.

После этого в модуле объекта справочника (для сравнения версий пригодится объединение модулей) будет автоматически создана процедура ОбработкаЗаполнения. Рассмотрим ее пример:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаявкаНаПеревод") Тогда
        // Заполняем реквизиты справочника из документа
        Наименование = "Операция по документу " + Строка(ДанныеЗаполнения.Номер);
        Клиент = ДанныеЗаполнения.Клиент;
        СуммаПеревода = ДанныеЗаполнения.СуммаПеревода;
    КонецЕсли;
КонецПроцедуры

Преимущество этого метода: пользователь может нажать кнопку «Создать на основании» в форме документа, и система откроет готовую, заполненную форму нового элемента справочника.

Решение №2: Профессиональный подход через модуль объекта документа

Если нам требуется, чтобы запись в справочнике создавалась автоматически и гарантированно (даже если документ проводится программно, а не интерактивно через форму), использование событий формы (ПриИзменении) не является надежным. Выясним причину: события формы срабатывают только при работе пользователя в интерфейсе.

Правильнее будет использовать процедуру ОбработкаПроведения в модуле объекта документа. Это гарантирует, что запись в истории появится только тогда, когда документ официально проведен и зафиксирован в учете.


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Создаем новую запись в справочнике при проведении
    НоваяЗапись = Справочники.ИсторияОпераций.СоздатьЭлемент();
    
    // Используем эффективный метод заполнения реквизитов
    ЗаполнитьЗначенияСвойств(НоваяЗапись, ЭтотОбъект);
    
    НоваяЗапись.Наименование = "Проведение документа " + Номер;
    НоваяЗапись.ДатаОперации = Дата;
    
    Попытка
        НоваяЗапись.Записать();
    Исключение
        ИнформационноеСообщение = "Не удалось записать историю операций: " + ОписаниеОшибки();
        Сообщить(ИнформационноеСообщение);
    КонецПопытки;
КонецПроцедуры

Оптимизация: Использование функции ЗаполнитьЗначенияСвойств

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

Важный архитектурный совет: Справочники vs Регистры сведений

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

Почему Регистр сведений лучше для истории:

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

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

← На главную