Почему при выборе договора в тонком клиенте открываются две формы выбора и как это исправить?

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

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

Анализируем ситуацию: почему открываются две формы?

Рассмотрим типичный сценарий. Программист хочет реализовать кастомный отбор в форме выбора. Для этого используется обработчик события НачалоВыбора. В коде прописывается СтандартнаяОбработка = Ложь, после чего вызывается функция ОткрытьФорму с нужными параметрами. Однако на практике пользователь видит сначала форму с примененным отбором, а следом за ней (или под ней) — стандартную форму без всяких фильтров.

Проанализируем основные причины этого поведения:

  1. Несоответствие количества параметров в процедуре-обработчике. Это самая частая причина, связанная с обновлением платформы до версии 8.3.22 и выше.
  2. Режим совместимости конфигурации. Если код написан под одну версию платформы, а база работает в режиме совместимости с более старой версией, платформа может не «узнать» обработчик.
  3. Особенности работы тонкого клиента. В отличие от толстого клиента, тонкий клиент более чувствителен к корректности передачи контекста и уникальности идентификаторов окон.

Причина №1: Коварный параметр ВыборДобавлением

Выясним, что изменилось в платформе. Начиная с версии 8.3.22, в событие НачалоВыбора для полей ввода был добавлен новый, четвертый параметр — ВыборДобавлением. Он отвечает за возможность множественного выбора элементов без закрытия формы.

Посмотрим на пример кода, который вызывает проблему на версиях младше 8.3.22 или при включенном режиме совместимости:


&НаКлиенте
Процедура ЗаявкаНаОплатуДоговорНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Код открытия формы...
КонецПроцедуры

В чем здесь подвох? Если ваша платформа (или режим совместимости) «ожидает» три параметра (Элемент, ДанныеВыбора, СтандартнаяОбработка), а вы передаете четыре, система просто не находит подходящую процедуру для обработки события. Для платформы это выглядит так, будто обработчик НачалоВыбора вообще не назначен. В результате:

Решение: Проверьте версию вашей платформы и режим совместимости. Если они ниже 8.3.22, удалите параметр ВыборДобавлением. Правильный заголовок процедуры должен выглядеть так:


&НаКлиенте
Процедура ЗаявкаНаОплатуДоговорНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Теперь платформа корректно увидит установку СтандартнаяОбработка в Ложь
КонецПроцедуры

Причина №2: Некорректные параметры функции ОткрытьФорму

Разберем еще один важный аспект, упомянутый опытными разработчиками. Часто при вызове ОткрытьФорму допускаются ошибки в передаче владельца и ключа уникальности. Рассмотрим пример из вопроса:


ОткрытьФорму("Справочник.ДоговорыКонтрагентов.Форма.ФормаВыбора", 
             СтруктураПараметровВыбора, 
             Элемент, 
             Элемент);

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

Как сделать правильно: Проанализируем более надежный способ вызова формы выбора. В качестве владельца формы лучше передавать само поле формы, чтобы платформа знала, куда вернуть результат. А в качестве ключа уникальности — либо уникальный идентификатор текущей формы, либо Истина, если нужно гарантировать открытие нового окна.


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

Пошаговый алгоритм исправления

Рассмотрим по шагам, как гарантированно избавиться от дублирования окон в тонком клиенте:

  1. Проверьте свойства конфигурации. Убедитесь, какой «Режим совместимости» установлен в корне метаданных. Если он ниже «8.3.22», ваш обработчик НачалоВыбора обязан иметь только 3 параметра.
  2. Установите флаг отмены. Строка СтандартнаяОбработка = Ложь; должна идти первой в коде обработчика. Это критически важно для тонкого клиента, чтобы прервать стандартный поток выполнения до обращения к серверу или открытия окон.
  3. Сформируйте структуру отбора. Напомним, что для справочника «Договоры» отбор по контрагенту является наиболее частой задачей.
  4. Вызовите форму программно. Используйте правильную структуру параметров, включая РежимВыбора = Истина.

Посмотрим на финальный, исправленный пример кода, который будет работать стабильно:


&НаКлиенте
Процедура ТЧДоговорНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // 1. Отключаем стандартный механизм
    СтандартнаяОбработка = Ложь;
    
    // 2. Формируем структуру отбора
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Контрагент", Объект.Контрагент);
    СтруктураОтбора.Вставить("ПометкаУдаления", Ложь);
    
    // 3. Подготавливаем параметры для открытия формы
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("Отбор", СтруктураОтбора);
    ПараметрыВыбора.Вставить("РежимВыбора", Истина);
    
    // 4. Открываем форму, указывая Элемент как владельца для автоматической подстановки значения
    ОткрытьФорму("Справочник.ДоговорыКонтрагентов.Форма.ФормаВыбора", 
                 ПараметрыВыбора, 
                 Элемент, 
                 ЭтаФорма.УникальныйИдентификатор);
                 
КонецПроцедуры

Дополнительные рекомендации

Проанализируем ситуацию, когда даже после исправления параметров проблема сохраняется. Это может указывать на баг конкретного релиза платформы. Например, в версиях ветки 8.3.21 наблюдались ошибки взаимодействия тонкого клиента с внешними обработками. В таких случаях помогает обновление платформы до стабильных релизов (например, 8.3.23.1865 и выше), где исправлены ошибки регрессии в механизмах интерактивного выбора.

Также помните, что если вы используете расширения, обработчик в расширении должен полностью дублировать сигнатуру (количество и тип параметров) обработчика в основной конфигурации, иначе вы получите аналогичную проблему с двойным вызовом или игнорированием СтандартнаяОбработка = Ложь.

Таким образом, секрет решения проблемы «двух форм» кроется в строгом соблюдении соответствия вашего кода версии платформы и внимательном управлении параметрами функции ОткрытьФорму. Надеемся, что этот разбор поможет вам избежать подобных ошибок в будущем!

← На главную