Как правильно реализовать создание документа при проведении другого в 1С?

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

Часто перед начинающими разработчиками 1С встает задача автоматизации бизнес-процессов, которая на первый взгляд кажется простой: «При проведении документа А должен автоматически создаваться документ Б». Однако, погружаясь в разработку, важно осознать, что архитектурно это решение является довольно рискованным. Давайте разберем, почему так происходит и как сделать работу системы надежной и стабильной.

Почему создание документов внутри проведения — это риск?

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

  1. Блокировки: Транзакция становится «тяжелой». Пока документ Б записывается и проводится, таблицы базы данных, к которым он обращается, блокируются. Это может привести к взаимоблокировкам (deadlocks), когда пользователи системы начинают жаловаться на «зависание» программы.
  2. Логическая целостность: Что произойдет, если документ Б не удалось записать? Например, не хватило остатков или сработали проверки заполнения? Вся транзакция проведения документа А откатится, и пользователь получит ошибку.
  3. Управление жизненным циклом: Если документ А был отменен или помечен на удаление, документ Б останется «висеть» в системе как «сирота», если вы не предусмотрите сложную логику отслеживания этих состояний.

Альтернатива 1: Использование механизма «Ввод на основании»

Самый безопасный и логичный путь — делегировать создание документа пользователю. Это стандарт для платформы 1С. Реализуя Ввод на основании, мы даем пользователю возможность проверить данные перед записью.

Чтобы реализовать этот механизм, необходимо настроить Ввод на основании в конфигураторе для документа Б. Это позволит пользователю нажать кнопку в форме документа А и получить готовый, заполненный данными документ Б, который он сможет при необходимости скорректировать.

Альтернатива 2: Использование регистров

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

Рассмотрим создание новых РегистровНакопления или РегистровСведений. Вся логика движений может быть реализована непосредственно в ОбработкаПроведения документа А. Это самый быстрый и производительный способ работы в 1С.

Альтернатива 3: Фоновые задания

Если бизнес-логика требует создания документа именно автоматически, без участия пользователя, разберем вариант использования РегламентныхЗаданий. Вместо прямого создания документа в транзакции:

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

Это исключает влияние на текущую сессию пользователя и гарантирует, что ошибки при создании документа Б не остановят работу пользователя в документе А.

На что обратить внимание, если создание документов необходимо?

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

1. Контроль проведения: Если документ А записался, но не провелся, должен ли существовать документ Б? 2. Повторное проведение: При перепроведении документа А нужно найти уже созданный документ Б (например, по ссылке в реквизите ДокументОснование) и обновить его, а не создавать новый дубль. 3. Отмена проведения: При отмене проведения документа А логично либо пометить документ Б на удаление, либо отменить его проведение.

Рассмотрим пример поиска уже существующего документа:


// Пример поиска документа Б по основанию
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ Ссылка ИЗ Документ.ДокументБ ГДЕ ДокументОснование = &СсылкаНаА";
Запрос.УстановитьПараметр("СсылкаНаА", Ссылка);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
    // Объект уже есть, работаем с ним
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    ОбъектБ = Выборка.Ссылка.ПолучитьОбъект();
КонецЕсли;

В завершение, всегда задавайте вопрос: какую реальную бизнес-задачу мы решаем? Часто выясняется, что документ Б — это лишь способ «обогатить» данные документа А, и его можно заменить дополнительными реквизитами или регистрами. Развивайте свое архитектурное мышление, и система будет работать стабильно!

← На главную