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