При активном использовании механизма расширений в системе «1С:Предприятие 8.3» разработчики часто сталкиваются с аппаратными ограничениями платформы. Одно из наиболее частых затруднений связано со стандартным механизмом «Ввод на основании». Рассматриваемая нами ситуация выглядит следующим образом: в расширении создан новый прикладной объект (например, документ-источник), и нам требуется реализовать ввод существующего типового документа (документа-приемника из основной конфигурации) на основании нашего нового документа.
Попытавшись настроить эту связь стандартным визуальным способом в конфигураторе, мы обнаружим проблему. В свойствах заимствованного типового документа в разделе «Вводится на основании» платформа просто не показывает документы, созданные внутри расширения. Платформа 1С строго разделяет области видимости: основная конфигурация не может напрямую ссылаться на метаданные расширения, так как расширение является динамически подключаемым модулем и теоретически может быть отключено в любой момент.
Выясним причину этого ограничения и подробно разберем три проверенных практических способа, как обойти его программным путем и предоставить пользователю удобный, бесшовный интерфейс.
Если вы работаете в самописной конфигурации или в системе, где не используется Библиотека стандартных подсистем (БСП), этот метод является самым надежным. Мы вручную спроектируем общую команду, которая будет автоматически выводиться в командной панели формы нашего документа-источника в подменю «Создать на основании». В качестве альтернативы ручному программированию можно использовать конструктор создания документов на основании с автоматическим копированием реквизитов.
Разберем процесс по шагам:
Шаг 1. Создание и настройка общей команды в расширении
Общие, кликните правой кнопкой мыши по подразделу Общие команды и добавьте новую команду. Назовем её, к примеру, _СоздатьНаОснованииДокументаРасширения.Командная панель формы.Создать на основании. Благодаря этому платформа автоматически поместит кнопку команды в стандартное подменю на форме.ДокументСсылка._СборАкцизныхМарок). Это гарантирует, что кнопка отобразится только на формах этого конкретного документа.Изменение, так как выполнение команды приведет к созданию новых данных в информационной базе.Шаг 2. Описание логики открытия формы в модуле общей команды
Нам необходимо перехватить нажатие кнопки пользователем, собрать нужные параметры и передать их при открытии формы документа-приемника. Перейдем в модуль созданной общей команды и напишем следующий код:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// ПараметрКоманды содержит ссылку на наш документ-источник из расширения.
// Формируем структуру параметров заполнения, где передаем эту ссылку.
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("Основание", ПараметрКоманды);
// Помещаем структуру в специальный системный параметр "ЗначенияЗаполнения"
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
// Открываем форму нового документа-приемника из основной конфигурации.
// Обратите внимание: документ-приемник должен быть предварительно заимствован в расширение!
ОткрытьФорму("Документ.ПересчетТоваров.ФормаОбъекта",
ПараметрыФормы,
ПараметрыВыполненияКоманды.Источник,
ПараметрыВыполненияКоманды.Уникальность,
ПараметрыВыполненияКоманды.Окно,
ПараметрыВыполненияКоманды.НавигационнаяСсылка);
КонецПроцедуры
Шаг 3. Обработка заполнения на стороне документа-приемника
Когда платформа открывает форму нового документа-приемника с параметром ЗначенияЗаполнения, на сервере автоматически вызывается событие ОбработкаЗаполнения. Заимствуем документ-приемник (в нашем примере это ПересчетТоваров) в расширение, откроем модуль его объекта и добавим процедуру-перехватчик с аннотацией &После:
&После("ОбработкаЗаполнения")
Процедура Расш_ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
// Проверяем, что данные заполнения переданы и имеют тип структуры
Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
СсылкаНаОснование = Неопределено;
Если ДанныеЗаполнения.Свойство("Основание", СсылкаНаОснование) Тогда
// Проверяем тип документа-основания. Он должен соответствовать нашему документу из расширения
Если ТипЗнч(СсылкаНаОснование) = Тип("ДокументСсылка._СборАкцизныхМарок") Тогда
// Блокируем стандартное заполнение платформы, если это необходимо
// СтандартнаяОбработка = Ложь;
// Заполняем реквизиты шапки документа-приемника данными из расширения
ЭтотОбъект.Комментарий = "Создано автоматически на основании: " + Строка(СсылкаНаОснование);
ЭтотОбъект.Склад = СсылкаНаОснование.Склад;
ЭтотОбъект.Ответственный = СсылкаНаОснование.Ответственный;
// Переносим табличную часть
Для Каждого СтрокаИсточника Из СсылкаНаОснование.Товары Цикл
НоваяСтрока = ЭтотОбъект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
// Дополнительная постобработка строк при необходимости
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Если вы работаете в современной типовой конфигурации от 1С (такой как 1С:ERP, 1С:КА, 1С:УТ или 1С:БП), интерфейс создания на основании формируется динамически с помощью подсистемы **«Подключаемые команды»** БСП. В этом случае создавать общую команду вручную в дереве метаданных не нужно — библиотека сама сформирует меню, если мы правильно зарегистрируем связь в модуле менеджера.
Проанализируем этот изящный способ заполнения:
Шаг 1. Регистрация команды в модуле менеджера документа-источника
Откройте модуль менеджера вашего документа, созданного в расширении (документ-источник), и добавьте экспортную процедуру, которую БСП использует для поиска команд создания на основании:
// Определяет список команд создания на основании, поставляемых этим документом.
//
// Параметры:
// КомандыСозданияНаОсновании - ТаблицаЗначений - описание колонок см. в БСП.
// Параметры - Структура - вспомогательные параметры контекста.
//
Процедура ДобавитьКомандыСозданияНаОсновании(КомандыСозданияНаОсновании, Параметры) Экспорт
Команда = КомандыСозданияНаОсновании.Добавить();
// Указываем полное имя заимствованного документа-приемника из основной конфигурации
Команда.Получатель = Метаданные.Документы.ПересчетТоваров.ПолноеИмя();
Команда.Представление = НСтр("ru = 'Пересчет товаров (по данным маркировки)'");
Команда.Порядок = 10;
Команда.КлючВарианта = "СоздатьИзМаркировки";
КонецПроцедуры
После добавления этой процедуры БСП автоматически выведет кнопку в подменю формы вашего документа-источника. При нажатии на неё система сама запустит создание документа-приемника и передаст ссылку на источник в событие ОбработкаЗаполнения.
Шаг 2. Обработка заполнения
Реализация обработчика в модуле объекта документа-приемника пишется аналогично первому способу: заимствуем документ-приемник и описываем процедуру &После("ОбработкаЗаполнения").
При вводе документов на основании пользователям крайне важно видеть их взаимосвязь в типовом отчете БСП «Структура подчиненности» (Связанные документы). Поскольку платформа не знает о связи на уровне метаданных, нам придется настроить это поведение вручную.
Рассмотрим алгоритм реализации:
_ДокументОснование) с типом ссылки на ваш документ расширения. Обязательно заполняйте этот реквизит при программном создании документа на основании._СвязанныеДокументыРасширения). В свойствах критерия в качестве типа укажите ваш документ расширения, а в его состав включите добавленный реквизит _ДокументОснование документа-приемника.СтруктураПодчиненностиСлужебный. Найдите в нем функцию, отвечающую за сбор критериев отбора (например, ПолучитьКритерииОтбораСвязанныхДокументов), и переопределите её с помощью аннотации &Вместо:
&Вместо("ПолучитьКритерииОтбораСвязанныхДокументов")
Функция Расш_ПолучитьКритерииОтбораСвязанныхДокументов()
// Получаем стандартный массив критериев отбора из основной конфигурации
Результат = ПродолжитьВызов();
// Добавляем наш собственный критерий отбора, созданный в расширении
Результат.Добавить("КритерийОтбора._СвязанныеДокументыРасширения");
Возврат Результат;
КонецФункции
Благодаря этой доработке типовой отчет БСП начнет считывать связи через ваш критерий отбора и будет корректно выстраивать и визуализировать дерево подчиненности прямо на форме.
При проектировании расширений, содержащих собственные объекты метаданных (документы, справочники, регистры), крайне важно помнить о стабильности СУБД. В старых версиях платформы (8.3.12 и ниже) хранение собственных данных в расширениях сопровождалось высокими рисками сбоев при реструктуризации СУБД и обновлениях конфигураций.
В современных версиях платформы (8.3.15 и выше) стабильность хранения собственных данных существенно возросла. Платформа создает полноценные изолированные физические таблицы в СУБД для объектов расширений. Данные в них надежно сохраняются даже при временном отключении расширения в списке. Тем не менее, всегда придерживайтесь правил безопасной разработки:
_СборАкцизныхМарок). Это исключит конфликты, если в будущих релизах типовой конфигурации от 1С появится объект с аналогичным именем.