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

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

В процессе разработки в среде 1С:Предприятие 8.3 часто возникает задача расширения стандартного функционала создания документов на основании. Типовые механизмы БСП (Библиотеки стандартных подсистем) автоматически формируют подменю «Создать на основании», но иногда бизнес-логика требует вынести это действие в отдельную кнопку или команду, расположенную в специфическом месте интерфейса. Разберем подробно, как правильно связать произвольную команду с механизмом заполнения нового документа данными из источника.

Анализ механизма создания на основании

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

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

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

Реализация команды на клиенте

Рассмотрим ситуацию, когда нам нужно добавить кнопку в форму или контекстное меню. Основная ошибка начинающих разработчиков — попытка создать объект на сервере и передать его на клиент. Правильный подход заключается в использовании метода ОткрытьФорму с передачей специального параметра Основание.

Проанализируем пример кода обработчика команды, который должен располагаться в модуле формы или в модуле команды документа:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    // ПараметрКоманды — это ссылка на документ-источник (например, РасходнаяНакладная)
    // Подготовим структуру параметров для открытия формы нового документа
    ПараметрыФормы = Новый Структура("Основание", ПараметрКоманды);
    
    // Открываем форму нового документа ЗаявкаНаДоставку
    ОткрытьФорму(
        "Документ.ЗаявкаНаДоставку.ФормаОбъекта", 
        ПараметрыФормы, 
        ПараметрыВыполненияКоманды.Источник, 
        ПараметрыВыполненияКоманды.Уникальность, 
        ПараметрыВыполненияКоманды.Окно, 
        ПараметрыВыполненияКоманды.НавигационнаяСсылка
    );
    
КонецПроцедуры

Важный нюанс: Обратите внимание, что этот код должен выполняться строго &НаКлиенте. Платформа 1С устроена так, что при передаче параметра Основание в функцию ОткрытьФорму, система автоматически инициирует серверный вызов ОбработкаЗаполнения в новом объекте. Это и есть тот «секрет», который позволяет открыть уже заполненную форму, а не пустую.

Обработка заполнения в модуле объекта

Чтобы кнопка действительно работала, в документе-приемнике (в нашем примере это «Заявка на доставку») должна быть прописана логика в модуле объекта. Выясним, как это выглядит изнутри:


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

Используя метод ЗаполнитьЗначенияСвойств, мы значительно ускоряем процесс разработки, если имена колонок в табличных частях обоих документов совпадают.

Работа с множественным выбором

Зачастую команды располагаются в списках документов, где пользователь может выделить сразу несколько строк. В этом случае ПараметрКоманды придет не как одиночная ссылка, а как Массив. Если мы проигнорируем этот факт, код выдаст ошибку. Давайте модифицируем решение, чтобы оно корректно обрабатывало такие ситуации:


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

Регистрация команд в современных конфигурациях (БСП)

Если вы работаете в конфигурации, базирующейся на БСП (УНФ, УТ 11, ERP), рекомендуется использовать штатные механизмы подключения команд. Это позволяет избежать «жесткого» кодирования кнопок в формах. Посмотрим, где обычно ищут регистрацию таких команд:

  1. Модуль менеджера документа: Ищите процедуру ДобавитьКомандыСозданияНаОсновании или ПриОпределенииКомандПодключенныхКОбъекту. Именно здесь описывается, какие документы могут служить основанием для других и в каких подменю будет отображаться кнопка.
  2. Конструктор «Ввод на основании»: В окне конфигурации на вкладке «Ввод на основании» у документа-приемника должен быть отмечен документ-источник. Это создает стандартную связь, которую потом можно использовать в программном коде.

Резюмируем: Для добавления создания на основании в новую команду не нужно заново писать логику переноса данных. Достаточно использовать клиентский метод ОткрытьФорму с ключом "Основание" в структуре параметров. Это обеспечит вызов стандартного обработчика заполнения и корректное открытие формы нового объекта в интерфейсе пользователя.

← На главную