Чем заменить ЭтаФорма при обращении к методам из списка или программного кода

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

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

Разберем детально, как решить эту задачу на примере типовых конфигураций (КА 2.0, ERP, УТ 11) и какие подходы считаются наиболее правильными с точки зрения архитектуры системы.

Анализ проблемы: почему возникает ошибка

Рассмотрим ситуацию, когда в коде вызывается метод клиентского общего модуля, например: УчетНДСУПКлиент.ОбработкаНавигационнойСсылкиСчетаФактурыВыданные(ЭтаФорма, ...). Этот метод ожидает, что первым параметром будет передан контекст управляемой формы. Если мы попытаемся использовать методы типа ПолучитьФорму() в контексте, где интерактивные операции запрещены, или просто передадим ссылку на объект, система выдаст ошибку "Интерактивные операции недоступны" или "Метод объекта не обнаружен".

Проблема заключается в том, что управляемая форма — это сложный объект, содержащий не только данные (Объект), но и элементы управления, уникальный идентификатор сеанса и состояние интерфейса. Если вызываемый метод обращается к этим свойствам, простая передача ссылки не сработает.

Решение 1: Использование структуры-заглушки (Fake Form)

Проанализируем наиболее гибкий способ — создание структуры, которая имитирует минимально необходимый набор свойств управляемой формы. Многие типовые процедуры обращаются только к данным объекта или идентификатору формы. В этом случае мы можем "обмануть" метод, передав вместо формы специально подготовленную структуру.

Посмотрим на пример формирования такой структуры:


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

// Вызываем метод, передавая структуру вместо ЭтаФорма
УчетНДСУПКлиент.ОбработкаНавигационнойСсылкиСчетаФактурыВыданные(ДанныеФормы, НавигационнаяСсылка, СтандартнаяОбработка, ПараметрыРегистрации);

Этот метод эффективен, если вызываемая процедура не пытается манипулировать элементами интерфейса (кнопками, полями ввода), а использует форму только как контейнер для данных.

Решение 2: Передача полного имени формы

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

Выясним, как программно получить полное имя формы, не прописывая его вручную. Для этого в типовых конфигурациях на базе УТ/ERP/КА существует специальный метод:


// Получаем полное имя формы через вызов сервера
ИмяФормы = ОбщегоНазначенияУТВызовСервера.ПолноеИмяФормыОбъекта(ТекущийОбъектСсылка);

// Используем полученную строку в качестве параметра
УчетНДСУПКлиент.ОбработкаНавигационнойСсылкиСчетаФактурыВыданные(ИмяФормы, НавигационнаяСсылка, СтандартнаяОбработка, ПараметрыРегистрации);

Важно: этот способ сработает только в том случае, если логика внутри ОбработкаНавигационнойСсылки... предусматривает проверку типа параметра (объект или строка).

Решение 3: Правильное использование БСП (Библиотеки стандартных подсистем)

Если задача стоит в создании документа (например, Счета-фактуры) на основании другого из формы списка, правильнее всего будет использовать механизмы БСП, а именно подсистему "Создание на основании".

Рассмотрим алгоритм действий для добавления команды без открытия формы реализации:

  1. Зарегистрируйте команду создания на основании в модуле менеджера объекта-основания (например, Реализации).
  2. В процедуре ДобавитьКомандыСозданияНаОсновании укажите параметры отображения команды в списке.
  3. Используйте серверный метод для генерации документа. В современных конфигурациях для массового создания счетов-фактур рекомендуется использовать метод модуля УчетНДСУП.

Пример программного создания счета-фактуры на сервере (наиболее надежный способ):


// Вместо имитации нажатия кнопок на клиенте, вызываем серверную логику
МассивОснований = Новый Массив;
МассивОснований.Добавить(СсылкаНаРеализацию);

СтруктураРезультата = УчетНДСУП.СформироватьСчетаФактурыВыданные(МассивОснований);
// Система создаст документы без участия интерфейса и ЭтаФорма

Решение 4: Доступ к экспортным методам через расширение

Если нужная логика "зашита" в модуле формы и её сложно продублировать, проанализируем возможность использования расширения. Мы можем создать в расширении формы объекта экспортную процедуру-обертку. Однако, чтобы вызвать её, форму всё равно придется получить (хотя бы неявно).

Если вы работаете в форме списка и вам нужны данные конкретной строки, используйте ТекущиеДанные:


ДанныеСтроки = Элементы.Список.ТекущиеДанные;
Если ДанныеСтроки <> Неопределено Тогда
    СсылкаНаОбъект = ДанныеСтроки.Ссылка;
    // Дальнейшая работа со ссылкой через серверные вызовы
КонецЕсли;

Выводы и рекомендации

При замене ЭтаФорма в программном коде придерживайтесь следующих правил:

  1. Приоритет серверной логике: Всегда старайтесь найти аналог клиентского метода в серверных общих модулях (МодульМенеджера, УчетНДСУП, ОбщегоНазначения). Серверные методы никогда не требуют параметр ЭтаФорма.
  2. Проверка контекста: Если метод вызывает Оповестить() или другие интерактивные команды, передача структуры-заглушки может привести к ошибке.
  3. Использование параметров заполнения: Вместо сложной передачи формы используйте метод ОткрытьФорму() с передачей структуры Параметры, где в ключе ЗначенияЗаполнения передана ссылка на основание. Система автоматически выполнит заполнение по правилам метаданных.

Таким образом, замена ЭтаФорма — это не просто поиск аналогичного объекта, а часто пересмотр подхода к решению задачи в пользу отделения бизнес-логики от интерфейсных функций.

← На главную