Как в коде 1С вызвать функцию новой версии платформы, сохранив совместимость со старыми версиями?

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

Разработчики 1С часто сталкиваются с ситуацией, когда в свежих релизах платформы появляются долгожданные функции (например, работа с регулярными выражениями СтрПодобнаПоРегулярномуВыражению, появившаяся в 8.3.23), но у конечных пользователей или клиентов могут быть установлены более старые версии платформы. Попытка просто написать условие Если ВерсияПлатформы >= "8.3.23" Тогда... приводит к критической ошибке: конфигурация просто не запускается, выдавая сообщение "Процедура или функция с указанным именем не определена". В этой статье мы подробно разберем, почему так происходит и как правильно реализовать адаптивный код.

Почему обычное условие «Если» не спасает от ошибки?

Проанализируем ситуацию: когда 1С загружает программный модуль (общий модуль, модуль приложения или формы), она выполняет его синтаксический разбор (компиляцию). Платформа проверяет наличие всех вызванных функций и процедур еще до того, как будет выполнена первая строка кода. Если в тексте модуля встречается функция, которую текущая версия платформы «не знает», компилятор выдает ошибку и выполнение прерывается. Даже если этот вызов находится внутри логического условия, которое в данный момент не выполняется, компилятор всё равно «видит» неизвестное имя.

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

Способ 1: Динамическое выполнение кода через Вычислить и Выполнить

Это самый надежный и распространенный метод. Суть его заключается в том, что вызов «новой» функции прячется внутри строковой переменной. Компилятор 1С не проверяет содержимое строк на этапе загрузки модуля. Проверка синтаксиса внутри строки произойдет только в момент вызова функции Вычислить() или Выполнить().

Разберем по шагам, как это реализовать на примере проверки строки по регулярному выражению:


// 1. Получаем информацию о версии платформы
Информация = Новый СистемнаяИнформация;
ВерсияПлатформы = Информация.ВерсияПриложения;

// 2. Проверяем, поддерживает ли платформа новый метод (например, >= 8.3.23.1865)
// Важно использовать правильное сравнение версий, так как это строки
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПлатформы, "8.3.23.1865") >= 0 Тогда
    
    // Прячем вызов в строку, чтобы компилятор не выдал ошибку при загрузке модуля
    ТекстКода = "СтрПодобнаПоРегулярномуВыражению(ПараметрАдрес, ПараметрШаблон)";
    
    // Выполняем код динамически
    Результат = Вычислить(ТекстКода);

Иначе
    // Используем старый проверенный способ (например, через COM или RegExp)
    Результат = ПроверитьАдресСтарымСпособом(ПараметрАдрес);
КонецЕсли;

Важный нюанс: при использовании Вычислить() или Выполнить(), переменные, используемые внутри строки (в примере это ПараметрАдрес), должны быть доступны в текущем контексте. Если вы работаете внутри процедуры, убедитесь, что имена переменных в строке в точности совпадают с именами локальных переменных.

Способ 2: Использование конструкции Попытка — Исключение

Если мы не хотим жестко привязываться к номеру версии платформы (ведь функционал может быть перенесен в патчи или другие ветки), можно использовать проверку «по факту наличия». Однако, прямой вызов в блоке Попытка все равно вызовет ошибку компиляции. Поэтому мы объединяем Попытка с динамическим выполнением.

Рассмотрим пример реализации:


Результат = Ложь;
Попытка
    // Пытаемся выполнить новый функционал
    Результат = Вычислить("СтрПодобнаПоРегулярномуВыражению(Адрес, ""^[a-z]+$"")");
Исключение
    // Если возникла ошибка (функция не найдена), используем альтернативный алгоритм
    Результат = МояЛогикаПроверкиНаСтарыхВерсиях(Адрес);
КонецПопытки;

Этот метод делает код более устойчивым: если завтра функция появится в мобильном клиенте или специфической сборке платформы, ваш код автоматически начнет ее использовать без правки условий с номерами версий.

Способ 3: Изоляция кода в отдельных общих модулях

Платформа 1С использует механизм «ленивой» компиляции. Это означает, что общий модуль не компилируется до тех пор, пока к нему не произошло первое обращение. Мы можем использовать это поведение для создания «слоеного пирога» из модулей.

Разберем алгоритм настройки:

  1. Создаем новый общий модуль РаботаСНовойПлатформой. В свойствах модуля снимаем лишние флаги (например, оставляем только Сервер или Тонкий клиент в зависимости от задач).
  2. В этот модуль помещаем код, использующий новые функции платформы.
  3. В основном коде конфигурации сначала проверяем версию платформы, и только если версия подходящая, обращаемся к функциям модуля РаботаСНовойПлатформой.

Почему это работает? Если платформа старая, код внутри Если никогда не выполнится. Следовательно, платформа никогда не попытается скомпилировать модуль РаботаСНовойПлатформой, и ошибка «Процедура не определена» не возникнет.

Пример вызова:


Если ЭтоВерсия8323ИВыше() Тогда
    // Обращаемся к модулю, который содержит «опасный» для старой платформы код
    Результат = РаботаСНовойПлатформой.ПроверитьРегулярку(Текст, Шаблон);
Иначе
    Результат = ОбычнаяПроверка(Текст);
КонецЕсли;

Способ 4: Использование альтернативных объектов для старых версий

Проанализируем конкретный пример с регулярными выражениями. Если ваша конфигурация должна работать на версии 8.3.20, где встроенной функции СтрПодобнаПоРегулярномуВыражению еще нет, мы можем реализовать идентичную логику через COM-объекты (для Windows-клиентов) или внешние компоненты.

Посмотрим на пример функции-обертки:


Функция НайтиПоРегулярке(Знач Текст, Знач Шаблон)
    
    // Пробуем штатный метод новой платформы
    Попытка
        Возврат Вычислить("СтрПодобнаПоРегулярномуВыражению(Текст, Шаблон)");
    Исключение
        // Работаем через COM (только для Windows)
        РегВыражение = Новый COMОбъект("VBScript.RegExp");
        РегВыражение.IgnoreCase = Истина;
        РегВыражение.Global = Ложь;
        РегВыражение.Pattern = Шаблон;
        Возврат РегВыражение.Test(Текст);
    КонецПопытки;
    
КонецФункции

Важные замечания по контексту и режиму совместимости

Проанализируем еще два важных фактора, которые упоминались в обсуждении:

  1. Режим совместимости: Новые функции встроенного языка (такие как методы строк) обычно становятся доступны сразу при запуске на новой платформе, даже если свойство конфигурации РежимСовместимости установлено в значение 8.3.14 или ниже. Исключение составляют случаи, когда поведение функции кардинально меняется в зависимости от режима. В случае с регулярными выражениями режим совместимости не блокирует вызов функции на новой платформе.
  2. Тонкий клиент: Помните, что версия платформы сервера и версия платформы клиента могут различаться. Если вы вызываете СистемнаяИнформация на клиенте, вы получите версию Тонкого клиента. Если ваш код должен работать и там, и там, убедитесь, что проверка версии выполняется в том же контексте (на той же «стороне»), где будет вызван новый функционал.

Выясним причину частых ошибок: многие разработчики забывают, что Выполнить() и Вычислить() не работают в безопасном режиме и имеют ограничения в облачных сервисах (1С:Фреш). Если вы разрабатываете расширение для облака, использование динамического кода может потребовать прохождения дополнительного аудита или использования профилей безопасности.

Подведем итог: для обеспечения стабильной работы конфигурации на разных версиях платформы лучше всего использовать комбинацию проверки версии через СистемнаяИнформация и вызова кода через Вычислить(). Это гарантирует, что ваша программа не «упадет» при запуске и плавно переключится на современный движок там, где это возможно.

← На главную