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