Как обработать нажатие Esc после выбора значения в поле ввода на обычных формах 1С?

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

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

Почему Esc очищает поле? Анализируем механизмы платформы

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

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

Способ 1. Использование события ПриОкончанииРедактирования

Рассмотрим самый эффективный способ контроля завершения ввода в табличном поле. У табличного поля есть событие ПриОкончанииРедактирования. Оно удобно тем, что предоставляет прямой доступ к результату действий пользователя через параметр Отмена.

Проанализируем параметры этого события:

  1. Элемент — ссылка на само табличное поле.
  2. НоваяСтрока — булево значение, указывающее, создается ли сейчас новая запись.
  3. Отмена — ключевой параметр. Если пользователь нажал Esc, этот параметр будет равен Истина. Если же редактирование завершено штатно (Enter, клик мышью в другое место), параметр будет равен Ложь.

Разберем пример кода для обработки этой ситуации:


Процедура ТабличнаяЧасть1ПриОкончанииРедактирования(Элемент, НоваяСтрока, Отмена)
    
    Если Отмена Тогда
        // Сюда мы попадем, если пользователь нажал Esc
        Сообщить("Редактирование отменено пользователем (нажат Esc)");
        
        // Если нам критично важно сохранить то, что было выбрано до Esc,
        // здесь можно реализовать дополнительную логику.
    Иначе
        // Штатное завершение редактирования
    КонецЕсли;

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

Способ 2. Принудительная фиксация через ЗаписатьВИсточник()

Выясним, можно ли заставить систему «забыть» о возможности отката. Если бизнес-логика требует, чтобы выбранное значение сохранялось мгновенно и Esc не мог его стереть, мы можем использовать метод элемента управления ЗаписатьВИсточник().

Посмотрим, как это реализовать в событии ПриИзменении конкретной колонки:


Процедура ТабличнаяЧасть1ИмяРеквизитаПриИзменении(Элемент)
    
    // Элемент здесь — это само поле ввода (редактор ячейки)
    // Принудительно записываем значение из редактора в данные строки
    Элемент.ЗаписатьВИсточник();
    
    // Теперь, даже если пользователь нажмет Esc, 
    // данные уже попали в объектную модель строки ТЧ.
КонецПроцедуры

Важный нюанс: использование ЗаписатьВИсточник() прерывает стандартный цикл «отката» редактирования, так как данные из буфера формы немедленно перемещаются в источник данных (строку таблицы).

Способ 3. Перехват в событии НачалоВыбора

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

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


Процедура ТабличнаяЧасть1Реквизит1НачалоВыбора(Элемент, СтандартнаяОбработка)
    
    // Отключаем стандартный механизм, чтобы 1С не открывала форму сама
    СтандартнаяОбработка = Ложь;
    
    // Открываем форму выбора программно (модально для простоты в ОФ)
    ВыбранноеЗначение = Справочники.Контрагенты.ВыбратьФорму().ОткрытьМодально();
    
    // Проверяем, было ли что-то выбрано или форму закрыли крестиком/Esc
    Если ВыбранноеЗначение <> Неопределено Тогда
        // Напрямую записываем в данные текущей строки, минуя буфер элемента
        ТекущаяСтрока = ЭлементыФормы.ТабличнаяЧасть1.ТекущиеДанные;
        ТекущаяСтрока.Реквизит1 = ВыбранноеЗначение;
        
        // Дополнительно можно обновить визуальное отображение
        Элемент.Значение = ВыбранноеЗначение;
    Иначе
        Сообщить("Выбор был отменен пользователем в форме выбора");
    КонецЕсли;
    
КонецПроцедуры

Важно: использование модальных окон в современном 1С не приветствуется, но для обычных форм в старых конфигурациях (например, УПП 1.3 или КА 1.1) это остается стандартным и наиболее надежным методом контроля потока выполнения кода.

Особенности для одиночных полей ввода

Стоит отметить, что если ваше поле ввода находится не в табличной части, а просто на форме, события ПриОкончанииРедактирования у него не будет. В этом случае поведение Esc жестко зашито в платформу. Если поле связано с реквизитом формы или объекта, Esc вернет значение к исходному. Чтобы обойти это, наиболее эффективным методом остается использование события ОбработкаВыбора или НачалоВыбора, как описано в Способе 3.

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

← На главную