В процессе разработки прикладных решений на платформе 1С:Предприятие 8.3 часто возникает задача ограничить ввод данных в строковый реквизит. Например, когда поле "Номер детали" должно содержать только цифры, определенные буквы (например, «п», «т», «о»), дефисы и запятые в качестве разделителей. Стандартные средства платформы, такие как свойство Маска, в данном случае оказываются бессильны, так как длина вводимых данных и их последовательность могут быть произвольными.
В этой статье мы подробно разберем, как реализовать проверку вводимых данных "по шаблону", проанализируем различные подходы к использованию регулярных выражений (похожая логика применяется, когда нужна проверка на заполненность обязательных полей в строке JSON) и определим оптимальные места в программном коде для размещения проверок.
Рассмотрим ситуацию: свойство Маска в 1С жестко фиксирует количество символов и их тип в каждой позиции. Это идеально подходит для номера телефона +7 (999) 999-99-99 или ИНН, но совершенно не применимо для списков. Если пользователь должен ввести «001т, 002-01, 005», система не знает заранее, сколько цифр будет в номере и сколько самих номеров будет перечислено. Поэтому мы будем использовать программные методы проверки.
Если ваша база работает на современной платформе (начиная с версии 8.3.23), нам доступен мощный встроенный объект РегулярноеВыражение. Это наиболее производительный и кроссплатформенный метод, для отладки которого пригодится Тестирование регулярных выражений на 1С. Проанализируем, как можно очистить строку от запрещенных символов:
&НаСервере
Процедура ПроверитьСтрокуНаСервере(СтрокаТекста)
// Определяем шаблон: разрешаем цифры \d, буквы п, т, о, символы тире, запятой и пробела
Шаблон = "[^\dпто ,\-]";
// Создаем объект регулярного выражения
РегВыр = Новый РегулярноеВыражение(Шаблон, Истина); // Истина - игнорировать регистр
// Пытаемся найти любые символы, НЕ входящие в разрешенный список
Если РегВыр.СодержитСовпадение(СтрокаТекста) Тогда
Сообщить("В строке обнаружены недопустимые символы!");
КонецЕсли;
КонецПроцедуры
В данном примере мы используем инвертированный набор символов [^...]. Это означает: "найди всё, что НЕ является цифрой, буквой п, т, о, запятой, пробелом или дефисом". Если такое совпадение найдено, значит, пользователь ввел некорректные данные.
Для более ранних версий платформы или в случаях, когда разработка ведется строго под Windows, классическим решением является использование VBScript.RegExp. Разберем по шагам создание функции-валидатора:
Функция СтрокаСоответствуетШаблону(Знач ПСтрока) Экспорт
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.MultiLine = Ложь;
RegExp.Global = Истина;
RegExp.IgnoreCase = Истина;
// Паттерн ищет любые символы кроме 0-9, букв п, т, о, запятой, пробела и дефиса
RegExp.Pattern = "[^0-9пто,\-\s]";
// Если найдено хотя бы одно совпадение - строка "грязная"
Matches = RegExp.Execute(ПСтрока);
Возврат Matches.Count = 0;
КонецФункции
Обратите внимание на использование \s в паттерне — это позволяет разрешить пробельные символы, чтобы ввод «001, 002» не считался ошибкой из-за пробела после запятой.
Выбор места проверки напрямую влияет на UX (пользовательский опыт). Рассмотрим три основных варианта:
Вместо того чтобы просто ругать пользователя за ошибку, мы можем проявить заботу и автоматически исправить строку. Проанализируем следующий код для события ПриИзменении:
&НаКлиенте
Процедура СписокДеталейПриИзменении(Элемент)
ТекущаяСтрока = Элементы.ТабличнаяЧасть.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// 1. Принудительно заменяем латинскую "o" (о) на кириллическую "о"
// Это самая частая ошибка пользователей при переключении раскладки
Текст = СтрЗаменить(ТекущаяСтрока.НомерДетали, "o", "о");
Текст = СтрЗаменить(Текст, "p", "п"); // латинская p на кириллическую п
// 2. Удаляем все символы, которые не входят в наш шаблон
// Используем СтрЗаменитьПоРегулярномуВыражению (доступно в 8.3.23+)
Шаблон = "[^\dпто ,\-]";
ОчищенныйТекст = СтрЗаменитьПоРегулярномуВыражению(Текст, Шаблон, "");
ТекущаяСтрока.НомерДетали = ОчищенныйТекст;
КонецПроцедуры
Важно помнить, что символы «о» и «п» имеют визуальных двойников в латинской раскладке (английские буквы "o" и "p"). Регулярное выражение [пто] настроено на кириллицу и заблокирует ввод английских букв. Чтобы пользователь не впал в замешательство («Я же нажал О, почему она удалилась?»), всегда добавляйте в обработку замену латиницы на кириллицу или включайте латинские аналоги в разрешенный список регулярного выражения.
Если мы хотим убедиться не только в наличии разрешенных букв, но и в том, что строка правильно структурирована (например, номера не могут начинаться с запятой или содержать две запятые подряд), нам понадобится более сложный паттерн. Разберем пример: ^([0-9пто\-]+)(,[0-9пто\-]+)*$.
Выясним причину использования такой конструкции:
^ — начало строки.([0-9пто\-]+) — обязательная группа из одного или более разрешенных символов (первый номер детали).(,[0-9пто\-]+)* — группа, начинающаяся с запятой, за которой следует номер детали. Символ * означает, что таких групп может быть ноль или много.$ — конец строки.Использование такого подхода в ОбработкаПроверкиЗаполнения позволит нам максимально строго контролировать качество данных в системе, не допуская появления "мусора" в виде висящих запятых или пустых элементов списка.
Таким образом, комбинируя регулярные выражения для фильтрации символов и события формы для оперативного взаимодействия с пользователем, мы создаем надежный и удобный механизм ввода данных, минимизирующий ошибки человеческого фактора.