Как ввести документ основной конфигурации на основании документа из расширения в 1С?

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

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

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

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

Способ 1. Программный вывод кнопки через общую команду (универсальный метод)

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

Разберем процесс по шагам:

Шаг 1. Создание и настройка общей команды в расширении

  1. Откройте конфигуратор и перейдите в дерево метаданных вашего расширения.
  2. Найдите ветку Общие, кликните правой кнопкой мыши по подразделу Общие команды и добавьте новую команду. Назовем её, к примеру, _СоздатьНаОснованииДокументаРасширения.
  3. В палитре свойств созданной команды заполните следующие параметры:
    • Группа: выберите значение Командная панель формы.Создать на основании. Благодаря этому платформа автоматически поместит кнопку команды в стандартное подменю на форме.
    • Тип параметра команды: выберите ссылку на ваш документ-источник, созданный в расширении (например, ДокументСсылка._СборАкцизныхМарок). Это гарантирует, что кнопка отобразится только на формах этого конкретного документа.
    • Режим изменения данных: укажите значение Изменение, так как выполнение команды приведет к созданию новых данных в информационной базе.

Шаг 2. Описание логики открытия формы в модуле общей команды

Нам необходимо перехватить нажатие кнопки пользователем, собрать нужные параметры и передать их при открытии формы документа-приемника. Перейдем в модуль созданной общей команды и напишем следующий код:


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

Шаг 3. Обработка заполнения на стороне документа-приемника

Когда платформа открывает форму нового документа-приемника с параметром ЗначенияЗаполнения, на сервере автоматически вызывается событие ОбработкаЗаполнения. Заимствуем документ-приемник (в нашем примере это ПересчетТоваров) в расширение, откроем модуль его объекта и добавим процедуру-перехватчик с аннотацией &После:


&После("ОбработкаЗаполнения")
Процедура Расш_ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    
    // Проверяем, что данные заполнения переданы и имеют тип структуры
    Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
        
        СсылкаНаОснование = Неопределено;
        Если ДанныеЗаполнения.Свойство("Основание", СсылкаНаОснование) Тогда
            
            // Проверяем тип документа-основания. Он должен соответствовать нашему документу из расширения
            Если ТипЗнч(СсылкаНаОснование) = Тип("ДокументСсылка._СборАкцизныхМарок") Тогда
                
                // Блокируем стандартное заполнение платформы, если это необходимо
                // СтандартнаяОбработка = Ложь; 
                
                // Заполняем реквизиты шапки документа-приемника данными из расширения
                ЭтотОбъект.Комментарий = "Создано автоматически на основании: " + Строка(СсылкаНаОснование);
                ЭтотОбъект.Склад = СсылкаНаОснование.Склад;
                ЭтотОбъект.Ответственный = СсылкаНаОснование.Ответственный;
                
                // Переносим табличную часть
                Для Каждого СтрокаИсточника Из СсылкаНаОснование.Товары Цикл
                    НоваяСтрока = ЭтотОбъект.Товары.Добавить();
                    ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
                    // Дополнительная постобработка строк при необходимости
                КонецЦикла;
                
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Программная интеграция через БСП (для типовых конфигураций)

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

Проанализируем этот изящный способ заполнения:

Шаг 1. Регистрация команды в модуле менеджера документа-источника

Откройте модуль менеджера вашего документа, созданного в расширении (документ-источник), и добавьте экспортную процедуру, которую БСП использует для поиска команд создания на основании:


// Определяет список команд создания на основании, поставляемых этим документом.
//
// Параметры:
//   КомандыСозданияНаОсновании - ТаблицаЗначений - описание колонок см. в БСП.
//   Параметры - Структура - вспомогательные параметры контекста.
//
Процедура ДобавитьКомандыСозданияНаОсновании(КомандыСозданияНаОсновании, Параметры) Экспорт
    
    Команда = КомандыСозданияНаОсновании.Добавить();
    // Указываем полное имя заимствованного документа-приемника из основной конфигурации
    Команда.Получатель = Метаданные.Документы.ПересчетТоваров.ПолноеИмя(); 
    Команда.Представление = НСтр("ru = 'Пересчет товаров (по данным маркировки)'");
    Команда.Порядок = 10;
    Команда.КлючВарианта = "СоздатьИзМаркировки";
    
КонецПроцедуры

После добавления этой процедуры БСП автоматически выведет кнопку в подменю формы вашего документа-источника. При нажатии на неё система сама запустит создание документа-приемника и передаст ссылку на источник в событие ОбработкаЗаполнения.

Шаг 2. Обработка заполнения

Реализация обработчика в модуле объекта документа-приемника пишется аналогично первому способу: заимствуем документ-приемник и описываем процедуру &После("ОбработкаЗаполнения").

Способ 3. Отражение связи в отчете «Связанные документы» (Структура подчиненности)

При вводе документов на основании пользователям крайне важно видеть их взаимосвязь в типовом отчете БСП «Структура подчиненности» (Связанные документы). Поскольку платформа не знает о связи на уровне метаданных, нам придется настроить это поведение вручную.

Рассмотрим алгоритм реализации:

  1. Создание реквизита связи: В расширении добавьте в заимствованный документ-приемник новый реквизит (например, _ДокументОснование) с типом ссылки на ваш документ расширения. Обязательно заполняйте этот реквизит при программном создании документа на основании.
  2. Создание критерия отбора в расширении: Создайте в расширении новый критерий отбора (например, _СвязанныеДокументыРасширения). В свойствах критерия в качестве типа укажите ваш документ расширения, а в его состав включите добавленный реквизит _ДокументОснование документа-приемника.
  3. Переопределение общего модуля БСП: Заимствуйте в расширение общий модуль БСП СтруктураПодчиненностиСлужебный. Найдите в нем функцию, отвечающую за сбор критериев отбора (например, ПолучитьКритерииОтбораСвязанныхДокументов), и переопределите её с помощью аннотации &Вместо:

&Вместо("ПолучитьКритерииОтбораСвязанныхДокументов")
Функция Расш_ПолучитьКритерииОтбораСвязанныхДокументов()
    
    // Получаем стандартный массив критериев отбора из основной конфигурации
    Результат = ПродолжитьВызов();
    
    // Добавляем наш собственный критерий отбора, созданный в расширении
    Результат.Добавить("КритерийОтбора._СвязанныеДокументыРасширения");
    
    Возврат Результат;
КонецФункции

Благодаря этой доработке типовой отчет БСП начнет считывать связи через ваш критерий отбора и будет корректно выстраивать и визуализировать дерево подчиненности прямо на форме.

Особенности хранения данных в расширениях и риски

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

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

← На главную