Почему не работает сортировка по клику на заголовок колонки в управляемой форме 1С?

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

При разработке управляемых форм часто возникает потребность отобразить в табличной части документа или обработки реквизит ссылочного поля. Например, в строке с товаром вывести артикул номенклатуры через путь к данным Объект.Товары.НоменклатураПоставщика.Артикул. Однако при попытке интерактивно отсортировать строки кликом по заголовку такой колонки ничего не происходит, тогда как по остальным колонкам сортировка отрабатывает штатно.

Проанализируем, почему платформа 1С ведет себя подобным образом, и разберем практические способы реализации сортировки для таких данных.

Причина поведения платформы

Выясним причину ограничения. В управляемых формах табличная часть объекта представлена коллекцией ДанныеФормыКоллекция. Стандартный механизм интерактивной сортировки по клику на заголовок колонки работает автоматически только для физических реквизитов этой коллекции.

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

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

Способ 1. Добавление физического реквизита в табличную часть объекта

Это классический и наиболее распространенный подход, применяемый в типовых конфигурациях 1С. Если значение реквизита требуется не только для просмотра, но и для постоянной работы (сортировки, печати, отчетов), добавим его непосредственно в метаданные табличной части.

Разберем по шагам реализацию этого подхода:

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

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


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

&НаСервереБезКонтекста
Функция ПолучитьАртикулНоменклатурыПоставщика(СсылкаНаНоменклатуру)
    Если ЗначениеЗаполнено(СсылкаНаНоменклатуру) Тогда
        Возврат СсылкаНаНоменклатуру.Артикул;
    КонецЕсли;
    Возврат "";
КонецФункции

После привязки колонки к прямому реквизиту табличной части штатная сортировка по клику на заголовок станет доступна автоматически.

Способ 2. Использование дополнительного реквизита формы без изменения метаданных

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

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

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

Рассмотрим пример заполнения данных на сервере:


&НаСервере
Процедура ЗаполнитьДополнительныеКолонкиНаСервере()
    Для Каждого Стр Из Объект.Товары Цикл
        Если ЗначениеЗаполнено(Стр.НоменклатураПоставщика) Тогда
            Стр.АртикулКолонкаФормы = Стр.НоменклатураПоставщика.Артикул;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    ЗаполнитьДополнительныеКолонкиНаСервере();
КонецПроцедуры

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

Так как реквизит АртикулКолонкаФормы теперь является полноценным элементом структуры ДанныеФормыКоллекция, пользователь сможет сортировать таблицу по нажатию на заголовок колонки.

Способ 3. Программная сортировка через отдельную команду

Если создание колонок нежелательно, можно добавить на командную панель таблицы специальную кнопку сортировки. Поскольку объект ДанныеФормыКоллекция не имеет прямого метода Сортировать(), операцию необходимо выполнить на сервере через промежуточную таблицу значений.

Рассмотрим пример программной сортировки строк:


&НаКлиенте
Процедура СортироватьПоАртикулу(Команда)
    СортироватьТабличнуюЧастьНаСервере();
КонецПроцедуры

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

Способ 4. Использование динамического списка для таблиц в режиме просмотра

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

В тексте запроса динамического списка поле через точку объявляется напрямую:


ВЫБРАТЬ
    Товары.НомерСтроки КАК НомерСтроки,
    Товары.НоменклатураПоставщика КАК НоменклатураПоставщика,
    Товары.НоменклатураПоставщика.Артикул КАК Артикул,
    Товары.Количество КАК Количество
ИЗ
    Документ.ЗаказПоставщику.Товары КАК Товары
ГДЕ
    Товары.Ссылка = &Ссылка

В этом случае платформа передает сортировку на уровень СУБД, и упорядочивание по клику на любую колонку динамического списка работает из коробки без написания дополнительного кода.

← На главную