Как реализовать выбор данных из вложенной таблицы в ячейке таблицы значений

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

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

Архитектурный подход: Разделение хранения и визуализации

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

Для решения задачи мы проанализируем три наиболее эффективных способа: организацию связанных таблиц (Master-Detail), использование дерева значений и программное формирование динамического списка выбора.

Решение 1: Связанные таблицы (схема Master-Detail)

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

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

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


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

Этот метод позволяет пользователю видеть все подробности по текущему контрагенту мгновенно, без лишних кликов и всплывающих окон.

Решение 2: Использование Дерева Значений

Если задача требует именно иерархического представления «внутри» одной области, воспользуемся объектом ДеревоЗначений. Это позволит «разворачивать» строку контрагента, видя под ней список его договоров как подчиненные строки.

Выясним преимущества этого метода:

Решение 3: Динамический выбор из программно сформированного списка

Рассмотрим сценарий, который наиболее близок к запросу автора темы: пользователь кликает в ячейку «Договор», и перед ним должен появиться расширенный список для выбора, содержащий не только название договора, но и его параметры (например, сумму). Мы реализуем это через событие НачалоВыбора и метод ПоказатьВыборИзСписка.

Посмотрим на алгоритм реализации по шагам:

Шаг 1. Подготовка данных. При заполнении основной таблицы мы одновременно получаем все данные по договорам и сохраняем их во временную таблицу значений на форме (не отображая её визуально).

Шаг 2. Обработка нажатия. В обработчике события НачалоВыбора колонки «Договор» мы отключаем стандартную обработку и формируем свой список.


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

    СписокДляВыбора = Новый СписокЗначений;
    
    // Перебираем данные из нашей скрытой вспомогательной таблицы
    // (на управляемых формах это будет ДанныеФормыКоллекция)
    Для Каждого СтрокаДоговора Из ВспомогательнаяТаблицаДоговоров Цикл
        Если СтрокаДоговора.Контрагент = ТекущаяСтрока.Контрагент Тогда
            // Формируем красивое представление: Договор + Сумма
            ТекстПредставления = Строка(СтрокаДоговора.Договор) + " | Сумма: " + Формат(СтрокаДоговора.Сумма, "ЧДЦ=2");
            СписокДляВыбора.Добавить(СтрокаДоговора.Договор, ТекстПредставления);
        КонецЕсли;
    КонецЦикла;

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

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

Дополнительные возможности: ХранилищеЗначения и HTML

Проанализируем ситуацию, когда структуру данных нужно сохранить в базе. Для этого в реквизитах объекта (например, документа) можно создать колонку с типом ХранилищеЗначения. Перед записью мы упаковываем вспомогательную таблицу в это хранилище, а при открытии формы — извлекаем обратно. Это позволяет хранить произвольные таблицы, привязанные к каждой строке основной табличной части.

Для самых взыскательных интерфейсных задач можно использовать Поле HTML-документа. В этом случае мы программно генерируем HTML-код таблицы, включая вложенные теги <table> внутри ячеек. Это обеспечит идеальный визуальный результат, однако потребует написания кода для обработки событий нажатия на ссылки внутри HTML, чтобы передать данные обратно в 1С.

Заключение

Мы рассмотрели несколько способов имитации вложенных таблиц. Выбор конкретного метода зависит от ваших целей:

  1. Нужна простота и скорость разработки — используйте связанные таблицы.
  2. Нужна строгая иерархия в одном окне — выбирайте дерево значений.
  3. Нужен удобный выбор из множества вариантов с подсказками — реализуйте кастомный список выбора через ПоказатьВыборИзСписка.

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

← На главную