Как программно удалить запрещенные символы и сформировать корректное имя реквизита в 1С?

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

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

Правила именования идентификаторов в 1С

Прежде чем переходить к коду, проанализируем основные ограничения платформы «1С:Предприятие» к именам реквизитов:

  1. Состав символов: Допускаются только буквы (русские или латинские), цифры и символ подчеркивания _.
  2. Первый символ: Идентификатор должен начинаться только с буквы или подчеркивания. Цифра в начале недопустима.
  3. Пробелы: Не допускаются. Обычно их либо удаляют, либо заменяют на подчеркивание, либо используют стиль CamelCase (каждое новое слово начинается с заглавной буквы).
  4. Длина: Максимальная длина имени обычно ограничена 256 символами.

Решение с помощью стандартных функций БСП

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

Основная функция для нашей задачи — ОбщегоНазначения.ИмяИдентификатора(). Она предназначена именно для преобразования произвольной строки в валидное имя объекта. Рассмотрим пример:


// Исходная строка с запрещенными символами
ИсходноеИмя = "Склад №1 (основной) - 2024";
// Получаем корректное имя
КорректноеИмя = ОбщегоНазначения.ИмяИдентификатора(ИсходноеИмя);
// Результат будет: Склад1основной2024

Также полезно знать о функции СтроковыеФункцииКлиентСервер.Латиница(). Она пригодится, если вы хотите не просто очистить строку, а транслитерировать её (перевести кириллицу в латиницу), что часто требуется для обмена данными с внешними системами или API.

Использование регулярных выражений (платформа 8.3.23+)

Если вы работаете на современной версии платформы (8.3.23 и выше), самым производительным и элегантным способом будет использование регулярных выражений. Выясним, как это работает на практике. Мы можем использовать метод СтрЗаменитьПоРегулярномуВыражению, чтобы одним действием удалить всё лишнее.


// Удаляем все символы, кроме букв, цифр и подчеркивания
// Шаблон [^а-яА-Яa-zA-Z0-9_] означает: найти всё, что НЕ является указанными символами
Результат = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, "[^а-яА-Яa-zA-Z0-9_]", "");

// Дополнительно проверяем первый символ: если это цифра, добавим подчеркивание
Если СтрНайти("0123456789", Лев(Результат, 1)) > 0 Тогда
    Результат = "_" + Результат;
КонецЕсли;

Алгоритм «ручной» очистки с перебором символов

Посмотрим на ситуацию, когда нам нужно более гибкое управление процессом, например, замена пробелов на подчеркивания или преобразование строки в CamelCase. Разберем по шагам функцию, которая анализирует каждый символ.


Функция ПолучитьРазрешенноеИмяРеквизита(ВходящаяСтрока)
    
    Буквы = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяabcdefghijklmnopqrstuvwxyz";
    Цифры = "0123456789";
    РазрешенныеСимволы = Буквы + ВРег(Буквы) + Цифры + "_";
    
    Результат = "";
    
    Для НомерСимвола = 1 По СтрДлина(ВходящаяСтрока) Цикл
        ТекСимвол = Сред(ВходящаяСтрока, НомерСимвола, 1);
        
        // Если символ разрешен — добавляем его
        Если СтрНайти(РазрешенныеСимволы, ТекСимвол) > 0 Тогда
            Результат = Результат + ТекСимвол;
        ИначеЕсли ТекСимвол = " " Тогда
            // Пробелы заменяем на подчеркивание
            Результат = Результат + "_";
        КонецЕсли;
    КонецЦикла;
    
    // Проверка первого символа на цифру
    Если СтрНайти(Цифры, Лев(Результат, 1)) > 0 Тогда
        Результат = "_" + Результат;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Улучшенный вариант: Реализация CamelCase

Зачастую простое удаление пробелов делает имя нечитаемым (например, «ИмяСкладаОсновной» превращается в «Имяскладаосновной»). Проанализируем более сложный алгоритм, предложенный участниками сообщества, который делает первую букву каждого слова заглавной.


Функция ПолучитьИмяВВерблюжьемРегистре(ВходящаяСтрока)
    
    Буквы = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяabcdefghijklmnopqrstuvwxyz";
    Цифры = "0123456789";
    СтрокаРазрешенных = Буквы + ВРег(Буквы) + Цифры + "_ "; // временно разрешим пробел
    
    НормализованнаяСтрока = "";
    СледующийВВерхнемРегистре = Ложь;
    
    Для К = 1 По СтрДлина(ВходящаяСтрока) Цикл
        Символ = Сред(ВходящаяСтрока, К, 1);
        
        Если СтрНайти(СтрокаРазрешенных, Символ) = 0 Тогда
            Продолжить; // Пропускаем запрещенные символы
        КонецЕсли;
        
        Если Символ = " " Тогда
            СледующийВВерхнемРегистре = Истина;
            Продолжить;
        КонецЕсли;
        
        Если СледующийВВерхнемРегистре Тогда
            НормализованнаяСтрока = НормализованнаяСтрока + ВРег(Символ);
            СледующийВВерхнемРегистре = Ложь;
        Иначе
            НормализованнаяСтрока = НормализованнаяСтрока + Символ;
        КонецЕсли;
    КонецЦикла;
    
    // Финальная проверка на первый символ
    Если СтрНайти(Цифры, Лев(НормализованнаяСтрока, 1)) > 0 Тогда
        НормализованнаяСтрока = "_" + НормализованнаяСтрока;
    КонецЕсли;
    
    Возврат НормализованнаяСтрока;
    
КонецФункции

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

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

  1. Пустой результат: Если исходная строка состояла только из запрещенных символов (например, "!!! &??"), функция вернет пустую строку. Платформа 1С выдаст ошибку при попытке создать реквизит с пустым именем. Всегда добавляйте проверку: Если ПустаяСтрока(Имя) Тогда Имя = "ДополнительныйРеквизит" + Формат(ТекущаяДата(), "ДФ=yyyyMMddhhmmss"); КонецЕсли;.
  2. Уникальность: Очистка строки не гарантирует, что такое имя еще не занято на форме. Перед вызовом ИзменитьРеквизиты() проанализируйте существующий состав реквизитов. Если имя «Склад1» уже есть, добавьте индекс: «Склад1_1», «Склад1_2» и так далее.
  3. Регистронезависимость: Помните, что для 1С имена ИмяРеквизита и имяреквизита идентичны. Использование CamelCase нужно только для удобства чтения кода и отладки.
  4. Длина имени: Если вы формируете имя на основе очень длинного описания, используйте Лев(Имя, 100), чтобы не превысить лимит платформы в 256 символов.

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

← На главную