При работе со складской логистикой в 1С:Управление торговлей 11.4 пользователи часто сталкиваются с проблемой некорректного порядка ячеек в печатных формах или списках. Типичный пример: система ставит ячейку "19" перед ячейкой "2". Это происходит потому, что поле Наименование имеет строковый тип данных, и платформа применяет стандартную строковую (лексикографическую) сортировку. В этой статье мы подробно разберем, как реализовать "естественную" сортировку, чтобы числа внутри строк учитывались корректно.
Прежде чем переходить к решению, выясним причину такого поведения. Для компьютера строка — это последовательность символов. При сравнении строк "19" и "2" программа смотрит на первый символ. Символ "1" меньше, чем символ "2", поэтому строка "19" признается меньшей и ставится в начало списка. Это стандарт для всех баз данных и языков программирования, если не заданы специальные правила сравнения.
Рассмотрим ситуацию на примере топологии склада, где ячейка имеет формат M1-13-P1-4. Здесь смешаны буквы и цифры, разделенные дефисами. Для правильной сортировки нам нужно либо привести все числовые сегменты к одинаковой длине, либо сортировать по скрытым числовым атрибутам.
Проанализируем самый универсальный способ — программное преобразование строки для целей сортировки. Чтобы "2" стало больше "19" в строковом представлении, нужно дополнить числа нулями слева до фиксированной длины. Например, если мы договоримся, что каждый сегмент числа занимает 5 знаков, то:
M1-13... превратится в M00001-00013...M2-3... превратится в M00002-00003...Теперь при сравнении первых символов после "M" система увидит "0" и "0", пойдет дальше и сравнит "0" с "0", пока не дойдет до разрядов, где "1" действительно меньше "2".
Разберем пример кода, который подготавливает данные для такой сортировки. Допустим, мы выгружаем данные в таблицу значений перед выводом на печать:
// Создаем вспомогательную колонку для сортировки
ТаблицаЯчеек.Колонки.Добавить("ПорядокСортировки", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(100)));
Для Каждого СтрокаДанных Из ТаблицаЯчеек Цикл
Оригинал = СтрокаДанных.НаименованиеЯчейки; // Например "M1-13-P1-4"
ЧастиНаименования = СтрРазделить(Оригинал, "-", Ложь);
Результат = "";
Для Каждого Часть Из ЧастиНаименования Цикл
// Очищаем часть от букв, если нужно выделить только цифры
ТолькоЦифры = "";
Префикс = "";
Для Индекс = 1 По СтрДлина(Часть) Цикл
Символ = Сред(Часть, Индекс, 1);
Если Найти("0123456789", Символ) > 0 Тогда
ТолькоЦифры = ТолькоЦифры + Символ;
Иначе
Префикс = Префикс + Символ;
КонецЕсли;
КонецЦикла;
// Дополняем числовую часть нулями до 5 знаков
Пока СтрДлина(ТолькоЦифры) < 5 Цикл
ТолькоЦифры = "0" + ТолькоЦифры;
КонецЦикла;
Результат = Результат + ?(Результат = "", "", "-") + Префикс + ТолькоЦифры;
КонецЦикла;
СтрокаДанных.ПорядокСортировки = Результат;
КонецЦикла;
// Теперь сортируем таблицу по служебной колонке
ТаблицаЯчеек.Сортировать("ПорядокСортировки Возр");
В типовой конфигурации УТ 11.4 справочник СкладскиеЯчейки спроектирован грамотно. Каждая ячейка — это не просто строка, а объект с набором реквизитов. Рассмотрим подробнее структуру этого справочника. В нем есть поля:
ЛинияСтеллажЯрусПозицияЕсли при генерации топологии склада вы использовали штатные средства 1С, эти поля заполнены соответствующими числами или короткими строками. Вместо того чтобы мучиться с преобразованием строки Наименование, правильнее и быстрее будет настроить упорядочивание в запросе по этим полям.
Посмотрим на пример запроса для получения данных печатной формы:
ВЫБРАТЬ
СкладскиеЯчейки.Ссылка КАК Ячейка,
СкладскиеЯчейки.Наименование КАК Наименование,
СкладскиеЯчейки.Линия КАК Линия,
СкладскиеЯчейки.Стеллаж КАК Стеллаж,
СкладскиеЯчейки.Ярус КАК Ярус,
СкладскиеЯчейки.Позиция КАК Позиция
ИЗ
Справочник.СкладскиеЯчейки КАК СкладскиеЯчейки
ГДЕ
СкладскиеЯчейки.Владелец = &СкладскаяЗона
УПОРЯДОЧИТЬ ПО
СкладскиеЯчейки.Линия,
СкладскиеЯчейки.Стеллаж,
СкладскиеЯчейки.Ярус,
СкладскиеЯчейки.Позиция
Важный нюанс: Если реквизиты Стеллаж или Ярус имеют строковый тип (что допускается настройками), к ним в самом запросе применить числовую сортировку не получится без ВЫРАЗИТЬ(... КАК ЧИСЛО), но это сработает только если в строке нет букв. Если же там "M1", используйте метод из первого способа.
Для складского работника важна не столько "красота" номера, сколько оптимальный маршрут. В 1С предусмотрен специальный реквизит ПорядокОбхода (тип: Число). Разберем ситуацию: вы можете назначить ячейке в начале первого ряда индекс 1, а ячейке в конце первого ряда — индекс 50. Даже если их названия будут "A-1" и "Z-99", при сортировке по ПорядкуОбхода они встанут так, как удобно кладовщику для последовательного отбора товара.
Проанализируем преимущества этого подхода:
Если вы только учитесь и работаете в живой базе, обязательно соблюдайте правила безопасности:
Подводя итог: для решения проблемы "19 < 2" в 1С 8.3 наиболее профессиональным подходом является использование либо структурных числовых реквизитов топологии, либо предварительная нормализация строк (лидирующие нули) во временных таблицах запроса или в коде формирования документа.