Как программно отключить или обойти маску ввода у реквизита в 1С:Предприятие

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

В процессе разработки и кастомизации типовых конфигураций 1С программисты часто сталкиваются с ситуацией, когда у реквизита объекта (например, реквизита табличной части или шапки документа) на уровне метаданных жестко задана маска ввода. Типичный пример — маска 9999999999 для кодов ТН ВЭД или номеров ГТД, которая разрешает ввод только цифр определенной длины.

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

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

Почему не работает стандартный метод очистки маски

Первое, что пытается сделать любой разработчик для отключения маски — это очистить свойство элемента формы при создании формы на сервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Элементы.ИмяПоляВвода.Маска = "";
КонецПроцедуры

Протестировав этот код, мы увидим, что маска никуда не исчезла. Выясним причину такого поведения. Дело в том, что в управляемом приложении 1С действует строгий приоритет свойств элементов формы. Свойство формы Маска по умолчанию пустое. Когда платформа видит, что программно или интерактивно в форме маска не задана (то есть равна пустой строке ""), она автоматически обращается к метаданным самого реквизита объекта БД. Если в конфигураторе у реквизита заполнена маска, платформа «подтягивает» ее в поле ввода.

Таким образом, присваивание пустой строки элементу формы просто возвращает систему к поведению по умолчанию, заставляя ее снова использовать маску из метаданных. Нам же требуется перебить это поведение непустым значением, которое скажет платформе: «не нужно применять ограничения».

Опасный «костыль»: маска из одного пробела

Иногда на форумах предлагают обходной путь — установить маску, состоящую из одного пробела:

Элементы.ИмяПоляВвода.Маска = " ";

Рассмотрим, почему этот способ является плохим решением. Да, маска метаданных действительно перестанет действовать, однако поле ввода теперь будет всегда начинаться со скрытого пробела. При вводе данных пользователем строка запишется в базу данных в искаженном виде (например, " 10311010" вместо оригинального "10311010"). Это приведет к проблемам при поиске данных, сравнении строк и выгрузке информации в сторонние системы или регламентированные отчеты. Использование пробела в качестве маски порождает скрытые ошибки в базе данных, поэтому мы настоятельно рекомендуем отказаться от этого подхода.

Решение 1. Использование универсальной маски из латинских символов «X»

Согласно официальному Синтакс-помощнику 1С, в свойствах маски ввода предусмотрены специальные управляющие символы. Одним из таких символов является латинская буква X (важно использовать именно латинскую раскладку, так как кириллическая «Х» платформой не распознается).

Символ X в маске означает: «допустимо ввести абсолютно произвольный символ». Это могут быть любые буквы любого алфавита, цифры, знаки препинания, спецсимволы и разделители. Чтобы полностью убрать ограничения метаданных, мы можем программно заполнить маску элемента формы символами X на всю максимальную длину реквизита.

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


&НаСервере
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Получаем имя документа и табличной части динамически или прописываем жестко
    МетаданныеРеквизита = Метаданные.Документы.ПоступлениеТоваровУслуг.ТабличныеЧасти.Товары.Реквизиты.КодТНВЭД;
    
    // Определяем максимальную длину строки, разрешенную для этого реквизита
    ДлинаРеквизита = МетаданныеРеквизита.Тип.КвалификаторыСтроки.Длина;
    
    // Формируем маску, состоящую только из латинских символов "X"
    СтрокаМаски = "";
    Для Сч = 1 По ДлинаРеквизита Цикл
        СтрокаМаски = СтрокаМаски + "X";
    КонецЦикла;
    
    // Устанавливаем маску для конкретного поля ввода на форме
    Элементы.ТоварыКодТНВЭД.Маска = СтрокаМаски;
    
КонецПроцедуры

Благодаря этому решению платформа видит явную маску в элементе формы и больше не обращается к метаданным реквизита. При этом сама маска XXXXX... позволяет пользователю вводить любые данные без паразитных сдвигов и пробелов в начале строки.

Решение 2. Использование буферного реквизита формы (архитектурно верный путь)

Если вам требуется абсолютная свобода ввода (включая ввод строк произвольной длины, которая может быть меньше или больше установленной маски без автодополнения символами), лучшим решением будет использование вспомогательного реквизита формы. Этот паттерн проектирования активно применяется разработчиками самой фирмы 1С в типовых конфигурациях (ERP, КА, УТ).

Идея заключается в том, чтобы связать элемент интерфейса не напрямую с реквизитом объекта базы данных, а с временным (буферным) реквизитом формы, у которого вообще нет никакой маски в метаданных. Синхронизацию данных мы берем на себя.

Выполним следующие шаги для реализации этого метода:

  1. В расширении конфигурации откроем нужную форму документа.
  2. Добавим новый реквизит формы с именем КодТНВЭД_Буфер и типом данных Строка (длину укажем равной длине исходного реквизита).
  3. Перетащим этот реквизит на форму, заменив им старое поле ввода (или просто изменим свойство ПутьКДанным у текущего элемента формы на КодТНВЭД_Буфер).
  4. При чтении данных на сервере будем заполнять наш буфер актуальным значением из объекта.
  5. При изменении значения в поле ввода на форме будем сразу записывать его обратно в объект.

Проанализируем программный код реализации этого механизма в модуле формы:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    // Заполняем буферный реквизит формы из данных объекта при открытии
    КодТНВЭД_Буфер = ТекущийОбъект.КодТНВЭД;
КонецПроцедуры

&НаКлиенте
Процедура КодТНВЭД_БуферПриИзменении(Элемент)
    // При изменении значения на форме сразу пишем его в объект данных
    Объект.КодТНВЭД = КодТНВЭД_Буфер;
    // Модифицируем форму, чтобы система знала о наличии изменений
    ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры

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


&НаКлиенте
Процедура ТоварыКодТНВЭД_БуферПриИзменении(Элемент)
    СтрокаТЧ = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТЧ <> Неопределено Тогда
        СтрокаТЧ.КодТНВЭД = СтрокаТЧ.КодТНВЭД_Буфер;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    // Синхронизируем буфер при переходе по строкам табличной части
    СтрокаТЧ = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТЧ <> Неопределено Тогда
        КодТНВЭД_Буфер = СтрокаТЧ.КодТНВЭД;
    КонецЕсли;
КонецПроцедуры

Этот подход полностью изолирует поле ввода от ограничений метаданных реквизита. Пользователь получает абсолютно «чистое» поле без масок, работающее по стандартным правилам ввода текстовых строк.

Резюме

Мы подробно разобрали проблему наследования свойств маски в 1С и нашли эффективные методы борьбы с ней. Для простых задач, где длина вводимой строки фиксирована, отлично подойдет Решение 1 с программной установкой маски из латинских символов X. В сложных интерфейсных сценариях более надежным и гибким решением будет применение Решения 2 с использованием буферного реквизита формы. Оба метода позволяют сохранить конфигурацию на поддержке и гарантируют корректное обновление баз данных ваших клиентов.

← На главную