Разработчики 1С часто сталкиваются с ситуацией, когда в свежих релизах платформы появляются долгожданные функции (например, работа с регулярными выражениями СтрПодобнаПоРегулярномуВыражению, появившаяся в 8.3.23), но у конечных пользователей или клиентов могут быть установлены более старые версии платформы. Попытка просто написать условие Если ВерсияПлатформы >= "8.3.23" Тогда... приводит к критической ошибке: конфигурация просто не запускается, выдавая сообщение "Процедура или функция с указанным именем не определена". В этой статье мы подробно разберем, почему так происходит и как правильно реализовать адаптивный код.
Проанализируем ситуацию: когда 1С загружает программный модуль (общий модуль, модуль приложения или формы), она выполняет его синтаксический разбор (компиляцию). Платформа проверяет наличие всех вызванных функций и процедур еще до того, как будет выполнена первая строка кода. Если в тексте модуля встречается функция, которую текущая версия платформы «не знает», компилятор выдает ошибку и выполнение прерывается. Даже если этот вызов находится внутри логического условия, которое в данный момент не выполняется, компилятор всё равно «видит» неизвестное имя.
Рассмотрим способы обхода этого ограничения, которые позволяют писать универсальный код для разных версий платформы.
Это самый надежный и распространенный метод. Суть его заключается в том, что вызов «новой» функции прячется внутри строковой переменной. Компилятор 1С не проверяет содержимое строк на этапе загрузки модуля. Проверка синтаксиса внутри строки произойдет только в момент вызова функции Вычислить() или Выполнить().
Разберем по шагам, как это реализовать на примере проверки строки по регулярному выражению:
// 1. Получаем информацию о версии платформы
Информация = Новый СистемнаяИнформация;
ВерсияПлатформы = Информация.ВерсияПриложения;
// 2. Проверяем, поддерживает ли платформа новый метод (например, >= 8.3.23.1865)
// Важно использовать правильное сравнение версий, так как это строки
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПлатформы, "8.3.23.1865") >= 0 Тогда
// Прячем вызов в строку, чтобы компилятор не выдал ошибку при загрузке модуля
ТекстКода = "СтрПодобнаПоРегулярномуВыражению(ПараметрАдрес, ПараметрШаблон)";
// Выполняем код динамически
Результат = Вычислить(ТекстКода);
Иначе
// Используем старый проверенный способ (например, через COM или RegExp)
Результат = ПроверитьАдресСтарымСпособом(ПараметрАдрес);
КонецЕсли;
Важный нюанс: при использовании Вычислить() или Выполнить(), переменные, используемые внутри строки (в примере это ПараметрАдрес), должны быть доступны в текущем контексте. Если вы работаете внутри процедуры, убедитесь, что имена переменных в строке в точности совпадают с именами локальных переменных.
Если мы не хотим жестко привязываться к номеру версии платформы (ведь функционал может быть перенесен в патчи или другие ветки), можно использовать проверку «по факту наличия». Однако, прямой вызов в блоке Попытка все равно вызовет ошибку компиляции. Поэтому мы объединяем Попытка с динамическим выполнением.
Рассмотрим пример реализации:
Результат = Ложь;
Попытка
// Пытаемся выполнить новый функционал
Результат = Вычислить("СтрПодобнаПоРегулярномуВыражению(Адрес, ""^[a-z]+$"")");
Исключение
// Если возникла ошибка (функция не найдена), используем альтернативный алгоритм
Результат = МояЛогикаПроверкиНаСтарыхВерсиях(Адрес);
КонецПопытки;
Этот метод делает код более устойчивым: если завтра функция появится в мобильном клиенте или специфической сборке платформы, ваш код автоматически начнет ее использовать без правки условий с номерами версий.
Платформа 1С использует механизм «ленивой» компиляции. Это означает, что общий модуль не компилируется до тех пор, пока к нему не произошло первое обращение. Мы можем использовать это поведение для создания «слоеного пирога» из модулей.
Разберем алгоритм настройки:
РаботаСНовойПлатформой. В свойствах модуля снимаем лишние флаги (например, оставляем только Сервер или Тонкий клиент в зависимости от задач).РаботаСНовойПлатформой.Почему это работает? Если платформа старая, код внутри Если никогда не выполнится. Следовательно, платформа никогда не попытается скомпилировать модуль РаботаСНовойПлатформой, и ошибка «Процедура не определена» не возникнет.
Пример вызова:
Если ЭтоВерсия8323ИВыше() Тогда
// Обращаемся к модулю, который содержит «опасный» для старой платформы код
Результат = РаботаСНовойПлатформой.ПроверитьРегулярку(Текст, Шаблон);
Иначе
Результат = ОбычнаяПроверка(Текст);
КонецЕсли;
Проанализируем конкретный пример с регулярными выражениями. Если ваша конфигурация должна работать на версии 8.3.20, где встроенной функции СтрПодобнаПоРегулярномуВыражению еще нет, мы можем реализовать идентичную логику через COM-объекты (для Windows-клиентов) или внешние компоненты.
Посмотрим на пример функции-обертки:
Функция НайтиПоРегулярке(Знач Текст, Знач Шаблон)
// Пробуем штатный метод новой платформы
Попытка
Возврат Вычислить("СтрПодобнаПоРегулярномуВыражению(Текст, Шаблон)");
Исключение
// Работаем через COM (только для Windows)
РегВыражение = Новый COMОбъект("VBScript.RegExp");
РегВыражение.IgnoreCase = Истина;
РегВыражение.Global = Ложь;
РегВыражение.Pattern = Шаблон;
Возврат РегВыражение.Test(Текст);
КонецПопытки;
КонецФункции
Проанализируем еще два важных фактора, которые упоминались в обсуждении:
РежимСовместимости установлено в значение 8.3.14 или ниже. Исключение составляют случаи, когда поведение функции кардинально меняется в зависимости от режима. В случае с регулярными выражениями режим совместимости не блокирует вызов функции на новой платформе.СистемнаяИнформация на клиенте, вы получите версию Тонкого клиента. Если ваш код должен работать и там, и там, убедитесь, что проверка версии выполняется в том же контексте (на той же «стороне»), где будет вызван новый функционал.Выясним причину частых ошибок: многие разработчики забывают, что Выполнить() и Вычислить() не работают в безопасном режиме и имеют ограничения в облачных сервисах (1С:Фреш). Если вы разрабатываете расширение для облака, использование динамического кода может потребовать прохождения дополнительного аудита или использования профилей безопасности.
Подведем итог: для обеспечения стабильной работы конфигурации на разных версиях платформы лучше всего использовать комбинацию проверки версии через СистемнаяИнформация и вызова кода через Вычислить(). Это гарантирует, что ваша программа не «упадет» при запуске и плавно переключится на современный движок там, где это возможно.