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