Как в 1С реализовать ввод нескольких документов на основании одного

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

Рассмотрим частую задачу, с которой сталкиваются разработчики при автоматизации бизнес-процессов в 1С: необходимо на основании одного исходного документа (например, Заказ покупателя) сформировать не один, а сразу несколько целевых документов (например, несколько документов Заказ поставщику, разнесенных по разным контрагентам или группам товаров).

Штатный механизм платформы 1С — событие ОбработкаЗаполнения в модуле объекта — рассчитан на стандартную инициализацию одного нового документа. Если требуется сформировать пакет документов, стандартной кнопки «Создать на основании» недостаточно. Разберем основные подходы к решению этой задачи на управляемых формах.

Вариант 1. Программное создание пакета документов на сервере без открытия форм

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

Выясним алгоритм работы данного подхода:

  1. На клиенте пользователь нажимает команду формирования документов.
  2. Вызывается серверный метод, который делает запрос к табличной части документа-основания и группирует строки (например, по партнерам или поставщикам).
  3. В цикле по сформированным группам вызывается метод СоздатьДокумент() для каждого нового объекта.
  4. Заполняются реквизиты, табличные части и производится запись с помощью метода Записать().
  5. Возвращенный массив ссылок на новые документы выводится пользователю на форме или в виде оповещения.

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


&НаСервере
Процедура СформироватьЗаказыПоставщикамНаСервере(СсылкаНаЗаказПокупателя)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ЗаказТовары.Поставщик КАК Поставщик,
        |	ЗаказТовары.Номенклатура КАК Номенклатура,
        |	ЗаказТовары.Количество КАК Количество
        |ИЗ
        |	Документ.ЗаказПокупателя.Товары КАК ЗаказТовары
        |ГДЕ
        |	ЗаказТовары.Ссылка = &СсылкаНаЗаказПокупателя
        |ИТОГИ ПО
        |	Поставщик";
    
    Запрос.УстановитьПараметр("СсылкаНаЗаказПокупателя", СсылкаНаЗаказПокупателя);
    РезультатЗапроса = Запрос.Выполнить();
    
    ВыборкаПоставщик = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    Пока ВыборкаПоставщик.Следующий() Цикл
        
        НовыйЗаказ = Документы.ЗаказПоставщику.СоздатьДокумент();
        НовыйЗаказ.Дата = ТекущаяДата();
        НовыйЗаказ.Партнер = ВыборкаПоставщик.Поставщик;
        НовыйЗаказ.ДокументОснование = СсылкаНаЗаказПокупателя;
        
        ВыборкаДетали = ВыборкаПоставщик.Выбрать();
        Пока ВыборкаДетали.Следующий() Цикл
            НоваяСтрока = НовыйЗаказ.Товары.Добавить();
            НоваяСтрока.Номенклатура = ВыборкаДетали.Номенклатура;
            НоваяСтрока.Количество = ВыборкаДетали.Количество;
        КонецЦикла;
        
        Попытка
            НовыйЗаказ.Записать(РежимЗаписиДокумента.Запись);
        Исключение
            ВызватьИсключение "Ошибка при записи документа для поставщика " + ВыборкаПоставщик.Поставщик;
        КонецПопытки;
        
    КонецЦикла;

КонецПроцедуры

Вариант 2. Передача параметров заполнения в форму нового документа

Если необходимо, чтобы создаваемый документ открывался интерактивно для проверки пользователем, используется механизм передаваемых параметров формы. В этом случае на клиенте формируется структура с данными и передается в ключ Основание при открытии формы целевого документа.

Рассмотрим, как это реализуется шаг за шагом:

  1. На клиенте формируем структуру с данными заполнения (или передаем ссылку на документ-основание).
  2. Открываем форму нового документа с помощью функции ОткрытьФорму(), передавая структуру в параметрах.
  3. В модуле объекта нового документа в событии ОбработкаЗаполнения обрабатываем входящую структуру и заполняем реквизиты.

Проанализируем код клиентской части:


&НаКлиенте
Процедура ОткрытьЗаказПоставщикуСДанными(ЗаказПокупателяСсылка, Поставщик)
    
    СтруктураПараметров = Новый Структура;
    СтруктураПараметров.Вставить("ЗаказПокупателя", ЗаказПокупателяСсылка);
    СтруктураПараметров.Вставить("Поставщик", Поставщик);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Основание", СтруктураПараметров);
    
    ОткрытьФорму("Документ.ЗаказПоставщику.ФормаОбъекта", ПараметрыФормы);
    
КонецПроцедуры

В модуле объекта создаваемого документа ЗаказПоставщику описываем событие ОбработкаЗаполнения:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
        
        Если ДанныеЗаполнения.Свойство("ЗаказПокупателя") Тогда
            // Вызываем процедуру заполнения по данным из структуры
            ЗаполнитьПоЗаказуПокупателя(ДанныеЗаполнения.ЗаказПокупателя, ДанныеЗаполнения.Поставщик);
        КонецЕсли;
        
    ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        
        // Стандартная обработка, если передана прямая ссылка
        ЗаполнитьПоЗаказуПокупателя(ДанныеЗаполнения);
        
    КонецЕсли;

КонецПроцедуры

Использование типовых процедур библиотеки (БСП)

В типовых конфигурациях (например, 1С:Управление торговлей, 1С:ERP, 1С:Комплексная автоматизация) заполнение документов часто выносится в отдельные экспортные процедуры общих модулей или модулей менеджеров.

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


// Процедура предназначена для заполнения общих реквизитов документов по документу-основанию.
// Вызывается в обработчиках событий "ОбработкаЗаполнения" в модулях документов.
Процедура ЗаполнитьПоОснованию(ДокументОбъект, ДокументОснование, КопироватьПодразделение = Истина) Экспорт
    
    // Алгоритм копирования шапки и связанных реквизитов
    ДокументОбъект.ЗаполнитьЗначенияСвойств(ДокументОснование);
    
КонецПроцедуры

Особенности работы с контекстом (Клиент / Сервер)

При реализации сложных алгоритмов ввода на основании важно четко разделять контексты выполнения кода:

При вызове создания сразу нескольких документов всегда выносите логику формирования выборки и записи объектов на сервер, возвращая на клиент лишь результаты выполнения операции.

← На главную