Разработчики, работающие с платформой 1С:Предприятие 7.7, часто сталкиваются с ограничениями стандартного событийного механизма форм. Одной из классических задач является необходимость точно знать, когда пользователь начал редактировать строку в списке справочника (при режиме редактирования «в строке») и когда этот процесс завершился — будь то успешное сохранение данных или отмена редактирования по клавише Esc.
В отличие от табличных частей документов, где предусмотрен более гибкий контроль, формы списков справочников лишены штатного предопределенного события «ПриОкончанииРедактированияСтроки». В этой статье мы подробно разберем, как обойти это ограничение стандартными средствами платформы, а также рассмотрим профессиональное решение с использованием возможностей внешней компоненты FormEx.
Прежде чем переходить к написанию кода, давайте проанализируем, какими стандартными инструментами мы располагаем «из коробки»:
ПриНачалеРедактированияСтроки().ПриРедактированииНовойСтроки().Enter или кликает мышью вне редактируемой строки, платформа пытается записать элемент и вызывает предопределенную процедуру модуля формы списка ПриЗаписи().Esc, внесенные изменения сбрасываются. При этом процедура ПриЗаписи() не вызывается, и никаких встроенных событий отмены редактирования строки в платформе не предусмотрено.Выяснив эти особенности, рассмотрим пошагово рабочие методы решения нашей задачи.
Самый простой способ отследить успешное завершение редактирования — завести глобальную переменную на уровне модуля формы списка, которая будет выступать в роли флага.
Рассмотрим пример реализации:
Перем РежимРедактированияСтроки; // Флаг состояния: 1 - редактируем, 0 - нет
Процедура ПриНачалеРедактированияСтроки()
РежимРедактированияСтроки = 1;
// Здесь выполняем действия, необходимые при старте изменения элемента
КонецПроцедуры
Процедура ПриРедактированииНовойСтроки()
РежимРедактированияСтроки = 1;
// Действия при создании нового элемента в строке
КонецПроцедуры
Процедура ПриЗаписи()
Если РежимРедактированияСтроки = 1 Тогда
РежимРедактированияСтроки = 0;
// Здесь мы гарантированно знаем, что редактирование строки успешно завершено
Сообщить("Редактирование строки успешно завершено и данные записаны!");
КонецЕсли;
КонецПроцедуры
Этот метод отлично работает для фиксации успешного изменения данных. Однако он не позволяет отследить событие отмены редактирования (нажатие кнопки Esc), так как при отмене процедура ПриЗаписи() игнорируется платформой.
Если вам необходимо реагировать на изменение конкретных реквизитов непосредственно в процессе редактирования ячеек, можно использовать механизм формул колонок.
Выполним следующие шаги:
ПослеИзмененияРеквизита().Теперь в модуле формы опишем эту функцию:
Функция ПослеИзмененияРеквизита()
// Данная функция вызывается каждый раз, когда фокус покидает ячейку после ее изменения
ТекущийЭлементСпр = ТекущийЭлемент();
Сообщить("Пользователь изменил значение колонки для элемента: " + ТекущийЭлементСпр);
Возврат "";
// Функция обязательно должна возвращать пустое значение или строку для отображения в ячейке
КонецФункции
Этот способ позволяет оперативно перехватывать изменения в конкретных полях ввода еще до того, как вся строка будет записана в базу данных.
Для решения нестандартных интерфейсных задач разработчики 1С 7.7 часто применяли элегантную хитрость — динамическое отслеживание состояния формы через расчет текстового поля.
Суть метода заключается в том, что платформа пересчитывает формулы всех текстовых элементов, расположенных на форме, при любом визуальном обновлении экрана (движении курсора, нажатии клавиш, изменении фокуса ввода).
Разберем реализацию этого приема по шагам:
глМониторингАктивности().
Перем ПредыдущийАктивныйЭлемент;
Функция глМониторингАктивности()
ТекущийАктивный = Форма.АктивныйЭлемент();
Если ТекущийАктивный <> ПредыдущийАктивныйЭлемент Тогда
// Фокус переместился
Если (ПредыдущийАктивныйЭлемент = "Наименование") И (ТекущийАктивный <> "Наименование") Тогда
Сообщить("Пользователь покинул поле ввода Наименование!");
КонецЕсли;
ПредыдущийАктивныйЭлемент = ТекущийАктивный;
КонецЕсли;
Возврат ""; // Возвращаем пустую строку, чтобы на форме ничего не отображалось
КонецФункции
Этот метод дает возможность в режиме реального времени понимать, находится ли пользователь внутри конкретного поля ввода строки или покинул его.
Если вам требуется абсолютный контроль над поведением формы списка, включая точное определение нажатия клавиши Esc и потерю фокуса ввода элементами управления, стандартных механизмов будет недостаточно. Лучшим решением является использование внешней компоненты FormEx (автор АЛьФ).
Внешняя компонента расширяет событийную модель 1С 7.7, добавляя системные перехватчики клавиатуры и событий фокуса Windows (Win32 API).
После загрузки компоненты FormEx в модуле формы списка становится доступна предопределенная процедура ПриНажатииКнопкиКлавиатуры(). С ее помощью мы можем легко поймать момент отмены редактирования по клавише Esc:
Процедура ПриНажатииКнопкиКлавиатуры(КодКлавиши, Альт, Шифт, Контрол, Символ, ФСО)
// КодКлавиши = 27 соответствует клавише Esc
Если (КодКлавиши = 27) И (РежимРедактированияСтроки = 1) Тогда
РежимРедактированияСтроки = 0;
Сообщить("Редактирование строки отменено пользователем (нажата кнопка Esc).");
// Здесь можно восстановить исходные значения или запустить обновление формы
КонецЕсли;
КонецПроцедуры
Каждое редактируемое поле ввода в строке таблицы на уровне операционной системы является элементом типа Edit. Компонента FormEx позволяет подписываться на события ПотеряФокуса и ПолучениеФокуса для этих элементов. Это дает возможность мгновенно узнать, когда фокус покинул редактируемое поле (даже если пользователь просто кликнул мышкой на пустую область формы) и оперативно завершить бизнес-логику вашего интерактивного алгоритма.
Используя комбинацию предложенных методов, мы можем гибко управлять интерфейсом форм списков справочников в 1С 7.7, обеспечивая высокий уровень контроля над действиями пользователя и сохранностью вводимых данных.