Как правильно открыть вторую форму внешней обработки на клиенте в 1С 8.3

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

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

Почему возникает ошибка «Неизвестное имя формы»?

Когда мы работаем в составе основной конфигурации, система заранее знает все пути к объектам. Для внешней обработки, запущенной из файла, ситуация иная. Внешняя обработка в момент выполнения получает уникальное внутреннее имя в сеансе. Если мы просто напишем "ФормаНастройкиЗаполнения", система будет искать эту форму в составе общих форм конфигурации или среди объектов метаданных самой конфигурации, но не внутри «безымянного» для неё внешнего файла.

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

Способ 1. Использование полного статического пути

Рассмотрим вариант, когда мы точно знаем имя нашей обработки в конфигураторе. Полное имя формы внешней обработки строится по шаблону: ВнешняяОбработка.[ИмяОбработки].Форма.[ИмяФормы].

Проанализируем пример кода:


&НаКлиенте
Процедура КомандаОткрытьНастройки(Команда)
    
    ПараметрыФормы = Новый Структура;
    // Указываем полный путь к форме
    ИмяФормы = "ВнешняяОбработка.ЗагрузкаДанныхИзExcel.Форма.ФормаНастройкиЗаполнения";
    
    ОткрытьФорму(ИмяФормы, ПараметрыФормы, ЭтаФорма);
    
КонецПроцедуры

Важный нюанс: Этот способ сработает только в том случае, если имя обработки внутри файла (свойство «Имя» в конфигураторе) совпадает с тем, что вы написали в строке. Если пользователь переименует файл, это не страшно, но если вы измените имя объекта в метаданных — код придется переписывать.

Способ 2. Динамическое формирование имени (Универсальный метод)

Чтобы сделать код более гибким и не зависеть от жестко заданных имен, мы можем воспользоваться свойством ИмяФормы текущей (уже открытой) формы. Это самый надежный метод, который рекомендуют опытные разработчики.

Выясним причину эффективности этого метода: свойство ЭтаФорма.ИмяФормы уже содержит правильный префикс, который система присвоила внешней обработке при открытии. Нам остается лишь заменить имя текущей формы на имя нужной нам формы.

Разберем реализацию:


&НаКлиенте
Процедура ОткрытьВторуюФормуДинамически()
    
    // Получаем текущее имя: "ВнешняяОбработка.ИмяОбъекта.Форма.ОсновнаяФорма"
    ТекущееИмяФормы = ЭтаФорма.ИмяФормы;
    
    // Находим позицию последней точки, чтобы отсечь имя текущей формы
    ЧастиИмени = СтрРазделить(ТекущееИмяФормы, ".");
    
    // Заменяем последний элемент массива на имя новой формы
    ЧастиИмени[ЧастиИмени.ВГраница()] = "ФормаНастройкиЗаполнения";
    
    // Собираем путь обратно
    ПолныйПутьКФорме = СтрСоединить(ЧастиИмени, ".");
    
    ОткрытьФорму(ПолныйПутьКФорме, , ЭтаФорма);
    
КонецПроцедуры

Или более лаконичный вариант через СтрЗаменить (если вы уверены, что имя формы уникально внутри строки):


&НаКлиенте
Процедура ОткрытьВторуюФормуЛаконично()
    
    ИмяНужнойФормы = "ФормаНастройкиЗаполнения";
    ПолныйПуть = СтрЗаменить(ЭтаФорма.ИмяФормы, "ФормаУправляемая", ИмяНужнойФормы); 
    // Примечание: "ФормаУправляемая" здесь — это имя формы, из которой вызываем.
    
    ОткрытьФорму(ПолныйПуть, , ЭтаФорма);
    
КонецПроцедуры

Передача владельца формы: распространенная ошибка

В исходном вопросе автора часто встречается код: ОткрытьФорму(..., ЭтотОбъект, ...). Проанализируем ситуацию: в управляемом приложении параметр Владелец ожидает тип УправляемаяФорма или ЭлементУправления, но никак не ЭтотОбъект (который на клиенте является типом ДанныеФормыСтруктура).

Правильно передавать в качестве владельца ЭтаФорма. Это обеспечит корректную связь между окнами: если основная форма будет закрыта, форма настроек закроется автоматически.

Особенности работы во внешних обработках на базе БСП

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

В этом случае использование ЭтаФорма.ИмяФормы — единственный способ программно открыть другие формы этой же обработки.

Передача данных между формами

Зачастую вторую форму нужно не просто открыть, но и передать в неё какие-то данные или настройки. Для этого используется структура Параметры.

Рассмотрим пример на стороне вызывающей формы:


&НаКлиенте
Процедура ОткрытьСПараметрами()
    
    ПараметрыЗапуска = Новый Структура;
    ПараметрыЗапуска.Вставить("РежимРаботы", "Расширенный");
    ПараметрыЗапуска.Вставить("ТекущийПользователь", ИмяПользователя());
    
    Путь = СтрЗаменить(ЭтаФорма.ИмяФормы, "ОсновнаяФорма", "ФормаНастройки");
    
    ОткрытьФорму(Путь, ПараметрыЗапуска, ЭтаФорма);
    
КонецПроцедуры

И на стороне открываемой формы (в модуле формы):


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("РежимРаботы") Тогда
        Заголовок = "Настройки (Режим: " + Параметры.РежимРаботы + ")";
    КонецЕсли;
    
КонецПроцедуры

Разница между ОткрытьФорму() и ПолучитьФорму()

Посмотрим на два метода работы с формами:

  1. ОткрытьФорму — быстрый способ. Система сама создает экземпляр формы и выводит его на экран. Это наиболее подходящий вариант для большинства задач.
  2. ПолучитьФорму — позволяет гибко настроить объект формы до того, как пользователь его увидит. Вы можете программно изменить заголовок, видимость кнопок или состав динамического списка, а затем вызвать метод Открыть().

Пример использования ПолучитьФорму:


&НаКлиенте
Процедура ТонкаяНастройкаИОткрытие()
    
    Путь = СтрЗаменить(ЭтаФорма.ИмяФормы, "Форма1", "Форма2");
    НоваяФорма = ПолучитьФорму(Путь);
    
    // Произвольные манипуляции с формой
    НоваяФорма.Заголовок = "Специальный заголовок от " + ТекущаяДата();
    НоваяФорма.ТолькоПросмотр = Истина;
    
    НоваяФорма.Открыть();
    
КонецПроцедуры

Подведем итог: для работы с формами внешних обработок всегда используйте динамическое получение пути через ЭтаФорма.ИмяФормы. Это избавит вас от проблем при переименовании объектов, при использовании обработки в составе БСП и обеспечит стабильную работу кода в любых условиях.

← На главную