Как получить выбранную строку из таблицы значений и обработать выбор в 1С

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

При разработке обработок и отчетов нередко возникает задача: выполнить запрос к базе данных, показать полученный список пользователю и дать ему возможность интерактивно выбрать нужную запись для дальнейшей обработки. Начинающие разработчики часто пытаются использовать метод ВыбратьСтроку() объекта ТаблицаЗначений и сталкиваются с вопросом: как перехватить событие выбора внутри открывшегося стандартного окна платформы? Разберем подробно механику работы этого метода, выясним причины возникающих сложностей и рассмотрим альтернативные варианты реализации выбора.

Принцип работы метода ТаблицаЗначений.ВыбратьСтроку

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

Метод ВыбратьСтроку() работает синхронно (модально): выполнение программного кода приостанавливается до тех пор, пока пользователь не выберет запись двойным кликом (или клавишей Enter), либо не закроет диалог кнопкой отмены.

Посмотрим, что возвращает данный метод. В результате выбора возвращается объект типа СтрокаТаблицыЗначений (а не ссылка и не прикладной объект). Если пользователь отказался от выбора, нажав кнопку «Отмена» или закрыв окно крестиком, метод возвращает значение Неопределено.

Рассмотрим типовой пример правильного использования этого метода:


// Выгружаем результат запроса в таблицу значений
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();

// Открываем модальное окно выбора строки
ВыбраннаяСтрока = ТаблицаРезультата.ВыбратьСтроку("Выберите нужную запись из списка");

// Обязательно проверяем результат на Неопределено
Если ВыбраннаяСтрока <> Неопределено Тогда
    // Получаем значения нужных колонок выбранной строки
    ВыбраннаяСсылка = ВыбраннаяСтрока.Номенклатура;
    Количество = ВыбраннаяСтрока.Количество;
    
    // Выполняем дальнейшие действия с полученными данными
    ОбработатьВыбор(ВыбраннаяСсылка, Количество);
КонецЕсли;

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

Ограничения и подводные камни метода ВыбратьСтроку

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

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

Способ 1. Немодальный выбор через СписокЗначений

Если из результата запроса пользователю необходимо выбрать только один объект (например, договор, контрагента или документ), вместо таблицы значений удобно использовать объект СписокЗначений и его асинхронный метод выбора. Разберем реализацию по шагам:


// Заполняем список значений данными из выборки запроса
Список = Новый СписокЗначений;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Список.Добавить(Выборка.Ссылка, Выборка.Представление);
КонецЦикла;

// Настраиваем оповещение о завершении выбора
Оповещение = Новый ОписаниеОповещения("ПослеВыбораИзСписка", ЭтотОбъект);
Список.ПоказатьВыборЭлемента(Оповещение, "Выберите значение");

Посмотрим на процедуру обработки результата, которая сработает после закрытия окна:


&НаКлиенте
Процедура ПослеВыбораИзСписка(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    Если ВыбранныйЭлемент <> Неопределено Тогда
        Значение = ВыбранныйЭлемент.Значение;
        // Обрабатываем выбранное значение
    КонецЕсли;
КонецПроцедуры

Такой подход полностью совместим с тонким клиентом и не нарушает политику отказа от модальных окон.

Способ 2. Создание собственной формы подбора и выбора

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

  1. Создаем отдельную форму (в обработке или общей форме) и добавляем на нее реквизит с типом ТаблицаЗначений.
  2. Перетаскиваем реквизит в элементы формы, формируя таблицу интерфейса с необходимыми колонками.
  3. В свойствах таблицы формы для события Выбор (Selection) назначаем обработчик.
  4. Внутри обработчика считываем текущие данные строки и вызываем процедуру ОповеститьОВыборе() или Закрыть().

Рассмотрим пример кода в форме выбора:


&НаКлиенте
Процедура ТаблицаДанныхВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ТекущиеДанные = Элементы.ТаблицаДанных.ТекущиеДанные;
    
    Если ТекущиеДанные <> Неопределено Тогда
        // Создаем структуру с выбранными значениями
        РезультатВыбора = Новый Структура("Номенклатура, Количество, Цена");
        ЗаполнитьЗначенияСвойств(РезультатВыбора, ТекущиеДанные);
        
        // Оповещаем владельца формы о выборе
        ОповеститьОВыборе(РезультатВыбора);
    КонецЕсли;
КонецПроцедуры

Посмотрим, как вызывается эта форма из исходного документа или обработки:


&НаКлиенте
Процедура ОткрытьПодборДанных()
    Оповещение = Новый ОписаниеОповещения("ОбработатьРезультатПодбора", ЭтотОбъект);
    ОткрытьФорму("Обработка.МояОбработка.Форма.ФормаВыбора", , ЭтотОбъект, , , , Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьРезультатПодбора(Результат, ДополнительныеПараметры) Экспорт
    Если Результат <> Неопределено Тогда
        // Заполняем табличную часть или реквизиты исходной формы
        Сообщить("Выбрано: " + Строка(Результат.Номенклатура));
    КонецЕсли;
КонецПроцедуры

Способ 3. Использование динамического списка

Если таблица формируется не в результате сложного алгоритмического расчета в памяти, а выбирает реальные данные из таблиц базы, оптимально использовать ДинамическийСписок вместо таблицы значений. Создаем форму выбора, устанавливаем признак «Произвольный запрос» и пишем необходимый текст запроса.

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

← На главную