При работе в комплексных системах автоматизации, таких как 1С:УПП с установленным модулем БИТ.ФИНАНС, пользователи часто сталкиваются с проблемой некорректной сортировки справочника Статьи бюджета. Основная сложность возникает с реквизитом Кодификатор, который имеет строковый тип. Экономисты и аналитики ожидают увидеть привычную «математическую» иерархию, но система выстраивает элементы в порядке, который кажется на первый взгляд хаотичным: например, код 2.3.2.1.10 оказывается выше, чем 2.3.2.1.2.
В этой статье мы подробно разберем, почему так происходит, изучим механизмы работы платформы 1С с данными и рассмотрим несколько эффективных способов решения этой задачи — от организационных до чисто технических.
Прежде чем переходить к решению, давайте проанализируем ситуацию с точки зрения системы. В 1С (как и в большинстве систем управления базами данных, например, SQL Server) строки сравниваются посимвольно слева направо. Это называется лексикографическим порядком.
Рассмотрим по шагам процесс сравнения двух строк: 2.3.2.1.10 и 2.3.2.1.2:
2.3.2.1.10 меньше строки 2.3.2.1.2.Именно поэтому в списке статей бюджета элемент с кодом «.10» всегда будет стоять выше, чем элемент с кодом «.2». Настройка в конфигураторе «Индексация с дополнительным упорядочиванием» в данном случае не поможет, так как она лишь оптимизирует поиск и физическое хранение индекса, но не меняет саму логику сравнения символов.
Это самый простой и часто рекомендуемый способ, который не требует написания сложного кода. Разберем его суть: чтобы строковая сортировка совпадала с числовой, все сегменты кода должны иметь одинаковую длину.
Вместо того чтобы писать 2.3.2.1.2, мы должны использовать формат 2.3.2.1.02. В этом случае при сравнении на седьмой позиции система столкнется с символом «0» (из строки ...02) и символом «1» (из строки ...10). Поскольку 0 меньше 1, сортировка станет корректной.
Рекомендации по реализации:
Чтобы избавить пользователей от рутинного ввода нулей и исключить человеческий фактор, мы можем автоматизировать этот процесс. Для этого проанализируем событие ПередЗаписью в модуле объекта справочника СтатьиБюджета.
Рассмотрим пример кода, который будет преобразовывать введенный пользователем «красивый» код в технически правильный:
Процедура ПередЗаписью(Отказ)
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Предположим, сегменты разделены точкой
МассивСегментов = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(Кодификатор, ".");
НовыйКодификатор = "";
Для Каждого Сегмент Из МассивСегментов Цикл
// Дополняем каждый сегмент до 3-х знаков ведущими нулями
ТекСегмент = СокрЛП(Сегмент);
Пока СтрДлина(ТекСегмент) < 3 Цикл
ТекСегмент = "0" + ТекСегмент;
КонецЦикла;
НовыйКодификатор = НовыйКодификатор + ?(НовыйКодификатор = "", "", ".") + ТекСегмент;
КонецЦикла;
Кодификатор = НовыйКодификатор;
КонецПроцедуры
Этот подход гарантирует, что в базе данные всегда будут храниться в виде 002.003.002.001.010, что обеспечит идеальную сортировку во всех списках и отчетах.
Бывают ситуации, когда экономисты категорически против «лишних» нулей в визуальном представлении кодов. В этом случае мы можем пойти по пути создания дополнительного реквизита.
Пошаговый алгоритм реализации:
КодификаторДляСортировки (тип Строка, длина должна быть достаточной для хранения кода с нулями).ПередЗаписью оставьте основной Кодификатор в том виде, в котором его ввел пользователь (например, 2.3.10).КодификаторДляСортировки, дополняя сегменты нулями (002.003.010).Таким образом, пользователи будут видеть привычные им цифры, а система будет использовать «правильную» строку для выстраивания иерархии.
Если проблема возникает только в определенных отчетах, мы можем решить её на уровне Системы компоновки данных, не меняя структуру справочника. Выясним, как это сделать с помощью вычисляемых полей.
В СКД можно добавить вычисляемое поле, которое будет использовать функции языка выражений для трансформации строки. Однако стоит помнить, что функции типа СтрокаРазделить доступны не во всех версиях платформы в выражениях СКД. В таких случаях лучше заранее подготовить данные в запросе или использовать Внешние функции (модули с флагом «Вызов сервера»).
Пример логики для выражения сортировки в СКД:
ВЫБОР КОГДА ПОДСТРОКА(Кодификатор, 8, 1) = "" ТОГДА ... ИНАЧЕ ... КОНЕЦ
Примечание: Данный метод является наиболее трудоемким и менее производительным, поэтому мы рекомендуем использовать его только в крайних случаях, когда редактирование справочника невозможно.
Проанализировав ситуацию, мы видим, что проблема «неправильной» сортировки — это не баг системы, а особенность работы со строковыми данными. Для исправления ситуации в БИТ.ФИНАНС наиболее эффективным и надежным методом является стандартизация длины сегментов с использованием ведущих нулей.
Если вы только начинаете внедрение, лучше сразу заложить маску кодификатора (например, 00.00.00.00). Если же база уже наполнена данными, следует запустить обработку, которая приведет коды к единому стандарту, предварительно согласовав это с финансовой службой, так как визуальное представление статей изменится.
Рассмотренные нами методы позволяют гибко подойти к решению задачи, сохранив баланс между удобством пользователей и технической корректностью работы 1С.