Как программно создать и провести документ "Реализация товаров и услуг" в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке обработок загрузки данных, интеграций с внешними системами или создании механизмов автоматического биллинга, мы часто сталкиваемся с необходимостью программного создания документов. Рассмотрим подробно, как правильно создать, заполнить и провести документ на примере конфигурации "Управление торговлей", хотя описанные принципы применимы к большинству конфигураций на платформе 1С:Предприятие 8.3.

В этой статье мы разберем процесс пошагово: от инициализации объекта до корректной обработки ошибок при проведении.

1. Создание объекта документа

Первым шагом нам необходимо обратиться к менеджеру документов конкретного типа. Для создания нового экземпляра документа используется метод СоздатьДокумент(). Важно понимать, что этот метод создает объект в оперативной памяти сервера, но еще не записывает его в базу данных.

Посмотрим на базовый пример инициализации:


// Получаем менеджер документа и создаем новый объект
НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

// Устанавливаем дату документа. Обычно это текущая дата сеанса
НовыйДокумент.Дата = ТекущаяДата();

Важно: Если вы загружаете документы "задним числом", обязательно устанавливайте время документа в конец дня или на конкретное время, чтобы избежать нарушений хронологии списания остатков.

2. Заполнение обязательных реквизитов шапки

Чтобы документ мог быть записан и, тем более, проведен, необходимо заполнить ключевые реквизиты шапки: Организацию, Контрагента, Склад, Валюту и другие данные, зависящие от настроек вашей системы. Рассмотрим заполнение основных полей.

Особое внимание уделим ссылкам на справочники. Убедимся, что мы передаем именно ссылки, а не строки или объекты.


// Заполняем реквизиты шапки
// Предположим, что переменные ОрганизацияСсылка, КонтрагентСсылка и СкладСсылка уже определены заранее
НовыйДокумент.Организация = ОрганизацияСсылка;
НовыйДокумент.Контрагент = КонтрагентСсылка;
НовыйДокумент.Партнер = ПартнерСсылка; // В УТ 11 и ERP есть разделение на Партнеров и Контрагентов
НовыйДокумент.Склад = СкладСсылка;
НовыйДокумент.Валюта = Константы.ВалютаУправленческогоУчета.Получить();
НовыйДокумент.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.РеализацияКлиенту;

В современных конфигурациях (ERP, УТ 11, КА 2) часто используется механизм "Соглашений" и "Договоров". Если они включены в настройках, их заполнение также обязательно:


НовыйДокумент.Соглашение = СоглашениеСсылка;
НовыйДокумент.Договор = ДоговорСсылка;

3. Заполнение табличной части "Товары"

После заполнения шапки перейдем к наполнению документа товарами. Для этого мы работаем с коллекцией строк табличной части, используя метод Добавить().

Проанализируем пример добавления строки с номенклатурой:


// Добавляем новую строку в табличную часть "Товары"
НоваяСтрока = НовыйДокумент.Товары.Добавить();

// Заполняем данные строки
НоваяСтрока.Номенклатура = НоменклатураСсылка;
НоваяСтрока.Количество = 10;
НоваяСтрока.Цена = 1500;
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;

// Рассчитываем сумму НДС
НоваяСтрока.СуммаНДС = НоваяСтрока.Сумма * 0.2 / 1.2; // Пример упрощенного расчета

В типовых конфигурациях часто существуют служебные процедуры для пересчета сумм, которые позволяют избежать ручных математических вычислений и ошибок округления. Например, в общих модулях могут быть функции типа РассчитатьСумму() или ОбработкаТабличнойЧастиТовары(). Если вы разрабатываете внутри конкретной конфигурации, рекомендуем изучить модуль объекта документа на наличие экспортных процедур пересчета.

4. Запись и проведение документа

Финальный этап — сохранение изменений в базе данных. Здесь у нас есть два пути: просто записать документ (сохранить черновик) или провести его (отразить движения в регистрах).

Для управления этим процессом используется метод Записать(), который принимает параметр типа РежимЗаписиДокумента.

Рассмотрим код для проведения документа:


Попытка
    // Попытка провести документ
    НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
    Сообщить("Документ успешно создан и проведен: " + НовыйДокумент.Ссылка);
Исключение
    // В случае ошибки выводим информацию и не прерываем выполнение всего кода (если это цикл)
    Сообщить("Ошибка при проведении документа: " + ОписаниеОшибки());
    
    // Можно попробовать записать непроведенным, чтобы сохранить данные
    Попытка
        НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
        Сообщить("Документ сохранен как черновик (не проведен).");
    Исключение
        Сообщить("Не удалось даже записать документ.");
    КонецПопытки;
КонецПопытки;

5. Оптимизация при массовом создании

Если ваша задача подразумевает создание сотен или тысяч документов за один раз (например, загрузка из Excel), крайне важно использовать транзакции и оптимизировать запись.

  1. Используйте НачатьТранзакцию() и ЗафиксироватьТранзакцию() для пакетов документов (например, по 50-100 штук), чтобы ускорить процесс и обеспечить целостность данных.
  2. Если логика позволяет, используйте свойство ОбменДанными.Загрузка = Истина. Это отключает многие проверки при записи и регистрацию изменений для планов обмена, что существенно ускоряет процесс. Однако, будьте осторожны: при этом режиме документ может записаться с некорректными данными, так как проверки отключены.

Пример оптимизированной записи для загрузки данных:


НовыйДокумент.ОбменДанными.Загрузка = Истина;
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись); 
// Примечание: Проведение с установленным флагом Загрузка = Истина не создаст движений 
// в большинстве типовых конфигураций, поэтому флаг нужно снимать перед проведением
// или использовать метод Записать() без флага загрузки, если нужны движения.

Разберем правильный подход к массовому проведению:


НачатьТранзакцию();
Попытка
    // ... создание и заполнение документа ...
    
    НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    Сообщить("Ошибка в транзакции: " + ОписаниеОшибки());
КонецПопытки;

Следуя этим инструкциям, вы сможете создать надежный механизм генерации документов в 1С, который будет устойчив к ошибкам и понятен для дальнейшей поддержки.

← На главную