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