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

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

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

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

Ограничения событий строки и особенности поведения платформы

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

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

Способ 1. Проверка в событии ячейки ПриИзменении и программная отмена ввода

Рассмотрим основной способ решения задачи. У каждой колонки табличного поля есть связанный элемент управления (как правило, ПолеВвода). Мы можем назначить обработчик события ПриИзменении непосредственно для этого поля ввода.

Если введенное значение даты недопустимо, мы выводим предупреждение и вызываем метод табличного поля ЗакончитьРедактированиеСтроки(Истина). Передача параметра Истина указывает платформе отменить редактирование и удалить незафиксированную строку.

Посмотрим на пример кода:


Процедура ТабличноеПолеДатаПриИзменении(Элемент)
    
    ТекущаяСтрока = ЭлементыФормы.ТабличноеПоле.ТекущиеДанные;
    Если ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем корректность введенной даты
    Если Не ДатаВходитВДinputИнтервал(ТекущаяСтрока.Дата) Тогда
        Предупреждение("Указанная дата недоступна для выбора!");
        
        // Отменяем ввод текущей строки и удаляем её из интерфейса
        ЭлементыФормы.ТабличноеПоле.ЗакончитьРедактированиеСтроки(Истина);
    КонецЕсли;

КонецПроцедуры

Способ 2. Очистка некорректного значения и удержание фокуса

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

Разберем по шагам реализацию этого сценария:

  1. В обработчике ПриИзменении поля ввода проверяем значение даты.
  2. Если дата некорректна, сбрасываем ее в пустое значение '00010101'.
  3. Принудительно возвращаем фокус на колонку с датой с помощью свойства ТекущаяКолонка.

Посмотрим, как выглядит программная реализация:


Процедура ТабличноеПолеДатаПриИзменении(Элемент)
    
    ТекущиеДанные = ЭлементыФормы.ТабличноеПоле.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Если Не ПроверитьДоступностьДаты(ТекущиеДанные.Дата) Тогда
        Сообщить("Выбранная дата недоступна. Пожалуйста, укажите другое число.", СтатусСообщения.Важное);
        ТекущиеДанные.Дата = '00010101';
        
        // Удерживаем фокус на колонке даты
        ЭлементыФормы.ТабличноеПоле.ТекущаяКолонка = ЭлементыФормы.ТабличноеПоле.Колонки.Дата;
    КонецЕсли;

КонецПроцедуры

Способ 3. Перехват ввода через событие ОкончаниеВводаТекста

Еще один способ пресечь ввод некорректных данных на самом раннем этапе — использовать событие элемента управления ОкончаниеВводаТекста. Это событие возникает до того, как введенный текст будет преобразован в значение и записан в строку.

Если введенное строковое значение не соответствует условиям, мы можем установить флаг СтандартнаяОбработка = Ложь, предотвратив применение значения к данным строки.


Процедура ТабличноеПолеДатаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
    
    Попытка
        ВведеннаяДата = Дата(Текст);
    Исключение
        Возврат;
    КонецПопытки;
    
    Если Не ПроверитьДоступностьДаты(ВведеннаяДата) Тогда
        СтандартнаяОбработка = Ложь;
        Предупреждение("Вы ввели недопустимую дату: " + Текст);
    КонецЕсли;

КонецПроцедуры

Способ 4. Ограничение выбора дат через список разрешенных значений

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

Для этого у элемента управления колонки настраивается режим выбора из предопределенного списка:

  1. Устанавливаем свойство РежимВыбораИзСписка = Истина для поля ввода колонки.
  2. Заполняем свойство СписокВыбора только разрешенными датами.
  3. При необходимости отключаем ручной ввод текста, запрещая ввод произвольных значений с клавиатуры.

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

Способ 5. Автоподстановка корректных данных в ПриНачалеРедактирования

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


Процедура ТабличноеПолеПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    
    Если НоваяСтрока И Не Копирование Тогда
        ТекущиеДанные = Элемент.ТекущиеДанные;
        Если ТекущиеДанные <> Неопределено Тогда
            // Подставляем ближайшую свободную рабочую дату
            ТекущиеДанные.Дата = ПолучитьБлижайшуюДоступнуюДату(ТекущаяДата());
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

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

← На главную