В процессе разработки на платформе 1С:Предприятие 8 часто возникает задача отображения списка элементов справочника в хронологическом порядке: от самых свежих к самым старым. Стандартно платформа предлагает сортировку по Коду или Наименованию, однако код не всегда отражает реальное время создания (например, если коды редактировались вручную или переносились из других систем). В этой статье мы подробно разберем все доступные способы решения этой задачи, проанализируем их надежность и выберем оптимальный вариант для вашей конфигурации.
Как показывает практика и обсуждение специалистов, единственным гарантированным способом сортировки является наличие в справочнике специального реквизита, хранящего дату и время создания элемента. Разберем по шагам, как это реализовать.
Во-первых, создадим в метаданных справочника новый реквизит ДатаСоздания с типом Дата (состав даты: Дата и время). Для того чтобы этот реквизит заполнялся автоматически и его нельзя было изменить случайно, пропишем логику в модуле объекта справочника.
Рассмотрим пример кода в обработчике ПередЗаписью:
Процедура ПередЗаписью(Отказ)
Если ЭтоНовый() Тогда
ДатаСоздания = ТекущаяДатаСеанса();
КонецЕсли;
КонецПроцедуры
Почему это лучший вариант? Во-первых, вы получаете индекс, по которому СУБД сможет мгновенно отсортировать тысячи записей. Во-вторых, этот метод работает корректно в распределенных информационных базах (РИБ) и при загрузке данных из внешних источников. Проанализируем ситуацию: если вам нужно вывести список в форме, достаточно будет установить порядок по этому полю в настройках динамического списка.
Если вносить изменения в структуру метаданных нельзя, можно попробовать использовать особенности хранения ссылок. В 1С ссылка (объект типа УникальныйИдентификатор) генерируется на основе времени (UUID v1). Рассмотрим, как это работает в запросах.
Посмотрим на пример использования директивы АВТОУПОРЯДОЧИВАНИЕ в языке запросов. Если в метаданных не задано иное, платформа будет пытаться упорядочить данные детерминировано. Однако для явной хронологии лучше использовать упорядочивание по самой ссылке:
ВЫБРАТЬ
Спр.Ссылка КАК Ссылка,
Спр.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Спр
УПОРЯДОЧИТЬ ПО
Ссылка УБЫВ
Важный нюанс: Сортировка по ссылке УБЫВ часто (но не всегда!) показывает новые элементы первыми. Это связано с тем, что GUID содержит временную метку. Однако, проанализируем техническую деталь: Microsoft SQL Server при хранении типа uniqueidentifier переставляет байты для оптимизации индексов. Из-за этого «соседние» по времени элементы могут оказаться в разных частях списка при бинарной сортировке. Этот метод можно использовать как временный или «черновой» вариант, но он не дает 100% гарантии хронологии.
Для тех, кто готов к нестандартным решениям, существует способ программного вычисления даты создания элемента прямо из его внутреннего идентификатора. Поскольку 1С использует UUID первого типа, в нем зашифровано количество 100-наносекундных интервалов с момента перехода на Григорианский календарь (15 октября 1582 года).
Разберем алгоритм, предложенный участниками обсуждения. Мы можем написать функцию, которая преобразует части GUID в дату:
Функция ДатаСозданияИзСсылки(Ссылка) Экспорт
УИД = Строка(Ссылка.УникальныйИдентификатор());
// UUID v1 имеет формат: xxxxxxxx-xxxx-Vxxx-Sxxx-xxxxxxxxxxxx
// Где V - версия (должна быть 1)
// Пересобираем строку для получения временных меток в правильном порядке
Строка16 = Сред(УИД, 16, 3) + Сред(УИД, 10, 4) + Сред(УИД, 1, 8);
ЧислоСек = 0;
Разрядность = СтрДлина(Строка16);
// Преобразуем из 16-ричной системы в 10-ричную
Для Позиция = 1 По Разрядность Цикл
Символ = Сред(Строка16, Позиция, 1);
Значение = Найти("0123456789abcdef", Символ) - 1;
ЧислоСек = ЧислоСек + Значение * Pow(16, Разрядность - Позиция);
КонецЦикла;
// Переводим 100-наносекундные интервалы в секунды
ЧислоСек = ЧислоСек / 10000000;
// Базовая дата Григорианского календаря + разница часового пояса (при необходимости)
Возврат Дата(1582, 10, 15, 04, 00, 00) + ЧислоСек;
КонецФункции
Внимание: Этот метод имеет серьезные ограничения. Если GUID был сгенерирован не платформой 1С (например, при программном создании с использованием Новый УникальныйИдентификатор(СтрокаGUID)), то дата может быть некорректной. Также в распределенных базах (РИБ) дата создания будет указывать на момент появления объекта в локальной базе, где он был создан первым, что может запутать пользователя при анализе общей базы.
Проанализируем ситуацию, когда конфигурация построена на базе Библиотеки стандартных подсистем (БСП). В этом случае у нас есть дополнительные инструменты, которые не требуют изменения структуры справочника.
ВерсииОбъектов. Первая запись в этом регистре для конкретной ссылки и будет датой создания.ВыгрузитьЖурналРегистрации() можно программно отобрать события добавления объектов. Это трудоемкая операция для динамических списков, но она идеально подходит для разовых отчетов или проверок.Выясним причину, по которой стоит выбрать тот или иной метод:
Если ваша задача — обеспечить надежную работу бизнес-логики (например, сортировка товаров в прайсе по новизне), используйте Метод 1. Добавление индексированного реквизита ДатаСоздания — это профессиональный стандарт разработки.
Если вам нужно быстро «прикинуть» порядок в консоли запросов или в небольшом списке без изменения конфигурации, используйте УПОРЯДОЧИТЬ ПО Ссылка УБЫВ (Метод 2). Это даст примерную картину, но помните о перемешивании байтов в SQL.
Если же вы столкнулись с задачей восстановления хронологии в уже существующей базе, где даты не записывались, попробуйте воспользоваться функцией извлечения даты из ГУИД (Метод 3) или анализом Журнала регистрации. Это поможет вам заполнить пустые значения дат создания для старых элементов, после чего вы сможете перейти к использованию надежного Метода 1.