При разработке конфигураций, связанных с логистикой, автотранспортом или пропускными системами, мы часто сталкиваемся с задачей ввода государственных регистрационных знаков автомобилей. Казалось бы, задача тривиальная — установить маску ввода. Однако, как показывает практика и обсуждения в профессионаческом сообществе, здесь кроется множество нюансов. Стандартные номера имеют разную длину кода региона, существуют спецномера, а пользователи могут путать кириллицу с латиницей.
Давайте подробно разберем, как грамотно реализовать ввод автомобильного номера, используя возможности платформы 1С:Предприятие, и проанализируем, почему одной лишь маски часто бывает недостаточно — для решения подобных задач отлично подойдёт расширение для настройки контроля ввода данных в 1С.
В начале обсуждения была поставлена задача создать маску для стандартного номера вида с065мк78 (формат: буква, 3 цифры, 2 буквы, код региона). Первое, что приходит в голову — использовать строку маски.
В синтаксисе маски 1С мы обычно оперируем следующими символами:
U — любой символ, который при вводе будет автоматически преобразован в верхний регистр.# — позволяет вводить только цифры (обязательный ввод).9 — позволяет вводить цифры, но ввод не является обязательным (можно оставить пробел).@ — ввод любых алфавитных символов (преобразуются в верхний регистр).Если мы попробуем задать жесткую маску для номера с двухзначным регионом, она будет выглядеть так: U###UU##. Однако, как справедливо заметили участники обсуждения, это решение не учитывает современные реалии. Для быстрой отладки и проверки различных вариантов масок в пользовательском режиме можно использовать редактор форм в режиме предприятия, который позволяет менять свойства элементов «на лету».
Проблема №1: Код региона.
Уже давно существуют регионы с трехзначными кодами (например, 777, 198, 750). Жесткая маска на 2 цифры в конце сделает ввод таких номеров невозможным. Если же поставить 3 обязательных знака (#), мы не сможем ввести старые номера с двухзначным регионом.
Решение: Использовать символ 9 для последней цифры региона. Правильная универсальная маска для легковых авто (Тип 1) будет выглядеть следующим образом:
U###UU###9
В этом случае, если регион двухзначный, пользователь просто не вводит последний символ, и он остается пустым (или пробелом, в зависимости от настроек хранения).
Даже настроив маску U###UU###9, мы сталкиваемся с Проблемой №2: Допустимые символы.
Согласно ГОСТ, в российских номерах используются только те буквы кириллицы, которые имеют графические аналоги в латинском алфавите. Это список из 12 букв: А, В, Е, К, М, Н, О, Р, С, Т, У, Х.
Стандартный механизм масок в 1С (символы U или @) позволяет вводить любые буквы. Это значит, что пользователь может ошибочно ввести номер с буквой "Б", "Ц" или "Щ", что технически неверно для стандартного номера РФ. Более того, маска не запретит ввод латинских букв, которые выглядят так же, но имеют другие коды символов (например, английская "C" и русская "С"). Это приведет к дублям в базе данных: визуально номера одинаковые, а для поиска — разные. В таких ситуациях для выявления уже существующих дублей с похожим написанием может пригодиться улучшенный алгоритм Левенштейна для 1С, обеспечивающий интеллектуальное сравнение строк — для этого подойдёт готовая обработка поиска и удаления дублей в 1С.
К сожалению, ограничить ввод конкретным набором символов (только эти 12 букв) исключительно средствами свойства Маска невозможно. Здесь нам на помощь приходит программная валидация.
Чтобы обеспечить чистоту данных, мы должны действовать в два этапа: помочь пользователю при вводе с помощью маски и проверить корректность данных при окончании ввода. Чтобы гарантировать отсутствие ошибок в самой логике проверки, полезно провести анализ конфигурации на наличие ошибок, связанных с вызовами экспортных процедур и функций в общих модулях.
Для поля ввода номера устанавливаем свойство Маска:
// Пример маски, учитывающей 2 или 3 цифры региона
Элементы.НомерАвто.Маска = "U###UU###9";
Это обеспечит автоматический перевод букв в верхний регистр и структуру "Буква-Цифры-Буквы-Цифры".
Самый надежный способ — обрабатывать событие ОкончаниеВводаТекста или проверять данные перед записью объекта. Нам необходимо выполнить две операции:
Рассмотрим пример функции, которая нормализует номер и проверяет его на соответствие списку допустимых букв.
Функция НормализоватьИПроверитьНомер(Знач НомерСтрокой) Экспорт
// 1. Удаляем лишние пробелы и разделители
НомерСтрокой = СокрЛП(СтрЗаменить(НомерСтрокой, " ", ""));
НомерСтрокой = ВРег(НомерСтрокой); // Приводим к верхнему регистру
// 2. Транслитерация: Латиница -> Кириллица
// Создаем соответствие похожих букв
Латиница = "ABEKMHOPCTYX";
Кириллица = "АВЕКМНОРСТУХ";
Для Сч = 1 По СтрДлина(Латиница) Цикл
СимволЛат = Сред(Латиница, Сч, 1);
СимволКир = Сред(Кириллица, Сч, 1);
НомерСтрокой = СтрЗаменить(НомерСтрокой, СимволЛат, СимволКир);
КонецЦикла;
// 3. Проверка допустимости символов (Регулярные выражения)
// Шаблон для Тип 1: 1 буква, 3 цифры, 2 буквы, 2 или 3 цифры региона
// Используем разрешенные буквы: АВЕКМНОРСТУХ
Шаблон = "^[АВЕКМНОРСТУХ]\d{3}[АВЕКМНОРСТУХ]{2}\d{2,3}$";
// Используем объект RegExp (для Windows) или встроенные средства, если платформа позволяет
// Для примера используем COM-объект (работает на клиенте под Windows)
Попытка
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.Pattern = Шаблон;
Если Не RegExp.Test(НомерСтрокой) Тогда
Возврат "Ошибка: Некорректный формат номера или недопустимые буквы.";
КонецЕсли;
Исключение
// Если проверка регуляркой недоступна, проверяем простым перебором,
// но регулярное выражение предпочтительнее.
КонецПопытки;
Возврат НомерСтрокой; // Возвращаем исправленный и проверенный номер
КонецФункции
Такой подход позволяет "молча" исправлять ошибки пользователя (замену латиницы) и выдавать предупреждение только в случае реального нарушения формата (например, введена буква "Ю").
В обсуждении также была затронута тема удобства пользователя (UX). Маска иногда мешает вводу, особенно на мобильных устройствах, где клавиатура может скакать. В крупных системах часто отказываются от единого поля ввода. Кстати, реализовать добавление новых реквизитов и элементов на управляемые формы для раздельного ввода серии и номера можно достаточно легко even без сложного кодирования — в этом поможет конструктор настройки реквизитов и управляемых форм в 1С.
Рассмотрим вариант разделения номера на три реквизита:
Преимущества такого подхода:
Важно помнить, что требование "задать маску для номера" часто разбивается о реальность. Если ваша система должна учитывать не только личные легковушки, но и такси, автобусы, прицепы или мотоциклы, единая жесткая маска не подойдет.
Примеры форматов (ГОСТ Р 50577-2018):
АА 123 77 (2 буквы, 3 цифры, регион) — маска UU ### ###9.АА 1234 77 (2 буквы, 4 цифры, регион) — маска UU #### ###9.1234 АА 77 (4 цифры, 2 буквы, регион).1234 АА 77 (формат похож на мото, но свои особенности).Как реализовать универсальность?
В таких случаях рекомендуется добавить в справочник транспортных средств реквизит ВидТранспортногоСредства или ТипНомера. В зависимости от выбранного значения мы программно меняем маску поля ввода, используя готовые функции для программного изменения форм. Упростить разработку такой логики поможет текучий конструктор для программной модификации форм, позволяющий лаконично описывать изменения интерфейса.
Процедура ВидТСПриИзменении(Элемент)
Если Объект.ВидТС = ПредопределенноеЗначение("Перечисление.ВидыТС.Легковой") Тогда
Элементы.ГосНомер.Маска = "U###UU###9";
ИначеЕсли Объект.ВидТС = ПредопределенноеЗначение("Перечисление.ВидыТС.Прицеп") Тогда
Элементы.ГосНомер.Маска = "UU#### ###9";
Иначе
// Для спецтехники или неизвестных типов убираем маску, чтобы не блокировать ввод
Элементы.ГосНомер.Mask = "";
КонецЕсли;
КонецПроцедуры
Подводя итог, можно сказать, что "правильная" маска для номера автомобиля в 1С — это сочетание гибкой настройки интерфейса и строгого контроля данных на сервере.
Для базового случая используйте маску U###UU###9. Для полноценной работы обязательно внедряйте транслитерацию латиницы в кириллицу и проверку на допустимые символы через регулярные выражения. Если парк техники разнородный — управляйте маской программно в зависимости от типа ТС или рассмотрите вариант разделения номера на составные части.