Как в динамическом списке 1С реализовать сортировку пустых дат в конец списка?

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

При работе с динамическими списками в 1С:Предприятии программисты часто сталкиваются со стандартным поведением платформы: при сортировке по возрастанию пустые значения (например, пустая дата 01.01.0001) всегда оказываются в самом верху. С точки зрения бизнес-логики это часто неудобно — пользователи хотят видеть актуальные задачи или документы сверху, а объекты с незаполненными датами (которые, например, еще не обработаны) должны уходить в самый низ списка, как если бы это были даты из далекого будущего.

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

Метод 1. Использование свойства «Выражение упорядочивания»

Это самый «чистый» способ, который не требует создания лишних колонок в интерфейсе и минимально нагружает систему. Рассмотрим его подробнее. В настройках динамического списка (схема компоновки данных) для каждого поля можно задать специальное выражение, которое платформа будет подставлять в SQL-запрос только в момент сортировки.

Проанализируем шаги для настройки:

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

ВЫБОР 
    КОГДА ДатаПриема = ДАТАВРЕМЯ(1, 1, 1) 
    ТОГДА ДАТАВРЕМЯ(3999, 12, 31) 
    ИНАЧЕ ДатаПриема 
КОНЕЦ

Важный нюанс: как отмечалось в обсуждении, это выражение нужно вводить вручную с клавиатуры прямо в поле настройки, так как стандартный выбор из списка не предложит вам написать конструкцию ВЫБОР. Теперь, когда пользователь нажмет на заголовок колонки «Дата приема», платформа фактически выполнит сортировку по виртуальной дате (31 декабря 3999 года) для всех пустых значений, и они окажутся внизу.

Метод 2. Двойная сортировка через вспомогательное поле

Иногда использование сложных выражений в упорядочивании может сбивать с толку СУБД или не срабатывать на специфических типах данных. В таких случаях мы рекомендуем использовать метод «булевого флага». Разберем, как это реализовать через изменение запроса динамического списка.

Добавим в текст запроса поле, которое будет определять, заполнена дата или нет:


ВЫБОР
    КОГДА Таблица.ДатаПриема = ДАТАВРЕМЯ(1, 1, 1) ТОГДА ИСТИНА
    ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ДатаПустая,
Таблица.ДатаПриема КАК ДатаПриема

Затем в настройках динамического списка (закладка «Порядок») установим последовательную сортировку:

  1. ДатаПустая — по возрастанию (сначала ЛОЖЬ, т.е. заполненные, потом ИСТИНА, т.е. пустые).
  2. ДатаПриема — по возрастанию.

Этот метод считается наиболее надежным для производительности, так как СУБД проще обрабатывать простые логические поля.

Метод 3. Работа с составными типами и NULL

Проанализируем ситуацию, когда поле даты может быть не просто пустым, а содержать NULL или Неопределено (например, при использовании левых соединений в запросе). Если мы просто проверим на ДАТАВРЕМЯ(1,1,1), то записи с NULL все равно могут «всплыть» наверх.

Для обеспечения универсальности в выражении упорядочивания или в запросе следует использовать функцию ЕСТЬNULL. Посмотрим на пример кода:


ВЫБОР 
    КОГДА ЕСТЬNULL(ДатаПриема, ДАТАВРЕМЯ(1, 1, 1)) = ДАТАВРЕМЯ(1, 1, 1) 
    ТОГДА ДАТАВРЕМЯ(3999, 12, 31) 
    ИНАЧЕ ДатаПриема 
КОНЕЦ

Если же поле имеет составной тип, необходимо сначала убедиться, что значение является датой, чтобы избежать ошибок исполнения кода:


ВЫБОР 
    КОГДА ТИПЗНАЧЕНИЯ(Дата) = ТИП(Дата) И Дата = ДАТАВРЕМЯ(1, 1, 1) 
    ТОГДА ДАТАВРЕМЯ(3999, 12, 31) 
    ИНАЧЕ Дата 
КОНЕЦ

Метод 4. Визуальное оформление (скрытие «фиктивных» дат)

Если вы решили использовать подстановку даты 31.12.3999 через вычисляемое поле или непосредственно в запросе, вы можете столкнуться с тем, что пользователь увидит этот «год будущего» в списке. Чтобы этого избежать, выясним, как настроить Условное оформление.

Выполним следующие шаги:

  1. Зайдем в настройки динамического списка, вкладка «Условное оформление».
  2. Добавим новое правило.
  3. В условии укажем: ДатаПриема Равно 31.12.3999.
  4. В оформлении установим параметр Текст и оставим его пустым (или впишем туда «Не задано»).
  5. В области использования выберем только поле ДатаПриема.

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

Программная установка порядка при открытии формы

Иногда требуется, чтобы эта сложная сортировка применялась автоматически при открытии списка, независимо от действий пользователя. Рассмотрим, как это сделать программно в модуле формы. Пропишем код в процедуре ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Очистим текущий порядок, если нужно
    Список.Порядок.Элементы.Очистить();
    
    // Добавляем сортировку по нашему выражению/полю
    ЭлементПорядка = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
    ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных("ДатаПриема"); // Здесь будет работать выражение упорядочивания
    ЭлементПорядка.ВидУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
    ЭлементПорядка.Использование = Истина;
    
КонецПроцедуры

Резюме: для большинства задач оптимальным решением является использование «Выражения упорядочивания» в свойствах поля списка. Это позволяет сохранить стандартный интерфейс (пользователь просто жмет на колонку) и достичь желаемого результата без радикальной переработки запросов. Если же список очень большой (миллионы записей), стоит рассмотреть вариант с хранением в базе данных отдельного индексированного числового поля для сортировки, так как любые вычисления в ORDER BY могут замедлять работу СУБД.

← На главную