Как отобразить в строке справочника список значений из его табличной части в 1С?

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

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

Ограничения платформы 1С при работе с динамическими списками

Выполнить объединение строк табличной части непосредственно в тексте запроса динамического списка штатными средствами невозможно по следующим причинам:

  1. Отсутствие функций агрегации строк: В языке запросов 1С отсутствуют аналоги SQL-функций STRING_AGG или GROUP_CONCAT. Написанный запрос не может самостоятельно сконкатенировать несколько строк табличной части в одно текстовое поле.
  2. Проблема дублирования записей: Если связать основную таблицу справочника с табличной частью через ЛЕВОЕ СОЕДИНЕНИЕ без группировки, динамический список продублирует строки справочника по числу строк в табличной части.

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

Способ 1. Хранение свернутой строки в реквизите объекта (Рекомендуемый)

Самый распространенный и производительный подход состоит в том, чтобы создать у справочника отдельный строковый реквизит и заполнять его при сохранении элемента. Подобная схема применяется в типовых решениях (например, в 1С:ЗУП).

Разберем алгоритм настройки по шагам:

  1. Добавим в метаданные справочника реквизит ПредставлениеТЧ с типом Строка (например, длиной 150 или 200 символов).
  2. В модуле объекта справочника в обработчике события ПередЗаписью пропишем формирование строки из элементов табличной части:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    МассивЗначений = Новый Массив;
    Для Каждого СтрокаТЧ Из МояТабличнаяЧасть Цикл
        Если ЗначениеЗаполнено(СтрокаТЧ.Значение) Тогда
            МассивЗначений.Добавить(СтрокаТЧ.Значение);
        КонецЕсли;
    КонецЦикла;
    
    ПредставлениеТЧ = СтрСоединить(МассивЗначений, ", ");
    
КонецПроцедуры
  1. Выведем реквизит ПредставлениеТЧ в колонку динамического списка на форме списка.

Преимущества: По этой колонке пользователю будут доступны стандартный поиск, отбор и сортировка непосредственно в динамическом списке.

Особенности и риски: При программном загрузке данных с флагом ОбменДанными.Загрузка = Истина обработчик ПередЗаписью не вызывается. В таких случаях требуется предусмотреть отдельный механизм или обработку для актуализации текстового поля.

Способ 2. Обработка события динамического списка «ПриПолученииДанныхНаСервере»

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

Рассмотрим порядок реализации:

  1. В форме списка добавим в динамический список вычисляемую колонку (несвязанный реквизит формы).
  2. Назначим обработчик события ПриПолученииДанныхНаСервере для динамического списка:

&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Данные)
    
    МассивСсылок = Новый Массив;
    Для Каждого КлючИЗначение Из Данные Цикл
        МассивСсылок.Добавить(КлючИЗначение.Ключ);
    КонецЦикла;
    
    Если МассивСсылок.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ТЧ.Ссылка КАК Ссылка,
        |   ТЧ.Значение КАК Значение
        |ИЗ
        |   Справочник.МойСправочник.МояТабличнаяЧасть КАК ТЧ
        |ГДЕ
        |   ТЧ.Ссылка В(&МассивСсылок)";
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    
    Для Каждого КлючИЗначение Из Данные Цикл
        ОформлениеСтроки = КлючИЗначение.Значение;
        СсылкаЭлемента = КлючИЗначение.Ключ;
        
        Отбор = Новый Структура("Ссылка", СсылкаЭлемента);
        НайденныеСтроки = РезультатЗапроса.НайтиСтроки(Отбор);
        
        МассивЗначений = Новый Массив;
        Для Каждого СтрИзТЧ Из НайденныеСтроки Цикл
            МассивЗначений.Добавить(СтрИзТЧ.Значение);
        КонецЦикла;
        
        ОформлениеСтроки.Данные.ВычисляемаяКолонка = СтрСоединить(МассивЗначений, ", ");
    КонецЦикла;
    
КонецПроцедуры

Преимущества: Структура базы данных остается чистой, отсутствует избыточность информации.

Ограничение: По вычисляемой таким образом колонке платформой 1С не поддерживаются поиск, сортировка и установка отборов в форме списка.

Способ 3. Использование связанного регистра сведений

Промежуточный вариант — создание независимого регистра сведений, где измерением выступает ссылка на элемент справочника, а ресурсом — сформированная строка с разделителями. В этом случае динамический список соединениями связывается с регистром сведений.

Этот способ позволяет выполнять поиск и отбор по свернутой строке, не расширяя состав реквизитов основного справочника.

Способ 4. Интерфейсная схема «Мастер – деталь» (Master-Detail)

Выясним еще один удобный вариант представления информации. Если строковое представление табличной части получается слишком длинным и неудобным для чтения в одной колонке таблицы, лучше вынести подчиненную табличную часть в отдельную область формы списка.

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

← На главную