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