Разработка и Конфигурация · 10 мин
Какие функции отсутствуют во встроенном языке 1С:Предприятие 8
Разбираем, какие функции отсутствуют во встроенном языке 1С:Предприятие 8: работа со строками, датами, коллекциями, файлами и регулярными выражениями. Способы обхода ограничений.
Встроенный язык 1С:Предприятие 8 (язык конфигуратора) создавался как инструмент описания бизнес-логики, а не как язык общего назначения. Поэтому разработчики, приходящие из C#, Java, Python или JavaScript, быстро обнаруживают: многих привычных конструкций и библиотечных функций в нём просто нет. При этом большинство задач всё же решается — либо штатными приёмами, либо через внешние компоненты и расширения платформы.
Ниже разобраны основные группы отсутствующих возможностей: работа со строками и датами, операции с коллекциями, функциональное программирование, файловые и сетевые операции, регулярные выражения. Для каждой группы приведены практические способы обхода ограничений, которые реально применяются в типовых и самописных конфигурациях.
Важно учитывать, что платформа развивается: часть ограничений снимается в новых версиях (например, появились объекты типа «СхемаКомпоновкиДанных» для программной работы с отчётами, расширены возможности HTTP-запросов). Поэтому перед реализацией обходного пути стоит проверить синтакс-помощник именно вашей версии платформы.
Строковые функции: чего не хватает и чем заменить
Базовый набор строковых функций в 1С минимален: Лев, Прав, Сред, СтрДлина, СтрНайти, СтрЗаменить, СокрЛП. Отсутствуют привычные из других языков функции Split (разбиение строки по разделителю), Join (склейка массива в строку), PadLeft/PadRight (дополнение символами), проверки начала и окончания строки (StartsWith, EndsWith), а также форматирование по шаблону в стиле printf — его частично заменяет СтрШаблон.
Разбиение строки по разделителю обычно реализуют либо циклом со СтрНайти, либо через функцию СтрРазделить, которая появилась в относительно свежих версиях платформы и возвращает массив подстрок. Обратная операция — СтрСоединить. Если ваша версия платформы их не содержит, пишется собственная функция на 15–20 строк. Проверку «строка начинается с» выполняют через сравнение Лев(Строка, СтрДлина(Префикс)) = Префикс.
Конкатенация большого числа строк в цикле через оператор «+» — частая ошибка производительности. На больших объёмах используют объект ЗаписьТекста в строку или массив с последующей СтрСоединить, что заметно быстрее при тысячах итераций.
// Проверка окончания строки без EndsWith
Функция СтрЗаканчиваетсяНа(Строка, Суффикс)
Возврат Прав(Строка, СтрДлина(Суффикс)) = Суффикс;
КонецФункцииРегулярные выражения: полное отсутствие и обходные пути
Во встроенном языке нет штатного механизма регулярных выражений — ни для поиска, ни для замены, ни для валидации. Это одно из самых ощутимых ограничений при обработке текстов: проверка email, ИНН, разбор логов и масок ввода требуют либо громоздкого ручного разбора посимвольно, либо внешних средств.
На практике применяют три подхода. Первый — собственные функции валидации через цикл по символам и проверку вхождения в допустимый алфавит; подходит для простых форматов вроде «только цифры и дефис». Второй — внешние компоненты по технологии Native API, например доступные в сообществе компоненты-обёртки над библиотеками regex. Третий — вынос обработки во внешний сервис или скрипт, если инфраструктура это позволяет.
В части версий платформы доступен объект для работы с регулярными выражениями на уровне системы компоновки и подобия строк в запросах (оператор ПОДОБНО), но это не полноценная замена regex: ПОДОБНО поддерживает лишь символы подстановки %, _ и ограниченный набор классов символов.
Как выбрать способ обработки текста
Работа с датами и временем
Язык предоставляет ТекущаяДата, ДобавитьМесяц и арифметику дат в секундах, но отсутствуют удобные функции добавления дней, часов, минут, вычисления разности в заданных единицах, определения номера недели, проверки високосного года. Всё это приходится считать вручную через секунды: Дата + 86400 для добавления суток.
Разность дат вычисляется вычитанием — результат в секундах, который затем делят на 60, 3600 или 86400. При делении помните об округлении: оператор Цел() или Окр() нужен, чтобы получить целое число дней. Частая ошибка — забыть, что границы периодов в запросах и отчётах завязаны на время, и сравнивать даты без приведения к началу дня.
Для работы с часовыми поясами есть функции вроде МестноеВремя и УниверсальноеВремя, однако логика пересчёта между произвольными зонами в языке не реализована — в распределённых системах это решают хранением времени в UTC и пересчётом на клиенте.
Коллекции и функциональные конструкции
В языке есть Массив, Структура, Соответствие, СписокЗначений и ТаблицаЗначений, но отсутствуют методы высшего порядка: аналоги map, filter, reduce, sort с пользовательским компаратором. Любая обработка коллекции — это явный цикл «Для Каждого … Из … Цикл». Лямбда-функций, замыканий и анонимных функций в языке нет; передача «поведения» возможна только через ОписаниеОповещения с именем экспортной процедуры, что не эквивалентно замыканию, так как контекст не захватывается.
Сортировка массива по произвольному критерию невозможна штатно: обходятся через СписокЗначений (метод СортироватьПоЗначению) или переносом данных в ТаблицуЗначений с сортировкой по колонке. У структур нет проверки существования ключа без исключения в старых версиях — используйте метод Свойство() с переменной-приёмником.
Отсутствие generics и типизированных коллекций означает, что ошибки типов обнаруживаются только в рантайме. Смягчить это помогают соглашения об именовании, явные проверки ТипЗнч() на входе функций и расширенная проверка конфигуратором.
Объектно-ориентированные возможности
Встроенный язык не поддерживает пользовательские классы, наследование, интерфейсы и инкапсуляцию в привычном смысле. Модули — это не классы: нельзя создать два экземпляра общего модуля с разным состоянием. Повторное использование логики достигается через общие модули, подписки на события и механизм переопределяемых процедур в БСП-подобных библиотеках.
Частичную замену «объектам с состоянием» дают обработки: у объекта обработки есть реквизиты и методы, и можно создать несколько экземпляров. Для сложных сценариев также применяют внешние компоненты, где ООП-логика реализуется на C++ или .NET.
Файлы, сеть и системное окружение
Работа с файлами реализована объектами ЧтениеТекста, ЗаписьТекста, ЧтениеXML, ДвоичныеДанные, но отсутствуют удобные операции уровня «скопировать папку рекурсивно», «получить список файлов по маске одной командой» — каталоги обходят через НайтиФайлы с маской. Архивы ZIP поддерживаются объектами ЧтениеZipФайла/ЗаписьZipФайла, а вот другие форматы сжатия штатно недоступны.
Сетевые возможности ограничены HTTPСоединение/HTTPЗапрос и объектами работы с интернет-почтой и FTP. Нет низкоуровневых сокетов, WebSocket-клиента и полноценного асинхронного I/O. Многопоточность в прикладном коде отсутствует: параллельность достигается только фоновыми заданиями, которые изолированы друг от друга и общаются через базу данных или временное хранилище.
Практические способы закрыть пробелы
Универсальная стратегия обхода ограничений выглядит так: сначала проверяется синтакс-помощник актуальной версии платформы — многие функции добавляются со временем; затем ищется готовое решение в библиотеке стандартных подсистем, если она внедрена; далее рассматриваются запросы (они умеют группировки, соединения, ПОДОБНО, функции над датами и строками на уровне СУБД); и только потом — внешние компоненты или вынос логики наружу.
Отдельно стоит упомянуть механизм расширений конфигурации и внешние обработки: они не добавляют новых функций языка, но позволяют инкапсулировать обходные решения и переиспользовать их между проектами без изменения типовой конфигурации.
- 1Проверьте синтакс-помощник вашей версии платформы — функция могла появиться в свежем релизе
- 2Поищите аналог в общих модулях библиотеки стандартных подсистем (СтроковыеФункцииКлиентСервер, ОбщегоНазначения)
- 3Оцените, решается ли задача запросом: СУБД умеет больше, чем встроенный язык
- 4Реализуйте обходную функцию в общем модуле с тестовыми примерами на граничных значениях
- 5Если возможностей языка принципиально не хватает — рассмотрите внешнюю компоненту Native API или внешний сервис
Что важно запомнить
Встроенный язык 1С 8 намеренно минималистичен: нет regex, лямбд, Split/Join в старых версиях, удобной арифметики дат, ООП и многопоточности. Практически всё закрывается запросами, циклами, библиотечными функциями и, при крайней необходимости, внешними компонентами. Перед написанием обходного кода проверяйте возможности вашей версии платформы.
Частые вопросы
Есть ли в 1С аналог функции Split для строк?
В свежих версиях платформы есть СтрРазделить, возвращающая массив подстрок, и обратная СтрСоединить. В старых версиях пишут собственную функцию на основе цикла со СтрНайти — её код занимает около 15 строк и легко переносится между проектами.
Можно ли использовать регулярные выражения в запросах 1С?
Полноценных regex нет. В запросах доступен оператор ПОДОБНО с символами % (любая последовательность), _ (один символ) и ограниченными классами символов в квадратных скобках. Для сложных шаблонов нужны внешние компоненты или предварительная обработка данных.
Как добавить к дате несколько дней или часов?
Арифметика дат ведётся в секундах: Дата + 86400 добавляет сутки, Дата + 3600 — час. Для месяцев есть штатная функция ДобавитьМесяц. При вычислении разности дат результат также в секундах — делите его на нужный коэффициент и округляйте.
Поддерживает ли язык 1С многопоточность?
Нет, в прикладном коде потоков нет. Параллельное выполнение возможно только через фоновые задания, которые работают изолированно. Их число следует ограничивать, а данные разбивать на непересекающиеся порции, чтобы избежать блокировок.
Можно ли создать собственный класс с наследованием?
Нет, пользовательских классов и наследования в языке нет. Ближайшие аналоги — общие модули для разделяемой логики и объекты обработок с реквизитами как носители состояния. Сложную объектную логику выносят во внешние компоненты.
Что делать, если нужной функции нет ни в языке, ни в запросах?
Последовательность такая: проверить библиотеку стандартных подсистем, написать обходную функцию в общем модуле, при невозможности — использовать внешнюю компоненту по технологии Native API или вынести обработку во внешний сервис, вызываемый по HTTP.