Разработчики, работающие с платформой 1С:Предприятие 7.7, часто сталкиваются с досадным ограничением: стандартный метод Сортировка() для форм списков справочников позволяет выбрать только реквизит, по которому будет упорядочен список, но не позволяет указать направление (по возрастанию или по убыванию). По умолчанию система всегда сортирует данные по возрастанию (от меньшего к большему, от ранних дат к поздним).
В этой статье мы подробно разберем, почему это происходит, и проанализируем несколько проверенных способов, как заставить форму списка отображать элементы в обратном порядке, чтобы, например, самые свежие записи всегда были вверху.
Проанализируем синтаксис метода Сортировка(). Как мы видим из документации, метод принимает два параметра: Способ (имя реквизита или стандартные поля Код/Наименование) и Разрешение (флаг возможности изменения сортировки пользователем). Параметра, отвечающего за направление, попросту не существует. В архитектуре 1С 7.7 индексы таблиц справочников строятся таким образом, что выборка всегда идет в прямом порядке. Поэтому нам придется использовать обходные пути.
Это самый надежный и производительный метод, если вам необходимо обеспечить быструю сортировку в больших справочниках. Суть заключается в создании специального служебного реквизита, значения в котором будут «перевернуты» относительно реальных данных.
Рассмотрим по шагам реализацию для сортировки по дате:
ИнверсДата с типом Число (длина 10, точность 0).ПриЗаписи() добавим вычисление этого поля:
Процедура ПриЗаписи()
// Вычитаем дату из очень большого числа, чтобы получить обратный порядок
// Например, из 2100 года
ИнверсДата = Число(Дата(2100,1,1)) - Число(ДатаДок);
КонецПроцедуры
Теперь в форме списка достаточно вызвать:
Сортировка("ИнверсДата", 0);
Важный момент: Для уже существующих элементов справочника необходимо написать разовую обработку, которая заполнит новый реквизит ИнверсДата по всем записям, иначе сортировка для них работать не будет.
Если мы не хотим менять структуру метаданных, мы можем воспользоваться методом ИспользоватьСписокЭлементов(). Этот метод позволяет ограничить выборку в форме списка только теми элементами, которые входят в заранее подготовленный объект СписокЗначений.
Разберем алгоритм реализации:
Пример кода в модуле формы списка:
Процедура ОбновитьОбратнуюСортировку()
Перем Запрос, ТекстЗапроса, СписокЭл;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|ТекущийЭлемент = Справочник.МойСправочник.ТекущийЭлемент;
|ДатаРеквизит = Справочник.МойСправочник.Дата;
|Группировка ТекущийЭлемент без упорядочивания;
|Упорядочить по ДатаРеквизит убывание;
|";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
СписокЭл = СоздатьОбъект("СписокЗначений");
Пока Запрос.Группировка(1) = 1 Цикл
СписокЭл.ДобавитьЗначение(Запрос.ТекущийЭлемент);
КонецЦикла;
ИспользоватьСписокЭлементов(СписокЭл);
КонецЕсли;
КонецПроцедуры
Нужно учитывать, что при использовании ИспользоватьСписокЭлементов список становится статичным. Если данные изменятся другими пользователями, форму придется переоткрывать или вызывать обновление списка программно. Также этот метод может замедлять работу, если в справочнике десятки тысяч элементов.
Часто пользователю не столько важна именно обратная сортировка, сколько возможность сразу увидеть последние добавленные записи при открытии формы. В этом случае мы можем просто программно перевести курсор на последнюю строку.
Выясним, как это сделать наиболее эффективно. В процедуре ПриОткрытии() можно использовать следующий прием:
Процедура ПриОткрытии()
// Устанавливаем стандартную сортировку
Сортировка("Дата", 1);
// Переходим к последнему элементу
Спр = СоздатьОбъект("Справочник.МойСправочник");
Спр.ОбратныйПорядок(1);
Спр.ВыбратьЭлементы();
Если Спр.ПолучитьЭлемент() = 1 Тогда
АктивизироватьОбъект(Спр.ТекущийЭлемент());
КонецЕсли;
КонецПроцедуры
Альтернативный «хитрый» способ — имитация нажатия клавиш Ctrl + End через WScript.Shell, что мгновенно прокрутит список вниз:
// В процедуре ПриОткрытии
Шелл = СоздатьОбъект("WScript.Shell");
Шелл.SendKeys("^{END}");
Профессиональное решение для версии 7.7 практически всегда подразумевает использование внешней компоненты 1С++. Она позволяет заменить стандартную таблицу справочника на объект Табличное Поле.
Разберем преимущества этого подхода:
ORDER BY Дата DESC.Хотя внедрение 1С++ требует определенных навыков, это единственный способ добиться полноценного современного поведения форм в старой платформе.
Мы рассмотрели различные варианты решения задачи. Выбор метода зависит от ваших условий: