← Назад к вопросам

Сравнение версий программы

1.6 Junior🔥 121 комментариев
#Стандарты разработки

Условие

Напишите функцию, которая сравнивает две версии программы в формате x.x.x.x (например, 8.1.4.2) и определяет, какая из них более свежая.

Функция должна вернуть:

  • 1, если первая версия новее
  • -1, если вторая версия новее
  • 0, если версии равны

Пример

Вход: "8.1.4.2" и "8.2.3.1" Выход: -1 (вторая версия новее)

Вход: "8.3.19.1" и "8.3.18.5" Выход: 1 (первая версия новее)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение

Обзор задачи

Сравнение версий — это критическая операция в системе управления софтом, обновлений и совместимости. В 1С это особенно важно при работе с конфигурациями, расширениями и интеграциями. Версия имеет иерархическую структуру, где каждый номер разной значимости: major (8), minor (1), patch (4), build (2).

Структура версии

Формат x.x.x.x состоит из четырёх частей:

  • x₁ — Major версия (основной выпуск)
  • x₂ — Minor версия (функциональные дополнения)
  • x₃ — Patch версия (исправления ошибок)
  • x₄ — Build номер (номер сборки)

Сравнение идёт слева направо — первый отличающийся номер определяет результат.

Реализация 1: Базовый вариант

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

Функция РазбитьВерсию(ВерсияСтрока)
    // Разбиваем строку по точке
    Компоненты = Новый Массив(4);
    ПозицияТочки1 = Найти(ВерсияСтрока, ".");
    ПозицияТочки2 = Найти(ВерсияСтрока, ".", , ПозицияТочки1 + 1);
    ПозицияТочки3 = Найти(ВерсияСтрока, ".", , ПозицияТочки2 + 1);
    
    Компоненты[0] = Число(Лево(ВерсияСтрока, ПозицияТочки1 - 1));
    Компоненты[1] = Число(Середина(ВерсияСтрока, ПозицияТочки1 + 1, ПозицияТочки2 - ПозицияТочки1 - 1));
    Компоненты[2] = Число(Середина(ВерсияСтрока, ПозицияТочки2 + 1, ПозицияТочки3 - ПозицияТочки2 - 1));
    Компоненты[3] = Число(Середина(ВерсияСтрока, ПозицияТочки3 + 1));
    
    Возврат Компоненты;
КонецФункции

Реализация 2: С использованием встроенных функций 1С

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

Реализация 3: С гибкой поддержкой разных форматов

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

Реализация 4: С преобразованием в число для быстрого сравнения

Функция СравнитьВерсииЧисловоеПредставление(Версия1, Версия2)
    // Преобразуем версии в единое числовое представление
    ЧисловоеПредставление1 = ПреобразоватьВерсиюВЧисло(Версия1);
    ЧисловоеПредставление2 = ПреобразоватьВерсиюВЧисло(Версия2);
    
    Если ЧисловоеПредставление1 > ЧисловоеПредставление2 Тогда
        Возврат 1;
    ИначеЕсли ЧисловоеПредставление1 < ЧисловоеПредставление2 Тогда
        Возврат -1;
    Иначе
        Возврат 0;
    КонецЕсли;
КонецФункции

Функция ПреобразоватьВерсиюВЧисло(ВерсияСтрока)
    КомпонентыВерсии = СтроковыеФункции.РазделитьСтроку(ВерсияСтрока, ".");
    
    // Объединяем числа в единое число, выделяя по 5 бит на каждый компонент
    // Например: 8.1.4.2 → 8*1000000 + 1*10000 + 4*100 + 2
    ЧисловоеПредставление = 0;
    Для И = 0 По КомпонентыВерсии.Количество() - 1 Цикл
        КоэффициентМасштабирования = Pow(100, КомпонентыВерсии.Количество() - И - 1);
        ЧисловоеПредставление = ЧисловоеПредставление + Число(КомпонентыВерсии[И]) * КоэффициентМасштабирования;
    КонецЦикла;
    
    Возврат ЧисловоеПредставление;
КонецФункции

Реализация 5: Объект для работы с версиями

Класс Версия
    Major;
    Minor;
    Patch;
    Build;
    
    Процедура ПриСоздании(ВерсияСтрока)
        Компоненты = СтроковыеФункции.РазделитьСтроку(ВерсияСтрока, ".");
        
        Если Компоненты.Количество() = 4 Тогда
            Major = Число(Компоненты[0]);
            Minor = Число(Компоненты[1]);
            Patch = Число(Компоненты[2]);
            Build = Число(Компоненты[3]);
        Иначе
            ВызватьОшибку("Неверный формат версии");
        КонецЕсли;
    КонецПроцедуры
    
    Функция СравнитьС(ДругаяВерсия) Экспорт
        Если Major <> ДругаяВерсия.Major Тогда
            Возврат ?(Major > ДругаяВерсия.Major, 1, -1);
        КонецЕсли;
        
        Если Minor <> ДругаяВерсия.Minor Тогда
            Возврат ?(Minor > ДругаяВерсия.Minor, 1, -1);
        КонецЕсли;
        
        Если Patch <> ДругаяВерсия.Patch Тогда
            Возврат ?(Patch > ДругаяВерсия.Patch, 1, -1);
        КонецЕсли;
        
        Если Build <> ДругаяВерсия.Build Тогда
            Возврат ?(Build > ДругаяВерсия.Build, 1, -1);
        КонецЕсли;
        
        Возврат 0;
    КонецФункции
    
    Функция ЭтоНовее(ДругаяВерсия) Экспорт
        Возврат СравнитьС(ДругаяВерсия) > 0;
    КонецФункции
    
    Функция ЭтоСтарше(ДругаяВерсия) Экспорт
        Возврат СравнитьС(ДругаяВерсия) < 0;
    КонецФункции
КонецКласса

Примеры использования

// Пример 1: базовое сравнение
Результат1 = СравнитьВерсииУлучшенная("8.1.4.2", "8.2.3.1");
Сообщить(Результат1); // -1 (вторая версия новее)

Результат2 = СравнитьВерсииУлучшенная("8.3.19.1", "8.3.18.5");
Сообщить(Результат2); // 1 (первая версия новее)

Результат3 = СравнитьВерсииУлучшенная("1.0.0.0", "1.0.0.0");
Сообщить(Результат3); // 0 (версии равны)

// Пример 2: с использованием класса
Версия1 = Новый Версия("8.1.4.2");
Версия2 = Новый Версия("8.2.3.1");

Если Версия1.ЭтоНовее(Версия2) Тогда
    Сообщить("Первая версия новее");
ИначеЕсли Версия1.ЭтоСтарше(Версия2) Тогда
    Сообщить("Вторая версия новее");
Иначе
    Сообщить("Версии равны");
КонецЕсли;

Рекомендация

Для production-кода рекомендую использовать реализацию 5 (класс Версия) — она обеспечивает:

  • Объектно-ориентированный подход
  • Переиспользуемость
  • Чистоту кода
  • Удобство использования через методы

Для быстрого решения — реализация 2 (улучшенная) простая и надёжная.