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