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

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

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

Ограничения стандартного свойства Маска

Свойство Маска у элементов формы предназначено исключительно для структурированных строк строго фиксированной длины (например, ИНН, СНИЛС, серии и номера паспорта, телефонные номера). В стандартном синтаксисе масок 1С спецсимвол # разрешает ввод цифры, знака плюс, знака минус или пробела, однако:

  1. Маска не поддерживает операции умножения (*) и деления (/).
  2. Маска требует фиксированного количества символов и позиций, тогда как математическое выражение имеет произвольную длину.
  3. Нельзя запретить ввод пробелов, если используется символ #.

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

Вариант 1. Валидация при завершении ввода через событие ПриИзменении

Рассмотрим наиболее стабильный подход для управляемых форм. Вместо фильтрации «на лету» при каждом нажатии клавиши (что может сбивать позицию курсора при программной замене текста), мы позволяем пользователю ввести строку целиком с клавиатуры, а затем выполняем очистку и проверку в событии ПриИзменении или ОкончаниеВводаТекста.

Посмотрим на пример функции, которая оставляет в строке только разрешенные символы (цифры от 0 до 9 и знаки +, -, *, /, .):


&НаКлиенте
Функция ОчиститьНедопустимыеСимволы(Знач ИсходныйТекст)
    РазрешенныеСимволы = "0123456789+-*/.";
    ОчищенныйТекст = "";
    
    Для Индекс = 1 По СтрДлина(ИсходныйТекст) Цикл
        Символ = Сред(ИсходныйТекст, Индекс, 1);
        Если СтрНайти(РазрешенныеСимволы, Символ) > 0 Тогда
            ОчищенныйТекст = ОчищенныйТекст + Символ;
        КонецЕсли;
    КонецЦикла;
    
    Возврат ОчищенныйТекст;
КонецФункции

&НаКлиенте
Процедура ПолеВыражениеПриИзменении(Элемент)
    Объект.Выражение = ОчиститьНедопустимыеСимволы(Объект.Выражение);
КонецПроцедуры

Вариант 2. Фильтрация ввода на лету через ИзменениеТекстаРедактирования

Если требуется запрещать ввод некорректных символов в реальном времени, задействуем обработчик события элемента формы ИзменениеТекстаРедактирования. В этом событии параметр Текст содержит текущее значение, введенное пользователем.

Разберем по шагам логику обработки:

  1. Получаем введенный текст из параметра Текст.
  2. Фильтруем недопустимые символы.
  3. Если обнаружены лишние знаки, перезаписываем параметр Текст очищенным значением.

&НаКлиенте
Процедура ПолеВыражениеИзменениеТекстаРедактирования(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
    ОчищеннаяСтрока = ОчиститьНедопустимыеСимволы(Текст);
    
    Если Текст <> ОчищеннаяСтрока Тогда
        Текст = ОчищеннаяСтрока;
    КонецЕсли;
КонецПроцедуры

Важно: при динамической замене текста в процессе ввода каретка (курсор) может перемещаться в конец строки. Если пользователь попытается отредактировать середину выражения, это может вызвать неудобство, поэтому данный метод чаще комбинируют с экранными кнопками или валидацией по завершении ввода.

Вычисление введенного математического выражения

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

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

Посмотрим на пример обработчика кнопки расчета с использованием функции Вычислить():


&НаКлиенте
Процедура КомандаРассчитать(Команда)
    СтрокаВыражения = ОчиститьНедопустимыеСимволы(Объект.Выражение);
    
    Если ПустаяСтрока(СтрокаВыражения) Тогда
        Возврат;
    КонецЕсли;
    
    Попытка
        Результат = Вычислить(СтрокаВыражения);
        Объект.Результат = Результат;
    Исключение
        ПоказатьПредупреждение(, "Ошибка в математическом выражении. Проверьте правильность расстановки знаков.");
    КонецПопытки;
КонецПроцедуры

Альтернативные интерфейсные решения

Если требуется полностью исключить возможность ввода некорректных данных и сделать интерфейс интуитивным:

  1. Экранная клавиатура на форме: создадим командную панель или сетку кнопок («0»–«9», «+», «-», «*», «/», «C», «=»). По нажатию кнопок программно дописываем символы в реквизит, отключив прямой клавиатурный ввод установкой свойства ТолькоПросмотр = Истина для поля отображения.
  2. Поле HTML-документа: встраивание мини-интерфейса на HTML/JavaScript внутри формы 1С позволяет нативно обрабатывать события клавиатуры onkeydown и oninput без задержек клиент-серверного взаимодействия и с полным контролем положения курсора.
← На главную