Как отсортировать справочник по полю составного типа в 1С

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

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

Разберем причины такого поведения платформы 1С:Предприятие и детально рассмотрим способы реализации корректной сортировки.

Выясним причину: почему составное поле не сортируется по алфавиту

Проанализируем, как платформа 1С и СУБД работают с полями составного типа и табличными частями форм:

  1. Хранение данных в СУБД. На уровне таблиц базы данных поле составного типа раскладывается на несколько колонок: код типа метаданных (разделитель типов) и бинарный идентификатор ссылки (GUID).
  2. Сортировка по ссылочным полям. Когда платформа обращается к СУБД с командой упорядочивания по ссылочному полю без разыменования наименования, сортировка выполняется не по пользовательскому представлению, а сначала по типу объекта, а затем по его внутреннему бинарному GUID. В результате записи в списке сначала группируются по видам объектов метаданных, а внутри групп упорядочиваются псевдослучайным образом, что совершенно не соответствует алфавитному порядку.
  3. Ограничения динамического списка в обычных формах. В обычном приложении источником данных табличного поля формы выступает объект СправочникСписок. Механизм НастройкаПорядка обычных форм работает напрямую с физической таблицей справочника и позволяет упорядочивать строки только по реальным индексированным полям таблицы БД. Выполнить динамическую сортировку списка по представлению ссылочного реквизита без дополнительных модификаций платформа в обычном режиме не позволяет.

Решение 1: Денормализация данных через реквизит «Наименование»

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

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

Шаг 1. Автоматическое заполнение при записи элемента

Откроем модуль объекта нужного справочника и в обработчике события ПередЗаписью добавим преобразование значения составного поля в строку:


Процедура ПередЗаписью(Отказ)
    
    // Преобразуем составное значение ссылки в строковое представление
    Наименование = Строка(Описание);
    
КонецПроцедуры

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

Шаг 2. Заполнение наименований для существующих элементов

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


Выборка = Справочники.НашСправочник.Выбрать();
Пока Выборка.Следующий() Цикл
    Если СокрЛП(Выборка.Наименование) <> СокрЛП(Строка(Выборка.Описание)) Тогда
        ОбъектСпр = Выборка.ПолучитьОбъект();
        ОбъектСпр.Наименование = Строка(ОбъектСпр.Описание);
        ОбъектСпр.Записать();
    КонецЕсли;
КонецЦикла;

Шаг 3. Настройка формы списка

В форме списка справочника настроим порядок отображения колонок. Чтобы не перегружать интерфейс, колонку Наименование можно сделать скрытой (снять флажок видимости), оставив пользователю только колонку Описание, либо наоборот отображать Наименование. При открытии формы зададим порядок сортировки в обработчике ПриОткрытии:


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

Подводные камни этого подхода:

  1. Длина реквизита. Стандартный реквизит Наименование имеет фиксированную длину (например, 50 или 100 символов). Если строковое представление объекта составного типа окажется длиннее, оно автоматически обрежется при записи.
  2. Актуальность данных. Если пользователь изменит название начисления в самом плане видов расчета, наименование в нашем справочнике не обновится автоматически до тех пор, пока элемент не будет перезаписан или не отработает регламентная синхронизация.

Решение 2: Сортировка составного реквизита в запросе

Если данные справочника необходимо вывести с сортировкой в отчете, печатной форме или вспомогательной таблице без изменения структуры метаданных и перезаписи элементов, разберем решение через запрос. Для составного поля нельзя применить операцию точки через составной тип без типизации. Поэтому воспользуемся конструкцией ВЫБОР КОГДА ... ССЫЛКА и функцией ВЫРАЗИТЬ:


ВЫБРАТЬ
    Спр.Код КАК Код,
    Спр.Описание КАК Описание,
    ВЫБОР
        КОГДА Спр.Описание ССЫЛКА ПланВидовРасчета.ОсновныеНачисленияОрганизаций
            ТОГДА ВЫРАЗИТЬ(Спр.Описание КАК ПланВидовРасчета.ОсновныеНачисленияОрганизаций).Наименование
        КОГДА Спр.Описание ССЫЛКА ПланВидовРасчета.ДополнительныеНачисленияОрганизаций
            ТОГДА ВЫРАЗИТЬ(Спр.Описание КАК ПланВидовРасчета.ДополнительныеНачисленияОрганизаций).Наименование
        КОГДА Спр.Описание ССЫЛКА Перечисление.ВидыОперацийПКО
            ТОГДА ПРЕДСТАВЛЕНИЕ(Спр.Описание)
        ИНАЧЕ ""
    КОНЕЦ КАК ТекстовоеПредставление
ИЗ
    Справочник.НашСправочник КАК Спр
УПОРЯДОЧИТЬ ПО
    ТекстовоеПредставление ВОЗР

Такой подход обеспечивает правильную алфавитную сортировку сразу на уровне СУБД, обращаясь к реальным строковым полям соответствующих таблиц.

Решение 3: Замена источника данных формы на ТаблицуЗначений

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

  1. В табличном поле формы в качестве типа значения указываем ТаблицаЗначений.
  2. При открытии формы выполняем запрос с конструкцией приведения типов (описанной в Решении 2) и выгружаем результат в эту таблицу.
  3. В свойствах колонок таблицы разрешаем интерактивную сортировку. Пользователь сможет сортировать данные кликом по шапке таблицы по текстовому представлению без каких-либо задержек и ограничений платформы.
← На главную