В процессе разработки и автоматизации бизнес-процессов на платформе 1С:Предприятие 8.3 одной из наиболее часто встречающихся задач является программное создание документов. Это необходимо при реализации механизмов импорта данных из внешних систем, разработке обработок для пакетного формирования документов или при настройке сложных цепочек взаимосвязанных операций (поможет автоматическая настройка создания цепочек документов), таких как создание внутренних потреблений на основании перемещений. В данной статье мы подробно разберем, как правильно инициализировать объект документа, заполнить его данные и обеспечить корректное проведение в системе.
Для начала работы нам необходимо создать экземпляр объекта документа. В системе 1С это выполняется через менеджер соответствующего типа документа. Рассмотрим ситуацию на примере создания документа РеализацияТоваровУслуг. Отметим, что в типовых конфигурациях часто требуется дополнительно реализовать создание счета на оплату на основании реализации. Проанализируем базовый синтаксис:
НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// Установка даты и номера (номер обычно присваивается автоматически при записи)
НовыйДокумент.Дата = ТекущаяДата();
// Заполнение основных реквизитов шапки
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Основная организация");
НовыйДокумент.Контрагент = Справочники.Контрагенты.НайтиПоКоду("00001");
Важно помнить, что при использовании метода СоздатьДокумент() объект создается только в оперативной памяти сервера. Чтобы он появился в базе данных, его необходимо будет записать. На данном этапе мы также рекомендуем использовать метод ЗаполнитьЗначенияСвойств(), если у вас есть структура с данными, что значительно сокращает объем кода и упрощает его чтение.
В типовых конфигурациях 1С (таких как ERP, КА или УТ) многие реквизиты должны заполняться по определенным правилам (например, счета учета или ответственные лица). Чтобы не прописывать это вручную, рассмотрим применение стандартного механизма заполнения:
// Вызов стандартного механизма заполнения при создании
НовыйДокумент.Заполнить(Неопределено);
Этот метод инициирует событие ОбработкаЗаполнения в модуле объекта. Проанализируем преимущество: система автоматически подставит значения из настроек пользователя или параметров учета, что снижает риск возникновения ошибок из-за незаполненных обязательных полей.
Почти каждый документ содержит табличные части (например, список товаров или услуг). Разберем по шагам процесс добавления строк и их заполнения. Подобная логика часто используется, когда реализуется создание документов «Чек ККМ» на основании заказа клиента. Для этого используется метод Добавить() у соответствующей табличной части объекта.
// Обращение к табличной части "Товары"
НоваяСтрока = НовыйДокумент.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Монитор 24 дюйма");
НоваяСтрока.Количество = 10;
НоваяСтрока.Цена = 15000;
// Сумма часто рассчитывается автоматически в типовых, но мы укажем её явно для примера
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
Если табличная часть содержит большое количество строк, мы рекомендуем предварительно подготовить данные в ТаблицаЗначений, а затем использовать метод Загрузить(). Этот подход работает значительно быстрее, чем добавление каждой строки в цикле, особенно при больших объемах данных.
После того как все реквизиты заполнены, документ необходимо сохранить. В 1С существует несколько режимов записи. Выясним причину, почему важно правильно выбирать режим:
РежимЗаписиДокумента.Запись) — данные сохраняются в базе, но не делают движений по регистрам. Документ считается "черновиком".РежимЗаписиДокумента.Проведение) — данные сохраняются и формируются проводки (движения по регистрам).Рассмотрим пример корректного проведения с обработкой возможных исключений:
Попытка
// Записываем документ с проведением
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ успешно создан и проведен: " + НовыйДокумент.Ссылка);
Исключение
// Обработка ошибок (например, нехватка остатков на складе)
ТекстОшибки = КраткоеОписаниеОшибки(ИнформацияОбОшибке());
Сообщить("Не удалось провести документ. Причина: " + ТекстОшибки);
КонецПопытки
Посмотрим на важный нюанс: если вы создаете документы в рамках массовой загрузки, стоит использовать свойство ОбменДанными.Загрузка = Истина. Это позволит отключить лишние проверки (например, контроль остатков или проверку заполнения), что существенно ускорит процесс записи, но требует полной уверенности в корректности загружаемых данных.
Когда мы создаем не один документ, а цепочку (например, создание заказа клиента на основании заказа поставщику), необходимо гарантировать, что либо создадутся оба документа, либо ни одного. Для этого проанализируем ситуацию с использованием механизма транзакций:
НачатьТранзакцию();
Попытка
// Пример: создание заказа поставщику на основании приобретения
// Создание заказа поставщику из приобретения товаров
Заказ = Документы.ЗаказПоставщику.СоздатьДокумент();
// ... заполнение реквизитов ...
Заказ.Записать(РежимЗаписиДокумента.Проведение);
// Создание связанного документа
Приобретение = Документы.ПриобретениеТоваровУслуг.СоздатьДокумент();
Приобретение.Заполнить(Заказ.Ссылка);
Приобретение.Записать(РежимЗаписиДокумента.Проведение);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
// Логирование ошибки
КонецПопытки
Использование НачатьТранзакцию() и ЗафиксироватьТранзакцию() — это лучшая практика при программном изменении данных, так как она защищает базу от появления "битых" или неполных цепочек документов в случае внезапного сбоя сервера или ошибки в коде.
Если для заполнения документа требуются сложные расчеты или получение данных из множества таблиц БД, рассмотрим использование запросов с временными таблицами. Это эффективнее, чем обращение к объектам в цикле. Мы можем получить все необходимые остатки или цены одним запросом, выгрузить их в таблицу значений и далее распределить по создаваемым документам.
Использование объекта МенеджерВременныхТаблиц позволяет хранить промежуточные результаты запроса в памяти SQL-сервера, что на порядок быстрее, чем многократные вызовы НайтиПоНаименованию() или обращение к реквизитам через точку внутри цикла.
Мы рассмотрели полный цикл программной работы с документом в 1С: от инициализации объекта до его проведения и обработки ошибок. Помните, что ключ к стабильной работе системы — это использование транзакций, проверка заполнения обязательных полей через Заполнить() и минимизация обращений к базе данных в циклах. Следуя этим правилам, вы сможете создавать надежные и быстрые механизмы автоматизации для любых конфигураций на платформе 8.3.