Как программно запустить стандартный выбор элемента в управляемой форме 1С

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

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

Стандартными средствами встроенного языка метод типа Элементы.ИмяПоля.ВыполнитьВыбор() не предусмотрен. Однако существует несколько эффективных стратегий, которые позволяют добиться нужного результата. Разберем их подробно, двигаясь от простых "хакерских" методов к более архитектурно правильным подходам.

Способ 1. Имитация нажатия клавиши F4 (метод SendKeys)

Проанализируем самый быстрый способ — программную эмуляцию действий пользователя. Платформа 1С во многих аспектах опирается на стандартные горячие клавиши операционной системы. Если мы "заставим" систему думать, что пользователь нажал F4, находясь в нужном поле, откроется стандартное окно выбора.

Для реализации этого метода нам понадобится COM-объект WScript.Shell. Рассмотрим пошагово, как это работает:

  1. Сначала необходимо передать фокус на элемент формы, для которого мы хотим вызвать выбор.
  2. Затем вызвать метод отправки клавиш в активное окно.

Посмотрим на пример кода:


&НаКлиенте
Процедура ВызватьВыборПрограммно()
    // Устанавливаем фокус на нужный элемент
    ЭтаФорма.ТекущийЭлемент = Элементы.ИмяВашегоРеквизита;
    
    // Создаем объект для управления вводом ОС
    Попытка
        ОбъектWshShell = Новый COMОбъект("WScript.Shell");
        // Отправляем нажатие клавиши F4
        ОбъектWshShell.SendKeys("{F4}");
    Исключение
        Сообщить("Метод SendKeys не поддерживается в данной среде.");
    КонецПопытки;
КонецПроцедуры

Важное ограничение: данный метод будет работать исключительно в тонком и толстом клиенте под управлением ОС Windows. Если ваш пользователь работает через веб-клиент (в браузере) или на Linux, этот код не сработает.

Способ 2. Использование обработчика ожидания для фиксации фокуса

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

Чтобы гарантировать успех, применим "хитрость" с небольшим ожиданием:


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

&НаКлиенте
Процедура ВыполнитьНажатиеF4()
    ОбъектWshShell = Новый COMОбъект("WScript.Shell");
    ОбъектWshShell.SendKeys("{F4}");
КонецПроцедуры

Этот подход особенно полезен при работе с табличными частями, когда фокус нужно установить не только на колонку, но и на конкретную строку через Элементы.ИмяТаблицы.ТекущаяСтрока.

Способ 3. Делегирование выбора платформе через «Владельца»

Теперь рассмотрим наиболее корректный с точки зрения архитектуры 1С способ. Если мы не хотим эмулировать клавиатуру, мы можем программно вызвать форму выбора, используя метод ОткрытьФорму. Основной секрет здесь заключается в параметре Владелец.

Если в качестве владельца формы выбора передать не саму ЭтаФорма, а конкретный элемент управления (поле ввода), то платформа автоматически сделает следующее:

  1. Определит тип данных элемента.
  2. Откроет стандартную форму выбора для этого типа.
  3. После выбора пользователем значения — сама подставит его в реквизит и вызовет все связанные события (ПриИзменении, ОбработкаВыбора).

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


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

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

Способ 4. Работа с колонками таблиц

Если задача стоит в вызове выбора для ячейки в таблице, нужно учитывать, что элемент формы для всей колонки один, а данных в строках много. Чтобы платформа поняла, куда именно нужно вернуть значение, перед вызовом выбора убедитесь, что:

Разберем пример для таблицы товаров:


&НаКлиенте
Процедура ВыборВТаблице()
    // Убедимся, что строка выбрана
    Если Элементы.Товары.ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Вызываем стандартную форму для поля Номенклатура в таблице
    ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", , Элементы.ТоварыНоменклатура);
КонецПроцедуры

Подведем итоги

Мы рассмотрели различные варианты решения задачи. Использование SendKeys удобно для быстрой реализации "как есть", но привязывает решение к Windows. Программное открытие формы с указанием элемента-владельца является универсальным и надежным способом, который полностью имитирует поведение платформы, сохраняя все стандартные обработчики и проверки данных.

Выбор конкретного метода зависит от ваших требований к кроссплатформенности и необходимости жестко контролировать процесс выбора (например, накладывать сложные динамические фильтры перед открытием окна).

← На главную