При интеграции данных и чтении внешних файлов (например, таблиц Excel) часто возникает задача очистки строк от нежелательных знаков препинания, пробелов и специальных символов. Типичный сценарий: заголовки столбцов загружаемого файла содержат символы вроде . / - \ #, скобки или пробелы, и при попытке создать колонку в объекте ТаблицаЗначений с таким именем платформа 1С вызывает исключение.
В этой статье мы подробно разберем, как очистить строку от лишних знаков, выясним правила именования идентификаторов в 1С и рассмотрим наиболее надежные архитектурные решения для загрузки табличных данных.
Проанализируем требования платформы 1С к именам колонок. Имя колонки в ТаблицаЗначений должно являться корректным системным идентификатором:
_.1Квартал вызовет синтаксическую ошибку).Если, Выбрать, Истина).Если просто попытаться передать текст из ячейки Excel напрямую в метод ТаблицаЗначений.Колонки.Добавить(), наличие любого запрещенного символа приведет к аварийному завершению работы алгоритма. Рассмотрим варианты решения этой задачи.
Разберем базовый алгоритм, который работает на любой версии платформы и не требует внешних библиотек. Мы создаем строку-алфавит со всеми допустимыми символами (цифры, русские и латинские буквы), после чего в цикле проверяем каждый символ исходного текста.
Посмотрим на пример универсальной функции:
Функция ОставитьТолькоБуквыИЦифры(Знач ВходнаяСтрока) Экспорт
Алфавит = "0123456789АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ_";
Результат = "";
ВходнаяСтрокаВРег = ВРег(ВходнаяСтрока);
Длина = СтрДлина(ВходнаяСтрока);
Для Индекс = 1 По Длина Цикл
Символ = Сред(ВходнаяСтрокаВРег, Индекс, 1);
Если СтрНайти(Алфавит, Символ) > 0 Тогда
// Сохраняем символ в оригинальном регистре
Результат = Результат + Сред(ВходнаяСтрока, Индекс, 1);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Обратите внимание: важно не забывать буквы Ё и Й, а также латинский алфавит и знак подчеркивания _, если они могут встретиться во входных данных.
Рассмотрим более лаконичный способ очистки строк с помощью регулярных выражений.
Для платформы 1С:Предприятие 8.3.23 и выше: в платформу добавлена встроенная кроссплатформенная функция СтрЗаменитьПоРегулярномуВыражению. Она работает на сервере под управлением Windows и Linux, а также в веб-клиенте:
// Удаляем все символы, кроме букв (рус/лат), цифр и знака подчеркивания
Шаблон = "[^a-zA-Zа-яА-ЯёЁ0-9_]";
ОчищеннаяСтрока = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, Шаблон, "");
Для более ранних версий под управлением Windows: можно использовать COM-объект VBScript.RegExp:
Функция ОчиститьСтрокуRegExp(Знач ИсходнаяСтрока) Экспорт
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Ложь;
RegExp.Pattern = "[^a-zA-Zа-яА-ЯёЁ0-9_]";
Возврат RegExp.Replace(ИсходнаяСтрока, "");
КонецФункции
Простая очистка строки от спецсимволов не решает всех проблем. Если исходный заголовок начинался с цифры (например, «1. Номенклатура») или состоял только из спецсимволов («№»), полученная строка останется некорректным идентификатором. Кроме того, два разных заголовка («Сумма (руб)» и «Сумма, руб») после очистки превратятся в одинаковое имя Суммаруб, вызвав ошибку дублирования колонки.
Разберем алгоритм генерации корректного и уникального имени колонки:
Функция ПолучитьКорректноеИмяКолонки(Знач ИсходныйЗаголовок, ТаблицаКолонок, НомерПоПорядку) Экспорт
// 1. Очищаем от недопустимых символов
Имя = ОставитьТолькоБуквыИЦифры(ИсходныйЗаголовок);
// 2. Если строка пустая, формируем системное имя
Если ПустаяСтрока(Имя) Тогда
Имя = "Колонка_" + Формат(НомерПоПорядку, "ЧГ=0");
КонецЕсли;
// 3. Проверяем, не начинается ли имя с цифры
ПервыйСимвол = Лев(Имя, 1);
Если СтрНайти("0123456789", ПервыйСимвол) > 0 Тогда
Имя = "Кол_" + Имя;
КонецЕсли;
// 4. Обеспечиваем уникальность имени в таблице
БазовоеИмя = Имя;
Счетчик = 1;
Пока ТаблицаКолонок.Найти(Имя) <> Неопределено Цикл
Имя = БазовоеИмя + "_" + Формат(Счетчик, "ЧГ=0");
Счетчик = Счетчик + 1;
КонецЦикла;
Возврат Имя;
КонецФункции
Наиболее правильный архитектурный подход при работе с произвольными файлами — не пытаться превратить пользовательский заголовок в идентификатор 1С, а разделить их роли.
Метод Колонки.Добавить() принимает параметры: Добавить(Имя, Тип, Заголовок, Ширина). Мы можем задавать гарантированно корректные системные имена (Колонка1, Колонка2), а исходный сложный текст из файла передавать в параметр Заголовок:
ТаблицаДанных = Новый ТаблицаЗначений;
Для НомерКолонки = 1 По ВсегоКолонокВФайле Цикл
ИсходныйЗаголовок = ПолучитьЗаголовокИзExcel(НомерКолонки); // Например, "Сумма с НДС, руб. / шт."
СистемноеИмя = "Колонка_" + Формат(НомерКолонки, "ЧГ=0");
// Создаем колонку с безопасным именем и красивым заголовком
ТаблицаДанных.Колонки.Добавить(СистемноеИмя, , ИсходныйЗаголовок);
КонецЦикла;
Преимущества такого подхода:
СтрокаТаблицы[НомерКолонки - 1].