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