При разработке интерфейсов на управляемых формах 1С часто возникает ситуация: колонка с текстовыми данными отображается в таблице динамического списка, по ней можно настроить отбор, однако интерактивная сортировка по клику на заголовок не работает, а само поле отсутствует в списке доступных полей для упорядочивания. Разберем подробно, почему платформа 1С накладывает такое ограничение и какими способами можно вернуть возможность сортировки.
Проанализируем типовой пример, в котором возникает эта проблема. Предположим, в запросе динамического списка источником выступает регистр сведений РеестрДокументов, а поле извлекается через обращение к реквизиту документа:
ВЫБРАТЬ
РеестрДокументов.Ссылка КАК Ссылка,
РеестрДокументов.НомерДокументаИБ КАК Номер,
РеестрДокументов.ДатаДокументаИБ КАК Дата,
РеестрДокументов.Ссылка.НомерБСО КАК НомерБСО
ИЗ
РегистрСведений.РеестрДокументов КАК РеестрДокументов
Выясним причину такого поведения системы. Проблема кроется в сочетании двух факторов: особенностей работы с составными типами данных и ограничений систем управления базами данных (СУБД).
Ссылка имеет составной тип (например, может содержать ссылки на документы различных видов), то при обращении через точку РеестрДокументов.Ссылка.НомерБСО платформа 1С неявно генерирует левые соединения со всеми таблицами документов, входящими в этот тип. Если хотя бы в одном из этих документов реквизит НомерБСО имеет тип Строка неограниченной длины (или длина не задана жестко), результирующее поле запроса автоматически приобретает тип строки неограниченной длины.TEXT, VARCHAR(MAX)) и не поддерживают сортировку по таким типам данных без явного преобразования. Платформа 1С:Предприятие отслеживает подобные типы и автоматически исключает их из списка полей, доступных для сортировки, чтобы предотвратить ошибки исполнения на сервере СУБД. При этом фильтрация (отбор) по таким полям остается доступной.Рассмотрим по шагам практические способы решения этой задачи.
Самым быстрым и простым решением в запросе динамического списка является явное ограничение максимальной длины строки с помощью функции ВЫРАЗИТЬ(...). Это явно сообщает платформе и СУБД, что результат имеет фиксированную длину, после чего колонка становится доступной для сортировки.
Посмотрим на пример модификации текста запроса:
ВЫБРАТЬ
РеестрДокументов.Ссылка КАК Ссылка,
РеестрДокументов.НомерДокументаИБ КАК Номер,
РеестрДокументов.ДатаДокументаИБ КАК Дата,
ВЫРАЗИТЬ(РеестрДокументов.Ссылка.НомерБСО КАК СТРОКА(50)) КАК НомерБСО
ИЗ
РегистрСведений.РеестрДокументов КАК РеестрДокументов
Указание типа СТРОКА(50) преобразует результирующее поле в строку фиксированной длины, что снимает ограничение СУБД и возвращает возможность сортировки как в настройках списка, так и по нажатию на заголовок колонки.
Если реквизит НомерБСО присутствует только в определенных видах документов, обращение через точку ко всем типам подряд создает избыточную нагрузку на СУБД. Оптимальнее проверить принадлежность ссылки к конкретному типу документа и явно привести тип:
ВЫБРАТЬ
РеестрДокументов.Ссылка КАК Ссылка,
РеестрДокументов.НомерДокументаИБ КАК Номер,
ВЫБОР
КОГДА РеестрДокументов.Ссылка ССЫЛКА Документ.РеализацияТоваровУслуг
ТОГДА ВЫРАЗИТЬ(РеестрДокументов.Ссылка.НомерБСО КАК СТРОКА(50))
КОГДА РеестрДокументов.Ссылка ССЫЛКА Документ.АктВыполненныхРабот
ТОГДА ВЫРАЗИТЬ(РеестрДокументов.Ссылка.НомерБСО КАК СТРОКА(50))
ИНАЧЕ ""
КОНЕЦ КАК НомерБСО
ИЗ
РегистрСведений.РеестрДокументов КАК РеестрДокументов
Такой подход защищает запрос от нежелательного разыменования таблиц других документов и гарантирует строковый тип фиксированной длины на выходе.
Разыменование полей составного типа через точку является антипаттерном с точки зрения стандартов разработки 1С, так как приводит к множественным неконтролируемым соединениям в СУБД. Разберем более производительный вариант с явным левым соединением только с теми таблицами, где этот реквизит реально присутствует:
ВЫБРАТЬ
РеестрДокументов.Ссылка КАК Ссылка,
РеестрДокументов.НомерДокументаИБ КАК Номер,
РеестрДокументов.ДатаДокументаИБ КАК Дата,
ЕСТЬNULL(ВЫРАЗИТЬ(Реализация.НомерБСО КАК СТРОКА(50)), "") КАК НомерБСО
ИЗ
РегистрСведений.РеестрДокументов КАК РеестрДокументов
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализация
ПО РеестрДокументов.Ссылка = Реализация.Ссылка
Использование явных соединений позволяет точно контролировать план выполнения запроса и исключает появление неограниченных строк в динамическом списке.
Если конфигурация находится на поддержке с возможностью изменения или разрабатывается с нуля, проанализируем настройки метаданных:
НомерБСО непосредственно в регистр сведений РеестрДокументов с фиксированной длиной строки и признаком индексирования. Это обеспечит максимальную производительность при работе с динамическим списком.