Как программно сравнить и отсортировать версии конфигураций в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки и поддержки систем на платформе 1С:Предприятие часто возникает задача сравнения номеров версий. Номера версий обычно хранятся в виде строк, например, "2.34.4", "2.35" или "11.0.1.5". Простая попытка сравнить такие строки «в лоб» операторами > или < часто приводит к логическим ошибкам. Например, строка "2.10" будет считаться меньше, чем "2.2", потому что при посимвольном сравнении единица во втором сегменте меньше двойки. В этой статье мы подробно разберем, как правильно реализовать алгоритм сравнения и выстроить версии по порядку.

Проблема лексикографического сравнения

Прежде чем переходить к коду, выясним причину, по которой обычное сравнение строк не работает для версий. Рассмотрим две версии: "2.4.5" и "2.10.1". Человеку понятно, что десятая минорная версия новее четвертой. Однако компьютер сравнивает символы слева направо: "2" равно "2", точка равна точке, а затем сравниваются символы "4" и "1". Так как единица меньше четверки, платформа вернет результат, что "2.10.1" меньше "2.4.5". Чтобы этого избежать, нам нужно привести сегменты версий к единому виду или сравнивать их как числа.

Решение 1: Нормализация строк (дополнение нулями)

Один из самых простых и эффективных методов — привести каждый сегмент версии к фиксированной длине. Если мы договоримся, что каждый сегмент (число между точками) будет занимать, например, 4 символа, то версия "2.34.4" превратится в "0002.0034.0004", а "2.35" в "0002.0035.0000". Такие строки уже можно корректно сравнивать стандартными операторами.

Рассмотрим функцию, которая выполняет подобную нормализацию:


Функция НормализоватьВерсию(Знач ИсходнаяВерсия) Экспорт
    // Убираем лишние пробелы
    ИсходнаяВерсия = СокрЛП(ИсходнаяВерсия);
    
    // Разделяем строку на сегменты по точке
    МассивСегментов = СтрРазделить(ИсходнаяВерсия, ".");
    НовыйМассив = Новый Массив;
    
    Для Каждого Сегмент Из МассивСегментов Цикл
        // Дополняем каждый сегмент нулями слева до 4-х знаков
        НормализованныйСегмент = Прав("0000" + СокрЛП(Сегмент), 4);
        НовыйМассив.Добавить(НормализованныйСегмент);
    КонецЦикла;
    
    // Собираем обратно в строку для удобства сравнения
    Возврат СтрСоединить(НовыйМассив, ".");
КонецФункции

После такой обработки версии можно просто складывать в список значений или таблицу и использовать стандартный метод Сортировать().

Решение 2: Сравнение сегментов через массивы чисел

Если мы не хотим модифицировать строки, мы можем реализовать функцию сравнения, которая разбивает версии на части и сравнивает их последовательно как числа. Этот метод считается более профессиональным и гибким, так как он не зависит от фиксированной длины сегмента.

Проанализируем алгоритм сравнения двух версий:


Функция СравнитьВерсии(Знач Версия1, Знач Версия2) Экспорт
    Массив1 = СтрРазделить(Версия1, ".");
    Массив2 = СтрРазделить(Версия2, ".");
    
    КоличествоСегментов = Макс(Массив1.Количество(), Массив2.Количество());
    
    Для Индекс = 0 По КоличествоСегментов - 1 Цикл
        // Если сегмент отсутствует в одной из версий, считаем его равным 0
        Число1 = 0;
        Если Индекс < Массив1.Количество() Тогда
            Число1 = Число(Массив1[Индекс]);
        КонецЕсли;
        
        Число2 = 0;
        Если Индекс < Массив2.Количество() Тогда
            Число2 = Число(Массив2[Индекс]);
        КонецЕсли;
        
        Если Число1 > Число2 Тогда
            Возврат 1; // Первая версия новее
        ИначеЕсли Число1 < Число2 Тогда
            Возврат -1; // Вторая версия новее
        КонецЕсли;
    КонецЦикла;
    
    Возврат 0; // Версии идентичны
КонецФункции

Данный метод учитывает ситуацию, когда версии имеют разное количество сегментов (например, "2.35" и "2.35.1"). В этом случае "2.35" будет трактоваться как "2.35.0".

Решение 3: Использование встроенных функций БСП

Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), вам не нужно изобретать велосипед. Разработчики 1С уже предусмотрели готовые инструменты в общем модуле ОбщегоНазначенияКлиентСервер.

Рассмотрим использование функции СравнитьВерсии из БСП:


// Пример использования в коде
Результат = ОбщегоНазначенияКлиентСервер.СравнитьВерсии("2.34.6", "2.35");

Если Результат < 0 Тогда
    Сообщить("Версия 2.35 новее");
ИначеЕсли Результат > 0 Тогда
    Сообщить("Версия 2.34.6 новее");
Иначе
    Сообщить("Версии одинаковы");
КонецЕсли;

Использование функций БСП является лучшей практикой, так как этот код оптимизирован, протестирован на различных форматах версий и учитывает все нюансы платформы.

Сортировка списка версий

Когда у нас есть механизм сравнения, выстроить список версий от старой к новой не составит труда. Рассмотрим самый простой способ с использованием ТаблицыЗначений, который позволяет избежать написания сортировки «пузырьком» вручную.

Разберем по шагам:

  1. Создадим ТаблицаЗначений с двумя колонками: ИсходнаяВерсия и СортировочныйКлюч.
  2. Для каждой версии вычислим СортировочныйКлюч методом нормализации (добавление нулей).
  3. Вызовем метод Сортировать("СортировочныйКлюч Возр").
  4. Получим упорядоченный список из первой колонки.

Процедура ВыстроитьПоПорядку(МассивВерсий)
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("Версия");
    ТЗ.Колонки.Добавить("Ключ");
    
    Для Каждого ТекВерсия Из МассивВерсий Цикл
        НоваяСтрока = ТЗ.Добавить();
        НоваяСтрока.Версия = ТекВерсия;
        НоваяСтрока.Ключ = НормализоватьВерсию(ТекВерсия); // Используем функцию из Решения 1
    КонецЦикла;
    
    ТЗ.Сортировать("Ключ Возр");
    
    Для Каждого Стр Из ТЗ Цикл
        Сообщить(Стр.Версия);
    КонецЦикла;
КонецПроцедуры

Подведение итогов

Мы проанализировали три способа решения задачи. Нормализация строк удобна для быстрой сортировки в таблицах и списках. Посегментное сравнение более гибкое и не требует изменения данных. А использование стандартных функций БСП — самый надежный и быстрый путь для профессионального разработчика.

Важно помнить, что в некоторых системах версионирования могут встречаться не только цифры, но и суффиксы (например, "RC", "beta"). В таких случаях алгоритм усложняется, но для стандартных номеров конфигураций 1С описанных выше методов более чем достаточно.

← На главную