В процессе разработки часто возникает задача автоматического упорядочивания строк в табличной части документа. Например, необходимо поднять наверх строки с незаполненными реквизитами или отсортировать товары по алфавиту для удобства пользователя. Однако при реализации этой задачи начинающие разработчики сталкиваются с тем, что обычный вызов метода Сортировать() может приводить к неожиданному поведению: появлению признака изменения документа («звездочки») сразу после открытия или отсутствию сохранения порядка в базе данных. В этой статье мы подробно разберем, как правильно реализовать сортировку, чтобы она работала эффективно и не мешала пользователю.
Прежде всего, проанализируем ситуацию: в управляемом приложении 1С мы работаем с двумя разными представлениями данных. С одной стороны, это ДанныеФормы (объект Объект на форме), с которыми взаимодействует интерфейс. С другой — Прикладной объект (тип ДокументОбъект), который существует на сервере в момент записи в базу данных. Метод Сортировать() доступен в обоих случаях, но последствия его вызова различаются.
Если мы вызываем Объект.ИмяТабличнойЧасти.Сортировать("ИмяПоля Возр") в процедурах формы, мы меняем порядок строк непосредственно в экранной коллекции. Это моментально отображается пользователю, но система воспринимает это как интерактивное изменение данных. В результате свойство Модифицированность формы принимает значение Истина.
Рассмотрим ситуацию, когда сортировка должна выполняться при открытии существующего документа. Если мы напишем код в обработчике ПриСозданииНаСервере или ПриЧтенииНаСервере, то сразу после открытия пользователь увидит, что документ изменен, хотя он еще ничего не делал. Чтобы этого избежать, необходимо принудительно сбросить флаг модифицированности.
Разберем по шагам, как это реализовать правильно:
ПриЧтенииНаСервере. Это наиболее подходящее место, так как оно срабатывает каждый раз, когда данные считываются из базы данных (в том числе при перечитывании документа).Объект.Модифицированность в значение Ложь.Пример кода для реализации этой логики:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Сортируем табличную часть "Товары" по колонке "Актуализировано" (Булево)
// Ложь (0) будет выше, чем Истина (1) при сортировке по возрастанию
Объект.Товары.Сортировать("Актуализировано Возр");
// Снимаем признак модифицированности, чтобы форма не считалась измененной
ЭтаФорма.Модифицированность = Ложь;
КонецПроцедуры
Важный нюанс: принудительный сброс модифицированности нужно делать осторожно. Если в этих же процедурах выполняются другие программные изменения данных, которые должны быть сохранены, установка Ложь может привести к потере этих изменений при закрытии формы без сохранения.
Выясним причину, по которой сортировка в процедуре ПриОткрытии может не сохраняться в базе. Дело в том, что если пользователь просто посмотрел документ и закрыл его (или если сортировка была только визуальной), индексы строк в таблице базы данных не изменятся. Чтобы гарантировать, что строки будут записаны в нужном порядке «навсегда», сортировку нужно выполнять непосредственно перед фиксацией данных в транзакции.
Для этого идеально подходит обработчик ПередЗаписьюНаСервере. Посмотрим на критическую деталь, которую часто упускают: в этом обработчике у нас есть доступ как к данным формы (Объект), так и к самому прикладному объекту (ТекущийОбъект). Сортировать нужно именно ТекущийОбъект.
Проанализируем правильный пример кода:
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Здесь ТекущийОбъект имеет тип ДокументОбъект.ИмяВашегоДокумента
// Сортируем физическую таблицу перед сохранением
ТекущийОбъект.Лимиты.Сортировать("Актуализировано Возр");
КонецПроцедуры
Почему не Объект.Лимиты.Сортировать()? Потому что в момент записи данные из Объект (форма) уже начинают миграцию в ТекущийОбъект. Если вы отсортируете Объект в этот момент, изменения могут не успеть корректно отразиться в записываемом прикладном объекте. Сортировка ТекущийОбъект гарантирует 100% результат.
В исходном вопросе упоминалась сортировка по типу Булево. В платформе 1С 8.3 при сортировке по возрастанию (Возр) значения располагаются в следующем порядке:
Ложь (пустой флажок)Истина (установленный флажок)Следовательно, если ваша задача — поднять «незаполненные» (неотмеченные) строки вверх, следует использовать направление Возр. Если же нужно, чтобы отмеченные строки были первыми — используйте Убыв.
Рассмотрим ситуацию с точки зрения удобства пользователя. Постоянная автоматическая пересортировка может раздражать, если пользователь привык к определенному порядку строк или хочет выстроить их вручную (используя кнопки «Переместить вверх» или «Переместить вниз»). Программная сортировка в ПередЗаписью уничтожит ручную расстановку пользователя.
В качестве альтернативы можно использовать следующие инструменты:
1. Условное оформление: вместо того чтобы перемещать строки, можно выделить «пустые» или «неактуальные» строки фоновым цветом. Это привлечет внимание пользователя, но не изменит физический порядок данных. Настраивается это в свойстве формы УсловноеОформление.
2. Визуальная сортировка в элементе формы: у самой таблицы на форме (элемент управления) есть свойства сортировки. Это позволяет отображать данные в нужном порядке пользователю, не меняя их индексы в самом объекте Документ.
Подведем итог нашего анализа. Для реализации качественной сортировки табличной части следует придерживаться следующих правил:
ПриЧтенииНаСервере с последующим сбросом ЭтаФорма.Модифицированность.ПередЗаписьюНаСервере, обращаясь к ТекущийОбъект.Соблюдение этих принципов позволит вам создавать стабильные и предсказуемые решения на платформе 1С:Предприятие 8.3.