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