При настройке пользовательского интерфейса в 1С часто возникает задача ограничить набор символов, разрешенных к вводу в строковое поле. Например, требуется разрешить ввод исключительно латинских букв и цифр (для артикулов, идентификаторов, VIN-кодов или кодов маркировки). Разработчики часто пытаются решить эту задачу с помощью свойства поля Маска, однако сталкиваются с тем, что стандартная маска пропускает кириллические символы и пробелы.
Разберем, почему маска ввода не решает данную задачу и как правильно настроить проверку и фильтрацию данных программными средствами платформы 1С.
Свойство Маска управляет позиционным форматом ввода, но не предназначено для тонкой фильтрации по языковым раскладкам. В синтакс-помощнике платформы описаны специальные символы маски:
X — допустимо ввести произвольный символ.N — допустимо ввести любые алфавитно-цифровые символы (буквы или цифры).U — допустимо ввести любые алфавитно-цифровые символы с автоматическим преобразованием в верхний регистр.Символы N и U воспринимают любые буквы, зарегистрированные в операционной системе, включая кириллицу. Разделить символы на латиницу и кириллицу исключительно с помощью маски ввода невозможно. Поэтому для решения задачи необходимо использовать обработчики событий элементов формы.
Событие ОкончаниеВводаТекста возникает в момент завершения редактирования строки пользователем (до того, как значение запишется в связанный реквизит). Это наиболее удобное место для перехвата и очистки введенной строки от недопустимых символов.
Посмотрим на пример обработчика с фильтрацией строки по набору разрешенных символов:
Процедура ПолеВводаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
// Формируем строку допустимых символов
ДопустимыеСимволы = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
ОчищенныйТекст = "";
Для Сч = 1 По СтрДлина(Текст) Цикл
Символ = Сред(Текст, Сч, 1);
Если Найти(ДопустимыеСимволы, Символ) > 0 Тогда
ОчищенныйТекст = ОчищенныйТекст + Символ;
КонецЕсли;
КонецЦикла;
// Устанавливаем итоговое значение
Значение = ОчищенныйТекст;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
В этом примере мы отсекаем русские буквы, спецсимволы и пробелы, оставляя только латиницу и цифры.
Событие ПриИзменении срабатывает после фиксации значения поля. Мы можем проверить каждый символ строки через функцию КодСимвола и, если обнаружены запрещенные знаки, предупредить пользователя или очистить реквизит.
Рассмотрим коды допустимых символов таблицы ASCII:
0–9: коды от 48 до 57.A–Z: коды от 65 до 90.a–z: коды от 97 до 122.Реализуем отдельную функцию валидации и вызовем ее при изменении поля:
Функция СтрокаСодержитТолькоЛатиницуИЦифры(ПроверяемаяСтрока)
Для Индекс = 1 По СтрДлина(ПроверяемаяСтрока) Цикл
Код = КодСимвола(ПроверяемаяСтрока, Индекс);
ЭтоЦифра = (Код >= 48 И Код <= 57);
ЭтоЛатиницаЗаглавная = (Код >= 65 И Код <= 90);
ЭтоЛатиницаСтрочная = (Код >= 97 И Код <= 122);
Если Не (ЭтоЦифра Или ЭтоЛатиницаЗаглавная Или ЭтоЛатиницаСтрочная) Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Процедура ПолеВводаПриИзменении(Элемент)
Если Не СтрокаСодержитТолькоЛатиницуИЦифры(Элемент.Значение) Тогда
Предупреждение("Поле может содержать только латинские буквы и цифры!");
Элемент.Значение = "";
КонецЕсли;
КонецПроцедуры
Для быстрой проверки всей строки без явных циклов можно задействовать COM-объект VBScript.RegExp. Разберем реализацию такой проверки:
Функция ПроверитьЛатиницуРегулярнымВыражением(ЗначениеСтроки)
РегЭксп = Новый COMОбъект("VBScript.RegExp");
РегЭксп.IgnoreCase = Истина;
РегЭксп.Global = Истина;
РегЭксп.Pattern = "^[a-zA-Z0-9]+$";
Возврат РегЭксп.Test(ЗначениеСтроки);
КонецФункции
Этот способ позволяет одной строчкой шаблона ^[a-zA-Z0-9]+$ проверить соответствие строки заданному правилу.
Пользователи часто вводят текст в неверной раскладке клавиатуры. Если поле требует латиницы, практичным решением будет автоматическая замена визуально похожих русских букв на латинские аналоги при помощи функции СтрЗаменить.
Посмотрим на пример функции автозамены:
Функция ЗаменитьРусскиеСимволыНаЛатиницу(ВходнаяСтрока)
Результат = ВходнаяСтрока;
// Словарь соответствия символов верхнего регистра
РусскиеСимволы = "АВЕКМНОРСТХУавекмнорстху";
ЛатинскиеАналоги = "ABEKMHOPCTXUabekmhopctxu";
Для Позиция = 1 По СтрДлина(РусскиеСимволы) Цикл
СимволРус = Сред(РусскиеСимволы, Позиция, 1);
СимволЛат = Сред(ЛатинскиеАналоги, Позиция, 1);
Результат = СтрЗаменить(Результат, СимволРус, СимволЛат);
КонецЦикла;
Возврат Результат;
КонецФункции
Применение такой замены перед проверкой существенно повышает удобство работы пользователей и предотвращает случайные ошибки ввода.