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